[Docker] Docker Compose를 이용한 컨테이너 구성 관리
1. docker-compose.yml
Compose 정의 파일에는 여러 컨테이너의 설정 내용을 모아 하나의 파일에 기술한다. 이 파일에는 관리하고 싶은 컨테이너의 서비스, 네트워크, 볼륨을 정의한다. 또한 Compose 정의 파일은 버전에 따라 기술할 수 있는 항목도 다르다. 버전을 명시적으로 지정하지 않을 경우 1.0으로 동작한다. 그리고 여러 개의 Compose 정의 파일이나 확장 서비스를 사용하는 경우는 각 파일에서 동일한 버전을 사용해야한다.
# 버전 지정
version: "3"
# 서비스 정의
services:
webserver:
image: ubuntu
ports:
- "80:80"
networks:
- webnet
redis:
image: redis
networks:
- webnet
# 네트워크 정의
networks:
webnet:
# 데이터 볼륨 정의
volumes:
data-volume:
2. 이미지 관리
1) 이미지 저장
도커 컨테이너의 바탕이 되는 베이스 이미지를 지정하려면 'image'를 사용한다. 'image'에는 이미지의 이름 또는 이미지 ID 중 하나를 지정한다. 베이스 이미지는 로컬 환경에 있을 경우 그것을 사용하고, 없을 경우 Docker Hub에서 자동으로 다운로드한다. 이미지의 태그를 지정하지 않을 경우 최신버전인 latest가 다운로드된다. 제품 환경에서 사용할 경우 태그를 지정해서 버전을 고정시키는 것을 권장한다.
services:
webserver:
image: ubuntu
2) 이미지 빌드
이미지의 작성을 Dockerfile에 기술하고 그것을 자동으로 빌드하여 베이스 이미지로 지정할 때는 빌드를 지정한다. 빌드에는 Dockerfile의 파일 경로를 지정한다.
services:
webserver:
build: . # 현재 디렉토리의 Dockerfile
만약 다른 이름으로 된 Dockerfile을 빌드할 경우에는 'context'로 지정한다.
services:
webserver:
context: /data
dockerfile: DockerfileTest
도커 이미지를 빌드할 때에 인수를 args로 지정할 수 있다. 만약 bool 연산자를 사용하는 경우 따옴표로 둘러싸야한다. 변수 값은 Docker Compose를 실행하는 머신 위에서만 유효하다.
services:
webserver:
build:
args:
projectno: 1
user: oz
3. 컨테이너 관리
1) 컨테이너에서 작동하는 명령 지정
컨테이너에서 작동하는 명령은 'command' 혹은 'entrypoint'로 지정한다. 베이스 이미지에서 지정되어 있을 경우 그 명령을 덮어쓴다.
// command 지정
command: /bin/bash
// entrypoint 지정
entrypoint:
- php
- -d
- memory_limit=-1
2) 컨테이너 간 연결
다른 컨테이너에 대한 링크 기능을 사용하여 연결할 때는 'links'를 사용하여 연결할 컨테이너명을 설정한다. 컨테이너명과는 별도로 별칭을 붙이고 싶을 경우 '서비스명:별칭'으로 지정한다.
// 로그 컨테이너와 연결할 경우
links:
- logserver
- logserver:log01
서비스 간의 의존관계나 서비스를 시작하는 순서는 'depend_on'으로 지정할 수 있다. 예를 들어 webserver zjsxpdlsjfmf tlwkrgkrl wjsdp db 컨테이너와 redis 컨테이너를 시작하고 싶을 경우 사용한다. 컨테이너 상의 애플리케이션이 이용 가능해 질 때까지 기다리고 제어를 하지 않는다. 즉, 의존관계에 있는 db 서비스의 준비가 끝날 때까지 기다리는 것이 아니기 때문에 애플리케이션 측에서 대책이 필요하다.
services:
webserver:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
3) 컨테이너 간 통신
컨테이너가 공개하는 포트는 ports로 지정한다. 또한 컨테이너의 포트 번호만 지정한 경우는 호스트 머신의 포트는 랜덤한 값으로 설정된다. YAML 형식에서는 xx:yy를 시간으로 인식하기에 문자열로 정의해야한다.
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
호스트 머신에 대한 포트를 공개하지 않고 링크 기능을 사용하여 연결하는 컨테이너에게만 포트를 공개할 때는 'expose'를 지정한다. 예를 들어 로그 서버와 같이 호스트 머신에서 직접 액세스하지 않고 웹 애플리케이션 서버 기능을 갖고 있는 컨테이너를 경유해서만 액세스하고 싶은 경우에 사용한다.
expose:
- "3000"
- "8000"
4) 컨테이너 환경 변수 지정
컨테이너 안의 환경 변수를 지정할 땐느 'enviroment'를 지정한다.
# 배열 형식
enviroment:
- HOGE=fuga
- FOO
# 해시 형식
enviroment:
HOGE: fuga
FOO:
설정하고 싶은 환경 변수가 많을 때에는 'env_file'로 환경변수를 정의한 파일을 읽어들이도록 설정할 수 있다. 또한 여러 개의 환경 변수 파일을 읽어 들일 수 있다.
// envfile
HOGE=fuga
FOO=bar
// docker-compose.yml
env_file:
- ./envfile
- ./app/envfile2
- ./tmp/envfile3
※ 애플리케이션 안에서 사용하는 API 키와 같은 비밀정보의 관리는 컨테이너 오케스트레이션 툴의 기능을 사용하는 것이 좋다.
5) 컨테이너 정보 설정
Docker Compose로 생성되는 컨테이너에 이름을 붙일 때는 'container_name'을 지정한다. 예를 들어 webserver 이름으로 정의한 컨테이너에 web-container로 이름을 붙일 때 사용한다. 단 도커 컨테이너명은 고유해야하기 때문에 커스텀명을 지정하면 여러 컨테이너로 스케일할 수 없어진다.
container_name: web-container
컨테이너에 라벨을 붙일 경우에는 'labels'를 사용한다.
# 배열 형식
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
# 해시 형식
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
※ 설정한 라벨을 확인할 경우 'docker-compose config' 명령을 사용한다.
6) 컨테이너 데이터 관리
컨테이너에 볼륨을 마운트 할때는 'volumes'를 지정한다. 호스트에서 마운트할 경로를 지정하려면 '호스트의 디렉토리 경로:컨테이너의 디렉토리 경로'를 지정한다.
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
볼륨 지정 뒤에 ro(read-only)를 지정하면 볼륨을 읽기 전용으로 마운트할 수 있다. 설정 파일이 저장된 볼륨 등과 같이 쓰기를 금지하고 싶은 경우에 지정한다.
volumes:
- ~/configs:/etc/configs/:ro
다른 컨테이너로부터 모든 볼륨을 마운트할 경우에는 'volumes_from'에 컨테이너명을 지정한다.
volumes_from:
- log
[참고] 완벽한 IT 인프라 구축을 위한 Docker (2판)