컴포즈 파일과 스택
컴포즈 파일을 이용하면 서비스를 보다 쉽게 만들고 업데이트할 수 있다. 다음 컴포즈 파일을 보자.
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