HY's Farm

[Docker] 개념 정리 및 사용방법까지.

2019-03-14

Docker 개념, 관리, 이미지생성까지 한번에!!

서비스 형태의 플랫폼(Platform-as-a-service, PaaS)은 서비스 제공업체가 고객에게 플랫폼을 제공함으로써 고객이 일반적으로 소프트웨어 개발 프로세스에 필요한 인프라를 구축하고 유지할 필요 없이 비즈니스 애플리케이션을 개발, 실행, 관리할 수 있도록 하는 클라우드 컴퓨팅의 시대를 말합니다.

이미 많은 사람들에게 친숙한 기술용어가 되어버린 Container ,그 시대를 이끌고 있는 대표주자가 바로 Docker입니다. 이번 글에서는 Docker의 개념, 관리, 이미지 생성에 대하여 정리하겠습니다.

Docker

도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.

도커는 컨테이너를 관리하는 플랫폼

​ Docker는 컨테이너를 관리하는 플랫폼

다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해줍니다. 백엔드 프로그램, 데이터베이스 서버, 메시지 큐등 어떤 프로그램도 컨테이너로 추상화할 수 있고 조립PC, AWS, Azure, Google cloud등 어디에서든 실행할 수 있습니다.

컨테이너란 무엇인가?

​ 운영체계를 기반으로 만들어진 대부분의 Software는 그 실행을 위하여 OS와 Software가 사용하는 동적 Library에 대하여 의존성을 갖습니다. 즉, Software의 실행을 위해선 OS와 Library를 포함, Software가 필요로 하는 파일 등으로 구성된 실행환경이 필요한데, 하나의 시스템 위에서 둘 이상의 Software를 동시에 실행하려고 한다면 문제가 발생할 수 있습니다. 예를 들어, Software A와 B가 동일한 Library를 사용하지만 서로 다른 버전을 필요로 하는 경우라던지 두 software의 운영 체제가 다를 경우 등 다양한 경우에서 문제가 발생할 수 있습니다. 이런 상황에서가장 간단한 해결책은 두 Software를 위한 시스템을 각각 준비하는 것인데, 시스템을 각각 준비할 경우 비용의 문제가 발생하게 된다(10개의 software일 경우 10개의 시스템이 필요). 이러한 문제점을 효율적으로 해결한 것이 바로 컨테이너입니다. 컨테이너(Container)는 개별 Software의 실행에 필요한 실행환경을 독립적으로 운용할 수 있도록 기반환경 또는 다른 실행환경과의 간섭을 막고 실행의 독립성을 확보해주는 운영체계 수준의 격리 기술을 말합니다. 컨테이너는 애플리케이션을 실제 구동 환경으로부터 추상화할 수 있는 논리 패키징 메커니즘을 제공합니다. Container

가상 환경에 익숙하다면 컨테이너를 가상 머신(Virtual Machine)에 비교하여 생각하면 이해하기 쉽습니다. 호스트 운영체제에서 구동되며 그 바탕이 되는 하드웨어에 가상으로 액세스하는 Linux, Windows 등의 게스트 운영체제를 의미합니다. 컨테이너는 가상 머신과 마찬가지로 애플리케이션을 관련 라이브러리 및 종속 항목과 함께 패키지로 묶어 소프트웨어 서비스 구동을 위한 격리 환경을 마련해 줍니다. 그러나 아래에서 살펴보듯 VM과의 유사점은 여기까지입니다. 컨테이너를 사용하면 개발자와 IT 운영팀이 훨씬 작은 단위로 업무를 수행할 수 있으므로 그에 따른 이점도 훨씬 많습니다.

가상 머신은 하드웨어 스택을 가상화합니다. 컨테이너는 이와 달리 운영체제 수준에서 가상화를 실시하여 다수의 컨테이너를 OS 커널에서 직접 구동합니다. 컨테이너는 훨씬 가볍고 운영체제 커널을 공유하며, 시작이 훨씬 빠르고 운영체제 전체 부팅보다 메모리를 훨씬 적게 차지합니다.

