본 포스팅은 시작하세요! 도커/쿠버네티스 서적 기반으로 작성한 포스팅입니다.
도커 컴포즈가 필요한 이유
도커커를 이용하여 웹 서버 컨테이너와 데이터베이스 컨테이너를 이용하여 웹 애플리케이션을 구동하려는 경우
# 여러 컨테이너로 구성된 애플리케이션을 구동하기 위해선 여러 개의 run 명령어가 요구됨
docker run --name mysql -d alicek106/composetest:mysql muysqld
docker run -d -p 80:80 \
--link mysql:db --name web \
alicek106/composetest:mysql:web apachectl -DFOREGROUND
따라서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너 묶음으로 관리하기 위한 도커 컴포즈가 나오게 되었음.
- 여러 개의 컨테이너 옵션과 환경을 정의한 파일을 읽어 컨테이너를 순차적으로 생성하는 방식
- 각 컨테이너의 의존성, 네트워크, 볼륨 등을 같이 정의
도커 컴포즈 설치
도커 컴포즈와 도커를 같이 설치해야 하는 경우,
도커 컴포즈만을 사용해야하는 경우
구 버전 도커 컴포즈에서 버전 업그레이드를 하는 경우 등 다양한 경우에 따라서, 설치 방법이 달라질 수 있다.
아래의 시나리오를 참고하여 자신에게 맞는 방법으로 설치하자.
아래의 시나리오는
Ubuntu Linux 기준 설치 기준이다.
시나리오 1. docker desktop 설치
https://docs.docker.com/desktop/setup/install/linux/ubuntu/
Ubuntu
Learn how to install, launch and upgrade Docker Desktop on Ubuntu. This quick guide will cover prerequisites, installation methods, and more.
docs.docker.com
기본적으로 docker desktop을 이용한 통합 설치를 권장하며,
도커 관련 아무런 패키지가 설치되지 않은 경우에 이 방법을 사용하면 되겠다.
단, docker desktop의 경우, 일정 이상의 규모의 기업에서는 라이센스 문제가 있으니 유의하도록 하자.
시나리오 2. docker compose plugin 설치
https://docs.docker.com/compose/install/linux/#install-using-the-repository
Plugin
Download and install Docker Compose on Linux with this step-by-step handbook. This plugin can be installed manually or by using a repository.
docs.docker.com
이 경우에는 이미 시스템에 Docker Engine과 Docker CLI가 설치되어 있는 상황일 때를 가정한 것이다.
sudo apt-get update
sudo apt-get install docker-compose-plugin
# 설치 확인
docker compose version
# 예상 출력
Docker Compose version vN.N.N
시나리오 3. docker compose standalone 설치
도커 컴포즈 명령어는 docker-compose(구버전) / docker compose(최신 버전) 두 가지가 있으며,
현재 docker-compose는 더 이상 지원되지 않기에 해당 방법은 권장되지 않는다.
Standalone형 vs 플러그인형
비교 항목 | Standalone (docker-compose) | 플러그인형 (docker compose) |
설치 방법 | 직접 바이너리 다운로드 | docker 패키지 설치 시 포함됨 |
실행 방식 | 독립 실행 파일 | docker 명령어의 서브커맨드 |
업데이트 | 직접 업데이트 필요 | Docker 버전 업데이트 시 함께 관리 |
운영 환경 | Docker 없이도 사용 가능 | Docker CLI가 필요함 |
https://docs.docker.com/compose/install/standalone/
Standalone
How to install Docker Compose - Other Scenarios
docs.docker.com
시나리오 4. apt repository를 이용하여 Docker 패키지 설치하기
시나리오 1 방법을 대체하여 설치할 수 있는 방법이다.
나의 경우에는 기존 Docker(구버전) & docker-compose(구버전) 에 대해서 두 개 모두 버전 업그레이드가 필요한 경우였지만, 시나리오 2 방법은 docker compose가 제대로 설치되지 않는 문제가 있어서 해당 방법을 통해 해결하였다.
실행중인 docker container는 모두 정리하고, docker service를 일시 중지한다.
sudo systemctl stop docker
https://docs.docker.com/engine/install/ubuntu/
Ubuntu
Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.
docs.docker.com
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# 최신 버전 설치
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
도커 컴포즈 활용
아무래도 해당 책은 구 버전 docker-compose에 기반한 내용이다 보니, 서적과 사용하는 명령어 및 docker-compose.yml의 문법이 달라져야 한다.
우리는 docker compose를 사용하고, docker-compose.yml도 최신 문법에 맞게 변경해야 한다.
아래와 같은 번거로운 명령어를 하나의 docker-compose.yml 파일로 통합이 가능하다.
docker 명령어
# 여러 컨테이너로 구성된 애플리케이션을 구동하기 위해선 여러 개의 run 명령어가 요구됨
docker run --name mysql -d alicek106/composetest:mysql muysqld
docker run -d -p 80:80 \
--link mysql:db --name web \
alicek106/composetest:mysql:web apachectl -DFOREGROUND
docker compose
services:
web:
image: alicek106/composetest:web
ports:
- "80:80"
depends_on:
- mysql
command: apachectl -DFOREGROUND
mysql:
image: alicek106/composetest:mysql
command: mysqld
- 최신 분법에서 version 생략 (YAML 파일의 포맷 버전)
- services: 생성될 컨테이너를 묶어놓은 단위
- web, mysql : 생성될 서비스의 이름이며, 이 항목 아래에 컨테이너가 생성될 때 필요한 옵션 지정이 가능
- [프로젝트 이름]_[서비스]_[컨테이너] 로 구성되어 있다.
docker compose 기본 명령어
# 해당 서비스 컨테이너들을 실행시킬 수 있다.
docker compose up -d
# 생성된 프로젝트의 컨테이너 종료
docker compose down
# 컨테이너 목록 확인
docker compose ps
# docker-compose.yml 파일에 명시된 특정 서비스의 컨테이너만 생성할 수 있다.
docker compose up -d mysql
# docker compose run 명령어로 컨테이너 생성할 수 있다. interacitve shell 사용 가능
docker compose run web /bin/bash
# 컨테이너 스케일 지정
docker compose up --scale mysql=2
# docker compose 는 기본적으로 현재 디렉토리 또는 상위 디렉토리에서 docker-compose.yml 이라는 이름의 YAML 파일을 찾는다.
# 옵션을 이용하여 특정 yml 파일을 지정할 수 있다.
docker compose \
-f /home/test/my-compose.yml \
up -d
docker compose 문법
서비스 정의
서비스는 도커 컴포즈로 생성할 컨테이너 옵션을 정의한다.
이 항목에 쓰인 각 서비스는 컨테이너로 구현되며, 하나의 프로젝트로서 도커 컴포즈에 의해 관리된다.
컨테이너 옵션은 서비스 이름의 하위 항목에 정의한다.
- image: 서비스 컨테이너 생성할 때 사용될 이미지의 이름
- environment: docker run 명령어의 --env, -e 옵션과 동일 / 컨테이너 내부에서 사용할 환경변수
- command: 컨테이너가 실행될 때 수행할 명령어 / docker run 의 마지막 커맨드
- ports: 서비스의 컨테이너를 개방할 포트 / 단일 호스트 환경에서 호스트의 특정 포트를 서비스의 컨테이너에 연결하면 docker compose up --scale 로 서비스의 컨테이너 수를 늘릴 수 없다. (포트 바인딩)
- build: Dockerfile에서 이미지를 빌드하여 서비스 컨테이너를 생성하도록 지정
- extends: 다른 YAML 파일이나 현재 YAML 파일에서 서비스 속성을 상속받게 설정
- depends_on: 특정 컨테이너에 대한 의존 관계, 이 항목에 명시된 컨테이너가 먼저 실행되고 실행된다. / 실행 순서만 설정할 뿐, 컨테이너 내부 애플리케이션이 준비된 상태인지 확인하지 않는다.
depends_on의 문제를 해결하는 방법 중 하나
services:
web:
...
entrypoint: ./sync_script.sh mysql:3306
# sync_script.sh 예시
# until 구문의 조건 안에 다른 컨테이너의 애플리케이션이 준비됐는지 확인하는 명령어 입력
until (상태 확인 명령어); do
echo "depend container is not available yet"
sleep 1
done
echo "depends_on container is ready
build 예시
# ./composetest 위치의 Dockerfile을 빌드하여 alicek106/composetest:web 이미지 생성
# 또한 Dockerfile에서 사용될 인자 값 설정이 가능하다.
services:
web:
build: ./composetest
context: ./composetest
dockerfile: myDockerfile
args:
HOST_NAME: web
image: alicek106/composetest:web
extends 예시
설정을 상속받을 docker-compose.yml
services:
web:
extends:
file: extend_compose.yml
service: extend_web
설정을 상속해줄 extend-compose.yml
services:
extend_web:
image: ubuntu:14.04
ports:
- "80:80"
다음 항목은 extends 상속이 불가하다.
- depends_on
- volumes_from
- links (deprecated)
네트워크 정의
- driver: 도커 컴포즈는 기본적으로 브리지 타입의 네트워크 생성 / driver를 직접 정의해 다른 네트워크 사용하도록 설정
- driver_opts: 특정 드라이버에 필요한 옵션
- ipam: IP Address Manager를 위해 사용할 수 있는 옵션 / subnet, ip 범위 등을 설정 가능
- external: 프로젝트를 생성할 때마다 네트워크를 생성하는 것이 아닌, 기존의 네트워크 사용하도록 설정 / 사용하려는 외부 네트워크 이름을 하위 항목으로 입력한 뒤 external의 값을 true로 설정한다. / 준비된 네트워크를 사용하므로 driver, driver_ops, ipam과 함께 사용할 수 없다.
driver 예시
services:
myservice:
image: nginx
networks:
- mynetwork
networks:
mynetwork:
driver: overlay
driver_opts:
subnet: "255.255.255.0"
IPAddress: "10.0.0.2"
ipam 예시
services:
...
networks:
ipam:
driver: mydriver
config:
subnet: 172.20.0.0/16
ip_range: 172.20.5.0/24
gateway: 172.20.5.1
external 예시
# alicek106_network 사용하도록 설정
services:
web:
images: alicek106/composetest:web
networks:
- alicek106_network
networks:
alicek106_network:
external: true
볼륨 정의
- driver: 볼륨을 생성할 때 사용할 드라이버 설정 / 설정하지 않으면 local / 드라이버 사용을 위한 추가 옵션은 driver_opts 하위 항목을 통해 인자로 설정
- external: 도커 컴포즈는 volume, volumes-from 옵션을 사용하면 프로젝트마다 볼륨을 생성함 / external을 이용하여 볼륨을 매번 생성하지 않고 기존 볼륨을 사용하도록 설정
external 예시
services:
web:
image: alicek106/composetest:web
volumes:
- myvolume:/var/www/html
volumes:
myvolume:
external: true
# docker-compose.yml 파일 검사(lint)
docker compose -f ${docker-compose.yml 경로}
도커 컴포즈 네트워크
YAML 파일에 네트워크 항목을 정의하지 않는다면, 도커 컴포즈는 프로젝트 별로 브리지 타입의 네트워크를 생성한다. 생성되는 네트워크의 이름은 [프로젝트 이름]_defulat 이며, docker compose up, down 명령어로 생성, 삭제 된다.
docker compose up --scale 명령어로 생성되는 컨테이너 역시, 브리지 타입의 네트워크를 사용한다.
서비스 내의 컨테이너는 --net-alias가 서비스의 이름이므로, 이 네트워크에 속한 컨테이너는 서비스의 이름으로 서비스 내의 컨테이너에 접근 가능하다.
호스트 이름으로 접근하면 서비스의 컨테이너 중 하나의 IP로 변환되며,
컨테이너가 여러 개 존재할 경우, 라운드 로빈으로 연결을 분산한다.
컨테이너 생태계
도커 사는 컨테이너 기술이 특정 벤더 또는 회사에 의존적으로 개발되지 않도록 OCI(Open Container Initiative)를 발표함.
OCI는 컨테이너를 구성하기 위해 공통 구현 런타임 및 이미지 스펙의 표준을 정의하고 있음
이후 도커는 runC, containerd, docker engine으로 분리되었다.
runC는 컨테이너에 1:1로 매칭되는 런타임 역할을 담당
containerd는 여러 개의 runC 컨테이너 프로세스 및 이미지를 관리하는 주체
docker engine은 containerd와 통신해 runC를 사용할 수 있도록 해줌
컨테이너를 생성하고 사용하기 위해 도커가 반드시 필요한 것은 아니며, runC와 containerd는 docker engine 없이도 독립적으로 사용이 가능하다.
'Kubernetes' 카테고리의 다른 글
kubernetes - service, namespace, configmap, secret (0) | 2025.04.13 |
---|---|
쿠버네티스 설치 및 기본 개념 (pod, replicaset, deployment) (0) | 2025.04.05 |
Docker Engine 핵심 정리 (0) | 2025.03.16 |
쿠버네티스 시크릿 관리 도구 (0) | 2025.01.20 |
kube-apiserver 트러블슈팅 (feat. kubelet) (1) | 2024.11.19 |