주요글: 도커 시작하기
반응형

컴포즈 파일과 스택

컴포즈 파일을 이용하면 서비스를 보다 쉽게 만들고 업데이트할 수 있다. 다음 컴포즈 파일을 보자.

version: "3.6"
services:
  web:
    image: madvirus/simplenode:0.1
    ports:
      - "5000:5000"
    deploy:
      mode: replicated
      replicas: 2
      update_config:
        parallelism: 1
        order: start-first
        delay: 10s
        failure_action: rollback
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s

컴포즈 파일은 YAML을 사용해서 작성한다. 최상위 services는 서비스 목록을 정의한다. services의 바로 아래는 정의할 서비스 이름이 온다. 위 설정의 경우 이름이 web인 서비스를 정의한다. 실제 생성되는 서비스의 이름은 web이 아니라 스택 이름과 조합한 이름을 사용한다. 스택은 뒤에서 설명한다.

서비스 이름 아래 표시한 속성은 도커 서비스를 생성할 때 사용한 옵션과 이름이 유사하다. 서비스를 생성할 때 사용한 옵션과 유사한 이름을 사용한다. 각 속성의 값은 서비스를 설명할 때 사용한 옵션과 동일한 값을 갖는다.

컴포즈 파일에 대한 내용은 https://docs.docker.com/compose/compose-file/ 문서를 참고한다.

컴포즈 파일을 작성했다면 이제 스택을 배포할 차례다. 위 파일이 stack01.yml이라고 할 경우 다음 명령어를 이용해서 스택을 배포할 수 있다. docker stack deploy 명령어는 컴포즈 파일을 이용해서 새로운 스택을 배포한다. -c(또는 --compose-file) 옵션은 사용할 컴포즈 파일을 지정한다. 명령어에서 마지막의 simple은 배포할 스택의 이름이다.

$ docker stack deploy -c stack01.yml simple
Creating network simple_default
Creating service simple_web

스택을 배포하면 simple_web 서비스를 만든다. simple_web에서 simple은 스택 이름이고 web은 컴포즈 파일에서 지정한 서비스 이름이다. 스택을 배포하면 docker stack ls 명령어로 배포한 스택을 확인할 수 있다.

$ docker stack ls
NAME                SERVICES            ORCHESTRATOR
simple              1                   Swarm

실제로 docker service ps simple_web 명령어를 실행하면 simple_web 서비스에 두 개의 컨테이너가 실행 중이다.

$ docker service ps simple_web
ID                  NAME                IMAGE                     NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
x8cq0l5i6jwg        simple_web.1        madvirus/simplenode:0.1   docker-node1        Running             Running 13 minutes ago
hu97kwyc8oon        simple_web.2        madvirus/simplenode:0.1   docker-node2        Running             Running 13 minutes ago

실행 중인 서비스의 이미지 버전이나 리플리케이션 개수를 변경하고 싶다면 컴포즈 파일을 알맞게 만들어 다시 스택을 배포하면 된다. 컴포즈 파일을 다시 만들자.

version: "3.6"
services:
  web:
    image: madvirus/simplenode:0.2
    ports:
      - "5000:5000"
    deploy:
      mode: replicated
      replicas: 4
      update_config:
        parallelism: 1
        order: start-first
        delay: 10s
        failure_action: rollback
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s

이미지 태그를 0.1에서 0.2로 바꾸고 리플리카 개수를 4로 바꿨다. 새로 바꾼 컴포즈 파일을 이용해서 스택을 다시 배포해 보자.

$ docker stack deploy -c stack02.yml simple
Updating service simple_web (id: oj33pustknvntz1ud4t9g5egs)

simple_web 서비스를 업데이트한다는 메시지가 출력된다. 배포 후에 서비스 목록을 보면 컨테이너가 4개로 증가하고 이미지가 0.2로 바뀐 것을 볼 수 있다.

환경 변수를 이용한 설정 변경