img

  컨테이너의 이점 가상 머신의 이점
일관성 있는 런타임 환경 O O
애플리케이션 샌드박스화 O O
디스크 용량 절감 O X
낮은 오버헤드 O X

Container 기술 자체는, 격리된 실행환경을 제공하기 위한 인프라 기술이긴 하지만, Docker는 이미 그 이름에서 향기를 품고 있듯이, 그 목적부터 Software 또는 Service의 빠르고 효율적인 Shipping에 강하게 집중하고 있다. 때문에 Docker는, 근간이 되는 격리 기술을 넘어 Container와 Image, 네트워크와 서비스, 보안 등 Software의 배포와 생명 주기를 관리할 수 있는 다양한 주변 기능에 초점이 맞추어져 있다고 할 수 있다.

이미지(Image)

이미지는 컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않습니다(Immutable). 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장됩니다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있습니다.

레이어 저장방식

Docker Layer Docker Layer

도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 보통 용량이 수백메가MB에 이릅니다. 처음 이미지를 다운받을 땐 크게 부담이 안되지만 기존 이미지에 파일 하나 추가했다고 수백메가를 다시 다운받는다면 매우 비효율적일 수 밖에 없습니다.

도커는 이런 문제를 해결하기 위해 레이어layer라는 개념을 사용하고 유니온 파일 시스템을 이용하여 여러개의 레이어를 하나의 파일시스템으로 사용할 수 있게 해줍니다. 이미지는 여러개의 읽기 전용 read only 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생성됩니다. ubuntu 이미지가 A + B + C의 집합이라면, ubuntu 이미지를 베이스로 만든 nginx 이미지는 A + B + C + nginx가 됩니다. webapp 이미지를 nginx 이미지 기반으로 만들었다면 예상대로 A + B + C + nginx + source 레이어로 구성됩니다. webapp 소스를 수정하면 A, B, C, nginx 레이어를 제외한 새로운 source(v2) 레이어만 다운받으면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있습니다.

컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기read-write 레이어를 추가합니다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용합니다.

이미지 경로

Docker image url

이미지는 url 방식으로 관리하며 태그를 붙일 수 있습니다. ubuntu 14.04 이미지는 docker.io/library/ubuntu:14.04 또는 docker.io/library/ubuntu:trusty 이고 docker.io/library는 생략가능하여 ubuntu:14.04 로 사용할 수 있습니다. 이러한 방식은 이해하기 쉽고 편리하게 사용할 수 있으며 태그 기능을 잘 이용하면 테스트나 롤백도 쉽게 할 수 있습니다.

Dockerfile

# vertx/vertx3 debian version
FROM subicura/vertx3:3.3.1
MAINTAINER chungsub.kim@purpleworks.co.kr


ADD build/distributions/app-3.3.1.tar /
ADD config.template.json /app-3.3.1/bin/config.json
ADD docker/script/start.sh /usr/local/bin/
RUN ln -s /usr/local/bin/start.sh /start.sh


EXPOSE 8080
EXPOSE 7000


CMD ["start.sh"]

도커는 이미지를 만들기 위해 Dockerfile이라는 파일에 자체 DSLDomain-specific language언어를 이용하여 이미지 생성 과정을 적습니다. 추후에 문법에 대해 자세히 다루겠지만 위 샘플을 보면 그렇게 복잡하지 않다는 걸 알 수 있습니다. 이것은 굉장히 간단하지만 유용한 아이디어인데, 서버에 어떤 프로그램을 설치하려고 이것저것 의존성 패키지를 설치하고 설정파일을 만들었던 경험이 있다면 더 이상 그 과정을 블로깅 하거나 메모장에 적지 말고 Dockerfile로 관리하면 됩니다. 이 파일은 소스와 함께 버전 관리 되고 원한다면 누구나 이미지 생성과정을 보고 수정할 수 있습니다.

