이 포스트는 Korea Azure User Group에서 진행하는 Docker/Container 스터디 그룹에 참여하며 작성했습니다.
스터디를 진행한 Katacoda 강좌: Docker & Containers(https://katacoda.com/courses/docker)
진행한 강의 목록
- Deploying Your First Docker Container
- Deploy Static HTML Website as Container
- Building Container Images
스터디는 Katacoda의 화면을 참조하되, 실습은 제 개인 PC에서 VM을 구성해서 진행했습니다. 따라해볼 수 있는 것만 별도로 정리했습니다.
구성환경
- Windows 10 Pro 1809
- Hyper-V
- CentOS 7.6.1810 (Kernel 4.20.2-1.el7)
내용 정리
개념: Docker는 개발자와 시스템 관리자가 다중 어플리케이션을 구성하고 배포할 수 있는 개방형 플랫폼이다.
실습기록
- Redis Cache를 시작하기위해 검색을하고, 실행해보자
search 명령어로 검색이 가능하다. docker hub에 등록된 redis의 목록이 나오게 된다. [root@docker-master ~]# docker search redis NAME DESCRIPTION STARS OFFICIAL AUTOMATED redis Redis is an open source key-value store that… 6664 [OK] bitnami/redis Bitnami Redis Docker Image 106 [OK] sameersbn/redis 76 [OK] ...
run으로 redis를 실행할 경우 기본적으로 최신버전(latest)을 구동하게 되며, 서버 내 이미지가 없을 경우 다운로드를 받는다 -d 옵션은 백그라운드에서 구동하도록한다. 이미지가 없을 경우 [root@docker-master ~]# docker run -d redis Unable to find image 'redis:latest' locally latest: Pulling from library/redis f7e2b70d04ae: Pull complete 421427137c28: Pull complete 4af7ef63ef0f: Pull complete f4d05f269476: Pull complete 3e747b51b85f: Pull complete c41406f91978: Pull complete Digest: sha256:dd04a0f82c6a838fa06b9a3b66827c7ac2ed54b8b2ced0db93df0af9d191d4c6 이미지가 있는 경우 [root@docker-master ~]# docker run -d redis 2554e598665eff28c0e53ae9874d2a361df38370206eb7efc0977002a8885011 ps 명령어로 현재 실행중인 컨테이너를 확인할 수 있다. [root@docker-master ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2554e598665e redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp infallible_torvalds
- Redis를 외부에서 접속할 수 있도록 실행하자
-p 명령어로 컨테이너의 외부 포트와 내부 포트의 매칭이 가능하다. [root@docker-master ~]# docker run -d --name redisHostPort -p 6379:6379 redis:latest b3c223c698f0a3147b4a533058dc7c97b8522a75fb01f18baa8969bd8223357a [root@docker-master ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b3c223c698f0 redis:latest "docker-entrypoint.s…" 4 seconds ago Up 4 seconds 0.0.0.0:6379->6379/tcp redisHostPort 단순하게 매칭이 아닌, 오픈할 포트만 적으며, 내부포트는 지정포트, 외부는 랜덤포트로 매칭된다. [root@docker-master ~]# docker run -d --name redisDynamic -p 6379 redis:latest ee627a410aacd938ed3a00b3433a3fafcd2dc4a88056fd239786c11cd853ba24 [root@docker-master ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ee627a410aac redis:latest "docker-entrypoint.s…" 4 seconds ago Up 4 seconds 0.0.0.0:32768->6379/tcp redisDynamic
- Redis에서 데이터 저장을 Host VM에 저장하도록 설정하자
컨테이너는 기본적으로 컨테이너 내부에 저장하게 된다. 이를 host vm에 저장하도록 실행하는 방법이다. [root@docker-master ~]# docker run -d --name redisMapped -v /opt/docker/data/redis:/data redis 0d1aac4e8f080227dcaa7a1e9c4dd8d1530293db72fe47001dd84eecb1594e47 [root@docker-master ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0d1aac4e8f08 redis "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 6379/tcp redisMapped
- 컨테이너 실행시 포그라운드로 실행해서 컨트롤 하자
-it 옵션을 사용하면 포 그라운드에서 실행이 된다. run 에 아무 옵션 없이 실행해도 포 그라운드에서 실행이 된다. [root@docker-master ~]# docker run -it ubuntu bash Unable to find image 'ubuntu:latest' locally latest: Pulling from library/ubuntu 898c46f3b1a1: Pull complete 63366dfa0a50: Pull complete 041d4cd74a92: Pull complete 6e1bee0f8701: Pull complete Digest: sha256:017eef0b616011647b269b5c65826e2e2ebddbe5d1f8c1e56b3599fb14fabec8 Status: Downloaded newer image for ubuntu:latest root@0d4a34e73015:/#
- 정적 HTML페이지를 컨테이너로 배포해보자.
index file 생성, 역시 hello world가 제격이다. [root@docker-master ~]# mkdir /home/www [root@docker-master ~]# vi /home/www/index.html <h1>Hello World</h1> 원하는 컨테이너 생성을 위해서는 Dockerfile을 통해 정의하고, 빌드를 하게된다. [root@docker-master ~]# cd /home/www [root@docker-master www]# vi Dockerfile FROM nginx:alpine # 사용할 이미지를 기재한다. COPY . /usr/share/nginx/htm # 현재 폴더내 파일을 컨테이너 내 htm 폴더로 복사한다. 빌드를 진행해보자 [root@docker-master www]# docker build -t nginxsvr-image:v1 . Sending build context to Docker daemon 5.12kB Step 1/2 : FROM nginx:alpine alpine: Pulling from library/nginx 8e402f1a9c57: Pull complete 7b69d8b552de: Pull complete 42e747db7e28: Pull complete 4f8106e1c445: Pull complete Digest: sha256:55390addbb1a2b82e6ffabafd72e0f5dfbc8f86c2e7d9f41fb914cca537bd500 Status: Downloaded newer image for nginx:alpine 32a037976344 Step 2/2 : COPY . /usr/share/nginx/html 2a3d77187128 Successfully built 2a3d77187128 Successfully tagged nginxsvr-image:v1 빌드가 되었으면 이미지를 확인해보자. [root@docker-master www]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginxsvr-image v1 2a3d77187128 About a minute ago 16.1MB 생성한 이미지를 실행해서 확인해보자. [root@docker-master www]# docker run -d -p80:80 nginxsvr-image:v1 b2d96bfb6bbd5bcbb5593a6743160ff073102f92ad29817d391a179392cd74fd [root@docker-master www]# curl localhost <h1>Hello World</h1>
- 컨테이너 이미지를 생성해보자
이미지는 Dockerfile로 정의해서 생성한다. [root@docker-master www]# vi Dockerfile FROM nginx:alpine # 사용할 이미지를 기재한다. COPY index.html /usr/share/nginx/html/index.html #복사할 파일을 기재한다. EXPOSE 80 # 포트를 지정한다 CMD ["nginx", "-g", "daemon off;"] # 컨테이너 실행시 입력할 기본 명령을 입력한다. -t 옵션은 이미지에 tag를 설정하는 옵션이다. [root@docker-master www]# docker build -t ysyukr-nginx-image:latest . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM nginx:1.11-alpine 1.11-alpine: Pulling from library/nginx 709515475419: Pull complete 4b21d71b440a: Pull complete c92260fe6357: Pull complete ed383a1b82df: Pull complete Digest: sha256:5aadb68304a38a8e2719605e4e180413f390cd6647602bee9bdedd59753c3590 Status: Downloaded newer image for nginx:1.11-alpine bedece1f06cc Step 2/4 : COPY index.html /usr/share/nginx/html/index.html 8c789a05476e Step 3/4 : EXPOSE 80 Running in 9326e8043694 Removing intermediate container 9326e8043694 c2f544c82496 Step 4/4 : CMD ["nginx", "-g", "daemon off;"] Running in 769e20a29a35 Removing intermediate container 769e20a29a35 5323ea3f71e4 Successfully built 5323ea3f71e4 Successfully tagged ysyukr-nginx-image:latest 이미지를 실행 하고 확인하자 [root@docker-master www]# docker run -d -p 80:80 ysyukr-nginx-image:latest 14d7618a29d2592dceade3201dbed3389a5c75a53881aedfa98b940303a7b875 [root@docker-master www]# curl -i localhost HTTP/1.1 200 OK Server: nginx/1.11.13 Date: Wed, 20 Mar 2019 08:26:52 GMT Content-Type: text/html Content-Length: 21 Last-Modified: Wed, 20 Mar 2019 08:06:11 GMT Connection: keep-alive ETag: "5c91f473-15" Accept-Ranges: bytes <h1>Hello World</h1>