환경 변수를 사용하면 컴포즈 파일을 수정하지 않고 값을 변경할 수 있다. 보통 컴포즈 파일을 사용해서 스택을 배포할 때는 새로 적용할 버전만 바뀔 때가 많은데 환경 변수를 사용하면 배포할 버전을 컴포즈 파일에 하드 코딩하지 않고 환경 변수로 전달할 수 있다.

version: "3.6"
services:
  web:
    image: madvirus/simplenode:${VER:-latest}
    ports:
      - "5000:5000"
    deploy:
      mode: replicated
      replicas: ${REPLICAS:-3}
      update_config:
        parallelism: 1
        order: start-first
        delay: 10s
        failure_action: rollback
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s

${VER}와 ${REPLICAS}는 각각 같은 이름의 환경 변수의 값을 사용한다. 해당 환경 변수가 존재하지 않으면 각각 latest와 3을 값으로 사용한다. 이제 도커 스택을 배포할 때 환경 변수를 이용해서 컴포즈 파일 변경없이 원하는 값을 쉽게 지정할 수 있다.

$ VER=0.2 REPLICAS=2 docker stack deploy -c stack.yml simple
Creating network simple_default
Creating service simple_web

컨테이너 환경 변수 설정: environment

컴포즈 파일에서 컨테이너에 전달할 환경 변수를 전달할 수도 있다. environment 속성에 컨테이너에 전달할 환경 변수 이름과 값 목록을 설정하면 된다. 다음은 설정 예이다.

version: "3.6"
services:
  web:
    image: madvirus/simplenode:0.3
    ports:
      - "5000:5000"
    environment:
      - RUNTIME_ENV=${ENV:-dev}
    deploy:
      mode: replicated
      replicas: 2

스택과 서비스 묶음

한 스택에는 한 개 이상의 서비스, 네트워크, 볼륨을 정의할 수 있다. 이 중 지금은 두 개 이상의 서비스를 에 대한 내용만 살펴보자. 다음은 두 서비스를 정의한 컴포즈 파일 예이다.

version: "3.6"
services:
  mysql:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=rootpw
    deploy:
      replicas: 1
  adminer:
    image: adminer
    ports:
      - "8080:8080"
    deploy:
      replicas: 1

이름이 mysql이고 adminer인 두 서비스를 정의하고 있다. 앞서 봤듯 실제로는 스택 이름을 앞에 붙인 서비스 이름을 사용한다. 위 컴포즈 파일을 이용해서 dbadmin이란 이름의 스택을 생성하자.

$ docker stack deploy -c stack03.yml dbadmin
Creating network dbadmin_default
Creating service dbadmin_adminer
Creating service dbadmin_mysql

스택을 생성하면 dbadmin_adminer와 dbadmin_mysql의 두 서비스가 만들어진다. 그리고 dbadmin_default 네트워크도 생성한 것을 알 수 있다. 스택을 생성하면 이름이 '스택_default'인 네트워크를 기본으로 생성한다. 이 네트워크는 오버레이 네트워크로 스택에 속한 서비스를 위한 네트워크이다. 스택에 속한 서비스는 서비스 이름을 사용해서 다른 서비스의 컨테이너와 통신할 수 있다.

dbadmin 스택의 경우 dbadmin_adminer 서비스에 속한 컨테이너에서 dbadmin_mysql라는 이름을 사용해서 해당 서비스의 컨테이너에 접근할 수 있다. 웹 브라우저에서 http://호스트:8080 주소를 입력하면 dbadmin_adminer 서비스가 생성한 컨테이너에 접속한다. 여기서 서버 이름에 dbadmin_mysql을 입력해서 dbadmin 스택에 속한 mysql DB에 연결할 수 있다.

같은 스택에 속한 컨테이너는 서비스 이름으로 접근

도커 스택과 네트워크에 대한 내용은 다음 글에서 간단히 살펴본다.

스택 삭제

docker stack rm 명령어를 사용하면 스택을 삭제한다.

$ docker stack rm dbadmin
Removing service dbadmin_adminer
Removing service dbadmin_mysql
Removing network dbadmin_default

관련 글

+ Recent posts