도커 설치하기

블로그 주인의 경우, AWS Linux 환경에서 개발을 많이 하기 때문에, Linux 환경으로 설치해보겠습니다. 리눅스에 도커를 설치하는 방법은 자동 설치 스크립트를 이용하는 것이 가장 쉽습니다. 다음 명령어를 입력하면 root 권한을 요구하고 잠시 기다리면 설치가 완료됩니다.

curl -fsSL https://get.docker.com/ | sudo sh 

sudo 없이 사용하기**

docker는 기본적으로 root권한이 필요합니다. root가 아닌 사용자가 sudo없이 사용하려면 해당 사용자를 docker그룹에 추가합니다.

sudo usermod -aG docker $USER # 현재 접속중인 사용자에게 권한주기
sudo usermod -aG docker your-user # your-user 사용자에게 권한주기

컨테이너 실행하기

도커를 실행하는 명령어는 다음과 같습니다.

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

다음은 자주 사용하는 옵션들입니다.

옵션 설명
-d detached mode 흔히 말하는 백그라운드 모드
-p 호스트와 컨테이너의 포트를 연결 (포워딩)
-v 호스트와 컨테이너의 디렉토리를 연결 (마운트)
-e 컨테이너 내에서 사용할 환경변수 설정
–name 컨테이너 이름 설정
–rm 프로세스 종료시 컨테이너 자동 제거
-it -i와 -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션
–link 컨테이너 연결 [컨테이너명:별칭]

도커 기본 명령어

컨테이너 목록 확인하기 (ps)

docker ps [OPTIONS]

컨테이너 중지하기 (stop)

docker stop [OPTIONS] CONTAINER [CONTAINER...]

도커 ID의 전체 길이는 64자리 입니다. 하지만 명령어의 인자로 전달할 때는 전부 입력하지 않아도 됩니다. 예를 들어 ID가 abcdefgh…라면 abcd만 입력해도 됩니다. 앞부분이 겹치지 않는다면 1-2자만 입력해도 됩니다.

컨테이너 제거하기 (rm)

종료된 컨테이너를 완전히 제거하는 명령어는 다음과 같습니다.

docker rm [OPTIONS] CONTAINER [CONTAINER...]

중지된 컨테이너 ID를 가져와서 한번에 삭제 docker rm -v $(docker ps -a -q -f status=exited)

이미지 목록 확인하기 (images)

docker images [OPTIONS] [REPOSITORY[:TAG]]

이미지 다운로드하기 (pull)

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

이미지 삭제하기 (rmi)

docker rmi [OPTIONS] IMAGE [IMAGE...]

images 명령어를 통해 얻은 이미지 목록에서 이미지 ID를 입력하면 삭제가 됩니다. 단, 컨테이너가 실행중인 이미지는 삭제되지 않습니다. 컨테이너는 이미지들의 레이어를 기반으로 실행중이므로 당연히 삭제할 수 없습니다.

컨테이너 로그 보기 (logs)

컨테이너가 정상적으로 동작하는지 확인하는 좋은 방법은 로그를 확인하는 것 입니다.

docker logs [OPTIONS] CONTAINER

컨테이너 명령어 실행하기 (exec)

실행중인 컨테이너에 들어가거나 컨테이너의 파일을 실행하고 싶을 때가 있습니다.

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

run은 새로 컨테이너를 만들어서 실행하고 exec은 실행중인 컨테이너에 명령어로 실행합니다.

도커 이미지 만들기

도커는 이미지를 만들기 위해 컨테이너의 상태를 그대로 이미지로 저장하는 방법을 사용합니다.

create docker image

어떤 애플리케이션을 이미지로 만든다면 리눅스만 설치된 컨테이너에 애플리케이션을 설치하고 그 상태를 그대로 이미지로 저장합니다. 가상머신의 스냅샷과 비슷한 방식입니다. 이때 핵심 명령어는 파일을 복사하는 COPY와 명령어를 실행하는 RUN입니다. DockerFile을 만드는 방법은 실제 쉘 스크립트의 내용을 그대로 옮기면 됩니다.

