도커 컴포즈 파일 구조와 컨테이너 관리
도커 컴포즈 파일의 구성 요소, 컨테이너 간 통신 방식, 애플리케이션 설정 관리
도커 컴포즈 파일 구조와 컨테이너 관리
1. 도커 컴포즈 파일의 구조
- 도커 컴포즈를 사용하면 여러 컨테이너에 걸쳐 실행되는 애플리케이션을 정의하고 관리할 수 있다.
- 각 컴포넌트는 자신만의 경량 컨테이너에서 실행되며 도커가 표준 네트워크 프로토콜을 통해 이들 컨테이너를 엮어낸다.
- 직접 순서대로 각각의 컨테이너를 도커 명령행을 통해 일일이 옵션을 지정해 가며 실행할 수도 있겠지만, 수동 실행 과정에서 조금만 옵션을 잘못 지정해도 애플리케이션이 정상적으로 동작하지 않거나 컨테이너 간 통신에 문제가 생길 수 있다.
- 수동 실행 대신 도커 컴포즈 파일에 애플리케이션의 구조를 정의할 수 있다.
- 도커 컴포즈 파일은 모든 컴포넌트가 실행 중일 때 어떤 상태여야 하는지를 기술하는 파일이다.
- docker container run 명령으로 컨테이너를 실행할 때 지정하는 모든 옵션을 모아둔 파일이다.
- 도커 컴포즈 파일을 작성하고 나면 도커 컴포즈 도구를 사용해 애플리케이션을 실행한다.
- 그러면 도커 컴포즈가 컨테이너, 네트워크, 볼륨 등 필요한 모든 도커 객체를 만들도록 도커 API에 명령을 내린다.
- 도커 컴포즈 파일 예시
1 2 3 4 5 6 7 8 9 10 11 12
version: '3.7' services: todo-web: image: diamol/ch06-todo-list ports: - "8020:80" networks: - app-net external: name: nat
- version은 이 파일에 사용된 도커 컴포즈 파일 형식의 버전을 가리킨다. 여러 번에 걸쳐 문법과 표현 가능한 요소에 많은 변화가 있었으므로 먼저 정의가 따르는 형식 버전을 지정할 필요가 있다.
- services는 애플리케이션을 구성하는 모든 컴포넌트를 열거하는 부분이다. 도커 컴포즈에서는 실제 컨테이너 대신 서비스(service) 개념을 단위로 삼는다. 하나의 서비스를 같은 이미지로 여러 컨테이너에서 실행할 수 있기 때문이다.
- image는 실행할 이름을 지정하는 필드
- ports는 공개할 포트에 대한 정보
- networks는 컨테이너가 접속할 도커 네트워크를 정의하는 필드
- 서비스 이름은 컨테이너의 이름이자 도커 네트워크상에서 다른 컨테이너들이 해당 컨테이너를 식별하기 위한 DNS 네임으로도 쓴다.
- external 필드의 의미는 nat 네트워크가 이미 존재하므로 새로 생성하지 말라는 뜻이다.
- 최종적인 결과는
docker container run -p 8020:80 --name todo-web --network nat diamol/ch06-todo-list
명령을 실행한 것과 같은 상태가 된다.
- 도커 컴포즈를 사용하려면 명령행에서 docker-compose 명령을 실행하면 된다.
up
1
docker-compose up
- up 명령어는 애플리케이션을 시작하는 명령이다.
- 도커 컴포즈는 up 명령을 실행하면 컴포즈 파일을 체크하고 애플리케이션을 정의된 상태로 실행하기 위해 필요한 요소를 준비하기 시작한다.
- 실행 중인 컨테이너가 없다면 컴포즈 파일에 정의된 내용대로 모든 서비스를 생성한다.
- 컴포즈 스크립트의 external 필드에 정의된 네트워크는 애플리케이션 실행 전에 생성돼 있어야 한다. 아직 해당 네트워크가 존재하지 않는다면 위 명령으로 nat이라는 이름의 도커 네트워크를 생성한다.
- docker-compose up 명령으로 애플리케이션이 실행된다. 도커 컴포즈는 현재 있는 리소스와 애플리케이션을 구성하는 리소스를 비교해 더 필요한 요소를 생성한다.
- 최종적으로 애플리케이션을 구성하는 단일 컨테이너가 실행된다. 컨테이너의 로그에 표준 출력을 연결해 애플리케이션의 로그를 보여 준다.
stop
1
docker-compose stop
- 컴포즈로 애플리케이션을 중지하면 모든 컨테이너가 중지된다. 중지된 컨테이너는 CPU나 메모리를 점유하지 않지만, 컨테이너 파일 시스템은 그대로 유지된다.
start
1
docker-compose start
- 다시 애플리케이션을 시작하면 기존 컨테이너가 재시작된다.
down
1
docker-compose down
- down 명령어는 애플리케이션을 제거하는 명령으로, 애플리케이션이 중지되고 컨테이너를 모두 제거한다.
- 컴포즈 파일에 포함됐으나 external 플래그가 붙지 않았다면 네트워크와 볼륨도 제거 대상이 된다.
- 컴포즈 파일을 수정하거나 도커 명령행으로 직접 애플리케이션을 수정하면, 애플리케이션이 컴포즈 파일에 기술된 구조와 불일치하게 만들 수도 있다. 이 상태에서 도커 컴포즈로 다시 애플리케이션을 관리하려 하면 비정상적인 동작을 보일 수 있다.
- 도커 컴포즈는 클라이언트 측에서 동작하는 도구이다. 도커 컴포즈 명령을 실행하면 컴포즈 파일의 내용에 따라 도커 API로 지시를 보낸다. 도커 엔진 자체는 컨테이너를 실행할 뿐, 여러 컨테이너가 하나의 애플리케이션으로 동작하는지 여부는 알지 못한다.
- 리눅스 컨테이너를 사용한다면 도커 컴포즈가 네트워크를 대신 관리해 주지만, 윈도우 컨테이너를 사용한다면 도커를 설치할 때 자동으로 생성되는 기본 네트워크 nat을 사용해야 한다.
- 도커 컴포즈 파일은 애플리케이션의 소스 코드, Dockerfile 스크립트와 함께 형상 관리 도구로 관리된다. 그리고 이 파일에 애플리케이션의 모든 실행 옵션이 기술된다. 따라서 애플리케이션 이미지 이름이나 공개해야 할 포트 번호를 따로 문서화할 필요가 없다.
2. 도커 컨테이너 간 통신
- 컨테이너는 도커 엔진으로부터 부여받은 자신만의 가상 IP 주소를 가지며 모두 같은 도커 네트워크로 연결돼 이 IP 주소를 통해 서로 통신할 수 있다.
- 애플리케이션 생애주기 동안에 컨테이너가 교체되면 IP 주소도 변경된다. IP 주소가 변경돼도 문제가 없도록 도커에서 DNS를 이용해 서비스 디스커버리 기능을 제공한다.
- 컨테이너에서 실행 중인 애플리케이션도 다른 구성 요소에 접근하기 위해 이 DNS 서비스를 사용한다.
- 컨테이너 이름을 도메인 삼아 조회하면 해당 컨테이너의 IP 주소를 찾아 준다. 이런 방법으로 도커 네트워크상에 있는 다른 컨테이너의 정보를 사용할 수 있다.
- 만약 도메인이 가리키는 대상이 컨테이너가 아니면, 도커 엔진을 실행 중인 컴퓨터에 요청을 보내 호스트 컴퓨터가 속한 네트워크나 인터넷의 IP 주소를 조회한다.
- 도커 네트워크에 연결된 모든 컨테이너는 이 네트워크 범위에 포함되는 IP 주소를 부여받는다. 그리고 이 네트워크를 통해 컨테이너 간 통신이 가능하다.
- DNS 조회를 사용하면 컨테이너가 교체돼 IP 주소가 변경되더라도 항상 새로 만들어진 컨테이너에 접근할 수 있다.
- 하나의 도메인에 대해 DNS 조회 결과에 여러 개의 IP 주소가 나올 수 있다. 도커 컴포즈는 이 점을 활용해 간단한 로드 밸런싱을 구현할 수 있다.
- 여러 개의 IP 주소가 담긴 조회 결과를 어떻게 활용할지는 전적으로 애플리케이션이 결정한다.
- 간단하게 조회 결과의 첫 번째 IP 주소만 사용할 수도 있다. 모든 컨테이너에 고르게 부하가 분배되도록 도커의 DNS 시스템은 조회 결과의 순서를 매번 변화시킨다.
3. 도커 컴포즈로 애플리케이션 설정값 지정
- 애플리케이션 설정값을 컴포즈 파일에 정의하면 같은 도커 이미지라도 다양하게 활용할 수 있고 서로 다른 각 환경에 대한 설정을 명시적으로 정의할 수 있다.
- 개발 환경과 테스트 환경의 컴포즈 파일을 별도로 작성해 두면 공개하는 포트를 환경에 따라 달리하거나 애플리케이션의 기능을 선택적으로 활성화할 수 있다.
- 패키징된 애플리케이션과 설정값을 분리할 수 있다는 것도 도커의 핵심적인 장점 중 하나다.
- 애플리케이션 이미지는 빌드 파이프라인을 통해 만들어지고 다시 테스트 환경을 거치며 운영 환경에 적합한지 검증된다.
- 각 환경마다 컴포즈 파일에서 쉽게 정의할 수 있는 환경 변수나 바인드 마운트 설정, 비밀값 등으로 설정값이 적용된다.
- 이런 방법을 통해 모든 환경에서 동일한 이미지를 사용하므로 개발 환경과 테스트 환경에서 모든 검증을 마친 이미지를 그대로 운영 환경에 투입할 수 있다.
4. 도커 컴포즈의 한계
- 컴포즈를 사용하면 애플리케이션을 정의하고 이 정의를 도커 엔진을 실행 중인 단일 컴퓨터에 적용할 수 있다.
- 하지만 도커 컴포즈는 도커 스웜이나 쿠버네티스 같은 완전한 컨테이너 플랫폼이 아니다. 도커 컴포즈에는 이들과 달리 애플리케이션이 지속적으로 정의된 상태를 유지하도록 하는 기능이 없다.
- 일부 컨테이너가 오류를 일으키거나 강제로 종료되더라도 docker-compose up 명령을 다시 실행하지 않는 한 애플리케이션의 상태를 원래대로 되돌릴 수 없다.
This post is licensed under CC BY 4.0 by the author.