Docker 컨테이너(Container) 커밋(Commit)하기

현재까지 작업해 놓은 ubuntu 컨테이너를 그대로 저장해보자.

docker commit CONTAINER IMAGE_NAME` 명령 이용.

  $ docker commit A A_image
  sha256:85b8eb5a23e6c850c4f4d298119275ec5a85bc43c78414372aee2859e9ad9e54

container 이름이 A 이고, 이를 이미지로 저장할 때 docker images로 확인하면 다음과 같다.

  $ docker images
  REPOSITORY        TAG                 IMAGE ID            CREATED              SIZE
  A_image           latest              85b8eb5a23e6        About a minute ago   582MB

Docker 이미지(Image) Push하기

Docker cloud 에 로그인 하기

  $ docker login

docker user id 변수 지정해놓기

  $ export DOCKER_ID_USER="nicewoong"

Docker Image 에 태그 달기

  $ docker tag ubuntu-cpp-driver $DOCKER_ID_USER/ubuntu-cpp-driver

Tag 가 적용되어 있는 Image 를 Docker Cloud 에 Push

  $ docker push $DOCKER_ID_USER/ubuntu-cpp-driver
  The push refers to a repository [docker.io/nicewoong/ubuntu-cpp-driver]
  441a4ecb7164: Pushing [==================================================>]  472.2MB
  7f7a065d245a: Mounted from nicewoong/ubuntu-bluecoat 
  f96e6b25195f: Mounted from nicewoong/ubuntu-bluecoat 
  c56153825175: Mounted from nicewoong/ubuntu-bluecoat 
  ae620432889d: Mounted from nicewoong/ubuntu-bluecoat 
  a2022691bf95: Mounted from nicewoong/ubuntu-bluecoat 

DockerFile

# 1. ubuntu 설치 (패키지 업데이트 + 만든사람 표시)
FROM       ubuntu:16.04
MAINTAINER dwhylee@gmail.com
RUN        apt-get -y update

# 2. A 설치
RUN apt-get -y install A

# 3. 소스 복사
COPY . /usr/src/app

# 4. 패키지 설치 (실행 디렉토리 설정)
WORKDIR /usr/src/app
RUN     bundle install

# 5. 실행 
CMD  ~

DockerFile 기본 명령어

1. FROM

​ 베이스 이미지를 지정합니다. 반드시 지정해야 하며 어떤 이미지도 베이스 이미지가 될 수 있습니다. tag는 ​ 될 수 있으면 기본값보다 구체적인 버전(16.04등)을 지정하는 것이 좋습니다. 이미 만들어진 다양한 베이스 이미지는 Docker hub에서 확인할 수 있습니다.

2. MAINTAINER

​ Dockerfile을 관리하는 사람의 이름 또는 이메일 정보를 적습니다. 빌드에 딱히 영향을 주지는 않습니다.

3. COPY

​ 파일이나 디렉토리를 이미지로 복사합니다. 일반적으로 소스를 복사하는 데 사용합니다. ​ target디렉토리가 없다면 자동으로 생성합니다.

4. ADD

COPY명령어와 매우 유사하나 몇가지 추가 기능이 있습니다. src에 파일 대신 URL을 입력할 수 있고 ​ src에 압축 파일을 입력하는 경우 자동으로 압축을 해제하면서 복사됩니다.

5. RUN

​ 가장 많이 사용하는 구문입니다. 명령어를 그대로 실행합니다. 내부적으로 /bin/sh -c 뒤에 명령어를 ​ 실행하는 방식입니다.

6. CMD

​ 도커 컨테이너가 실행되었을 때 실행되는 명령어를 정의합니다. 빌드할 때는 실행되지 않으며 여러 개의 CMD가 ​ 존재할 경우 가장 마지막 CMD만 실행됩니다. 한꺼번에 여러 개의 프로그램을 실행하고 싶은 경우에는 run.sh ​ 파일을 작성하여 데몬으로 실행하거나 supervisord, forego와 같은 여러 개의 프로그램을 실행하는 프로그램을 ​ 사용합니다.

7. WORKDIR

​ RUN, CMD, ADD, COPY등이 이루어질 기본 디렉토리를 설정합니다. 각 명령어의 현재 디렉토리는 한 줄마다 ​ 초기화되기 때문에 RUN cd /path를 하더라도 다음 명령어에선 위치가 초기화 됩니다. 같은 디렉토리에서 ​ 계속 작업하기 위해서 WORKDIR을 사용합니다

8. EXPOSE

​ 도커 컨테이너가 실행되었을 때 요청을 기다리고 있는(Listen) 포트를 지정합니다. 여러개의 포트를 지정할 수 ​ 있습니다.

9. VOLUME

​ 컨테이너 외부에 파일시스템을 마운트 할 때 사용합니다. 반드시 지정하지 않아도 마운트 할 수 있지만, ​ 기본적으로 지정하는 것이 좋습니다.

10. ENV

​ 컨테이너에서 사용할 환경변수를 지정합니다. 컨테이너를 실행할 때 -e옵션을 사용하면 기존 값을 오버라이딩 ​ 하게 됩니다.

여기까지 Dockerfile에서 가장 많이 사용하는 명령어에 대해 알아보았습니다. 모든 명령어가 궁금하신 분은 공식문서를 참고하시면 됩니다.

Docker 빌드하기

docker build [OPTIONS] PATH | URL | -

생성할 이미지 이름을 지정하기 위한 -t(--tag) 옵션

INPUT : 
Docker build -t app .

Output :
Sending build context to Docker daemon 22.02 kB
Step 1/10 : FROM ubuntu:16.04
 ---> f49eec89601e
Step 2/10 : MAINTAINER subicura@subicura.com
 ---> Running in 06f20ac1017d
 ---> fc41cd8ac52d
Removing intermediate container 06f20ac1017d
Step 3/10 : RUN apt-get -y update
 ---> Running in c35738e75a51
Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Get:4 http://archive.ubuntu.com/ubuntu xenial/main Sources [1103 kB]
Get:5 http://archive.ubuntu.com/ubuntu xenial/restricted Sources [5179 B]

... 생략 ...

Step 9/10 : EXPOSE 4567
 ---> Running in 9c514a1f0c8e
 ---> c5ce4376282e
Removing intermediate container 9c514a1f0c8e
Step 10/10 : CMD bundle exec ruby app.rb -o 0.0.0.0
 ---> Running in 1f7a9ba8d63c
 ---> 54d239c00f11
Removing intermediate container 1f7a9ba8d63c
Successfully built 54d239c00f11

빌드 명령어를 실행하면 Dockerfile에 정의한 내용이 한 줄 한 줄 실행되는 걸 볼 수 있습니다. 실제로 명령어를 실행하기 때문에 빌드 시간이 꽤 걸리는 걸 알 수 있습니다. 도커 빌드는 임시 컨테이너 생성 > 명령어 수행 > 이미지로 저장 > 임시 컨테이너 삭제 > 새로 만든 이미지 기반 임시 컨테이너 생성 > 명령어 수행 > 이미지로 저장 > 임시 컨테이너 삭제 > … 의 과정을 계속해서 반복합니다. 명령어를 실행할 때마다 이미지 레이어를 저장하고 다시 빌드할 때 Dockerfile이 변경되지 않았다면 기존에 저장된 이미지를 그대로 “캐시”처럼 사용합니다. 이러한 레이어 개념을 잘 이해하고 있어야 최적화된 이미지를 생성할 수 있습니다.

최종적으로 Successfully built xxxxxxxx 메시지가 보이면 정상적으로 이미지를 생성한 것입니다. 이후 docker images를 통해 확인하면 이미지가 생성된 것을 확인할 수 있고, 잘 동작하는지 컨테이너를 실행하면 됩니다.

도커 이미지 리팩토링 및 명령어 최적화

이미지를 빌드하는 과정에서 각 단계를 이미지 레이어로 저장하고 다음 빌드에서 캐시로 사용합니다. 도커는 빌드할 때 Dockerfile의 명령어가 수정되었거나 추가하는 파일이 변경 되었을 때 캐시가 깨지고 그 이후 작업은 새로 이미지를 만들게 됩니다. 또한 이미지를 빌드할 때 불필요한 로그는 무시하는게 좋고 패키지 설치시 문서 파일도 생성할 필요가 없습니다. (-qq 옵션 또는 quite 옵션 , --no-doc--no-ri 옵션 등)

컨테이너 업데이트

container

도커에서 컨테이너를 업데이트 하려면 새 버전의 이미지를 다운(pull)받고 기존 컨테이너를 삭제(stop, rm) 한 후 새 이미지를 기반으로 새 컨테이너를 실행(run)하면 됩니다. 컨테이너 삭제시 유지해야하는 데이터는 반드시 컨테이너 내부가 아닌 외부 스토리지에 저장해야 합니다. 가장 좋은 방법은 AWS S3같은 클라우드 서비스를 이용하는 것이고 그렇지 않으면 데이터 볼륨(Data volumes)을 컨테이너에 추가해서 사용해야 합니다. 데이터 볼륨을 사용하면 해당 디렉토리는 컨테이너와 별도로 저장되고 컨테이너를 삭제해도 데이터가 지워지지 않습니다.

Docker Compose

도커는 복잡한 설정을 쉽게 관리하기 위해 YAML방식의 설정파일을 이용한 Docker Compose라는 툴을 제공합니다. Dokcer Compose에서는 컨테이너 실행에 사용되는 옵션과 컨테이너 간 의존성을 모두 docker-compose.yml파일에 적어두고, 컴포즈용 명령어를 사용하여 컨테이너들을 실행, 관리합니다.

  • docker build vs. docker-compose build: 도커 이미지 만들기(=클래스 선언을 애플리케이션에 로드)
  • docker run의 옵션들 vs. docker-compose.yml: 이미지에 붙이는 장식들(=인스턴스의 변수들)
  • docker run vs. docker-compose up: 장식 붙은 이미지를 실제로 실행(=인스턴스 생성)

클래스와 인스턴스의 예를 들면, 어떤 인스턴스를 자주 생성해야 해서 필요한 변수를 딕셔너리로 저장해두는 것과 비슷하겠습니다. 이를 그림으로 나타내면 다음과 같습니다.

img

설치하기

curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# test
docker-compose version

docker-compose.yml

version: '3.1'

service:
	servicename:
		image: # optional
		command: # optional
		environment: # optional
		volumes # optional
	servicename2: # if have second service...
    volumes: # optional

    network: # optional
1. version

​ docker-compose.yml 파일의 제일 윗부분에는 파일 규격 버전을 적습니다.

2. services

​ 실행하려는 서비스들을 정의합니다. 서비스란, 앱 컨테이너나 postgres 컨테이너 각각의 묶음입니다.

3. image

​ 서비스에서 사용할 도커 이미지를 적습니다.

4. volumes

​ docker run으로 앱 컨테이너를 실행할 때 –volume 옵션을 사용하여 데이터베이스의 데이터를 로컬 컴퓨터에 ​ 저장했던 부분과 같습니다. 다만 docker-compose.yml에서는 상대 경로를 지정할 수 있다는 점이 다릅니다.

5. environment

​ docker run에서 -e 옵션에 적었던 내용들입니다.

6. build

​ 앱 서비스는 도커 이미지를 빌드할 일이 잦기 때문에, 특정 이미지 대신 build 옵션을 추가합니다.

7. port

​ 도커 컴포즈로 서비스를 실행하면 기본적으로 가상의 네트워크가 하나 만들어지고, 네트워크 외부의 접근이 ​ 막힙니다. 따라서 외부에서 접근할 수 있는 포트를 지정해주어야 합니다.

8. depends_on

​ 서비스가 하나 이상일 때, 실행 의존성을 지정할 수 있습니다.

​ docker run에서 –link 옵션에서 지정했던 내용입니다

10. command

docker run으로 앱 컨테이너를 실행하는 command 입니다.

이 외에 자세한 사항은 docker-compose를 참조하시면 됩니다.

docker-compose.yml 관리법

docker-compose.yml : 이미지만 설정되어있는 베이스 파일

version: '3.1'

services:

  drupal:
    image: drupal:latest

  postgres:
    image: postgres:9.6

docker-compose.override.yml : 개발시 사용되는 config

version: '3.1'

services:

  drupal:
    build: .
    ports:
      - "8080:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - ./themes:/var/www/html/themes

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - drupal-data:/var/lib/postgresql/data

  volumes:
    drupal-data:
    drupal-modules:
    drupal-profiles:
    drupal-sites:
    drupal-themes:

  secrets:
    psql-pw:
      file: psql-fake-password.txt

docker-compose.prod.yml : 실제 배포시 사용되는 config

version: '3.1'

services:

  drupal:
    ports:
      - "80:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - drupal-themes:/var/www/html/themes

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - drupal-data:/var/lib/postgresql/data

  volumes:
    drupal-data:
    drupal-modules:
    drupal-profiles:
    drupal-sites:
    drupal-themes:

secrets:
  psql-pw:
    external: true

docker-compose.test.yml : CI에서 사용되는 config

version: '3.1'

services:

  drupal:
    image: drupal
    build: .
    ports:
      - "80:80"

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - ./sample-data:/var/lib/postgresql/data
secrets:
  psql-pw:
    file: psql-fake-password.txt

이미지 저장소

Docker Registry

도커는 빌드한 이미지를 서버에 배포하기 위해 직접 파일을 복사하는 방법 대신 도커 레지스트리(Docker Registry)라는 이미지 저장소를 사용합니다. 도커 명령어를 이용하여 이미지를 레지스트리에 푸시(push)하고 다른 서버에서 풀(pull)받아 사용하는 구조입니다. (git과 유사)

배포하기

컨테이너 배포 방식으로

컨테이너를 배포하는 방식은 기존에 애플리케이션을 배포하는 방식과 큰 차이가 있습니다. 기존에 애플리케이션을 배포하는 방식은 사용하는 언어, 프레임워크, 웹(or WAS)서버, 리눅스 배포판, 개발자의 취향에 따라 각각 다른 방식을 사용했습니다. 새로운 서버를 셋팅하고 한 번에 배포를 성공한다는 건 굉장히 힘든 일이었고 의존성 라이브러리가 제대로 설치되었는지 검증하기도 매우 어려웠습니다. ftp, rsync, ant, gradle, capistrano, fabric, chef, puppet, ansible등 다양한 배포툴이 저마다의 장점을 가지고 등장하였고 배포하는 방식을 하나로 정의한다는 건 거의 불가능했습니다. 하지만, 컨테이너를 사용하면 어떤 언어, 어떤 프레임워크를 쓰든 상관없이 배포 방식이 동일해지고 과정 또한 굉장히 단순해집니다. 그냥 이미지를 다운받고 컨테이너를 실행하면 끝입니다.

Update

참고 자료

https://cloud.google.com/containers/

https://www.sauru.so/blog/getting-started-with-docker/

https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

https://subicura.com/2017/01/19/docker-guide-for-beginners-2.html

https://subicura.com/2017/01/19/docker-guide-for-beginners-3.html

https://gist.github.com/kkweon/2359da953f9b127b19c4146060797631

https://docs.docker.com/compose/compose-file/


Content