필터:Docker×

[Docker] Docker Swarm 정리

Docker를 사용하다 보면 단일 서버만으로는 한계가 생긴다. 트래픽이 몰리거나 서버가 죽었을 때 대응이 안 되기 때문이다. 이런 문제를 해결하기 위해 나온 게 바로 Docker Swarm이다. Docker vs Docker Compose vs Docker Swarm Docker — 단일 호스트, 단일 컨테이너 Docker Compose — 단일 호스트, 여러 종류의 컨테이너 Docker Swarm — 다수의 호스트(manager + workers)에 여러 종류의 컨테이너 여러 개의 호스트 묶음을 "클러스터" 라고 한다. docker swarm은 도커에서 만든 컨테이너 오케스트레이션 툴이다. 오케스트레이션이란? 오케스트레이션은 다수의 호스트로 구성된 클러스터에서 다수의 컨테이너를 관리하는 기술이다. (스케일링, 헬스체크, 로드밸런서(트래픽제어)) 혼자서 악기 하나를 연주하는 건 쉽지만, 수십 명의 연주자가 합주를 하려면 지휘자가 필요하다. docker swarm은 그 지휘 역할을 하는 것이다. 클러스터링 : 여러 대의 물리 서버를 하나의 가상 리소스로 통합한다. 스케일링 : 명령 한 줄로 컨테이너 개수를 수십 개로 늘리거나 줄인다. 상태 관리(Selfhealing) : 어떤 서버가 죽어서 컨테이너가 꺼지면 살아있는 다른 서버에 자동으로 그 컨테이너를 다시 살려낸다. 로드밸런싱(트래픽제어) : 들어오는 요청을 여러 서버에 떠 있는 컨테이너들에게 골고루 분산한다. docker swarm 클러스터 구성 실습에서 사용한 클러스터 구성은 아래와 같다. manager : 211.183.3.100 worker1 : 211.183.3.110 worker2 : 211.183.3.120 manager node 구성 manager 노드는 control plane 역할을 한다. manager에서 아래 명령으로 swarm을 초기화한다. bash docker swarm init 초기화 후 출력되는 join 토큰을 파일로 저장해두자. bash vi token manager 노드와 worker1,2 노드가 연결이 되었다. docker service 다수의 호스트에 한 가지 종류의 컨테이너를 한 개 이상 생성한다. docker run으로 컨테이너를 생성하는 것과 비슷한 개념이다. bash docker service create replicas 2 p 5858:80 name myweb oolralra/ipnginx replicas : 복제본, 컨테이너를 두 개 띄우겠다는 의미. ipnginx : 자신(컨테이너)의 IP를 출력하는 이미지. 로드밸런싱이 잘 되고 있다. bash docker service ps myweb 따로 컨테이너 배치 제한을 두지 않았기 때문에 현재 총 3개의 노드 중 아무 곳에 배치되었을 것이다. bash docker network inspect ingress docker swarm을 구성하는 순간, 오버레이 네트워크도 함께 구성된다. 오버레이 네트워크에 의해 다른 호스트에 있는 컨테이너들끼리도 서로 통신이 가능하다. 만든 web1과 web2 컨테이너를 하나로 묶어주는, 눈에는 보이지 않는 접속 포인트가 생긴다. (LB와 유사) docker stack deploy docker compose와 비슷하다. 컴포즈 파일이 필요하다. 기존의 컴포즈 파일과 거의 문법이 흡사하지만 조금 다른 부분이 있다. 스택이란 여러 종류의 서비스의 묶음이라고 생각하면 된다. bash mkdir /swarm cd /swarm vi dockercompose.yml yml services: ipnginx: image: oolralra/ipnginx deploy: replicas: 2 placement: constraints: [node.role != manager] 노드의 역할이 manager인 경우는 배치하지 않겠다. 워커노드에만 컨테이너를 배치하겠다. bash docker stack deploy c dockercompose.yml ipstack bash docker stack rm ipstack 스택 삭제 명령어. visualizer — 컨테이너 시각화 각 호스트의 컨테이너를 시각화하는 컨테이너 이미지 = visualizer bash vi visual.yml yml services: visual: image: 61.254.18.30:5000/visualizer ports: '5656:8080' volumes: /var/run/docker.sock:/var/run/docker.sock deploy: placement: constraints: [node.role == manager] bash docker stack deploy c visual.yml vis insecure 설정이 안 되어있으면 해주자. bash vi /etc/docker/daemon.json json { "insecureregistries": ["211.183.3.100:5000","61.254.18.30:5000"] } bash systemctl restart docker 211.183.3.100:5656으로 접속. 사설 저장소에서 이미지 가져오기 61.254.18.30:5000/ipnginx:latest 이미지로 컴포즈 파일을 수정해서 replicas 4개로 5959 포트로 publish 해보자. 저장소 수정 후 insecure 설정도 바꿔줘야 한다. 사설 저장소에 이미지가 존재함에도 불구하고 컨테이너가 띄워지지 않는다. 사설 저장소 insecure 설정이 manager 노드에만 되어있는데, 실질적으로 컨테이너 이미지를 땡겨오는 주체는 worker1과 worker2이기 때문이다. worker1과 worker2에도 insecure 설정을 해주면 된다. bash vi /etc/docker/daemon.json json { "insecureregistries": ["211.183.3.100:5000","61.254.18.30:5000"] } bash docker stack deploy c dockercompose.yml pstack ECR 퍼블릭 갤러리 이미지로 WordPress + MySQL 스택 배포 DB는 manager에 한 개만 띄우고, wordpress는 worker 노드에 2개를 띄워서 12345 포트로 접속 가능하게 해보자. bash vi wordpress.yml yml services: mywp: image: public.ecr.aws/docker/library/wordpress:php8.1apache ports: '12345:80' deploy: replicas: 2 placement: constraints: [node.role == worker] environment: WORDPRESSDBHOST: dbdb WORDPRESSDBUSER: wpuser WORDPRESSDBPASSWORD: '1234' WORDPRESSDBNAME: wpdb dependson: dbdb dbdb: image: public.ecr.aws/docker/library/mysql:8 deploy: placement: constraints: [node.role == manager] environment: MYSQLROOTPASSWORD=1234 MYSQLUSER=wpuser MYSQLPASSWORD=1234 MYSQLDATABASE=wpdb 잘 접속된다.

May 12, 2026Docker
[Docker] Docker Swarm 정리

[Docker] Compose 파일 작성법과 주요 옵션 총정리

Docker compose 도커(docker run)의 경우에는 단일 컨테이너를 실행한다. 도커 컴포즈는 여러 종류의 컨테이너를 한번에 띄울 수 있다. ex) 도커로 3tier를 구성한다면, docker run 을 3번 해서 webwasdb 컨테이너를 각각 구성해야 하고 —link도 구성해줘야 한다. 하지만 docker compose의 경우엔 3종류의 컨테이너를 컴포즈 파일 하나에 서 동시에 구성이 가능하다. 컨테이너를 띄우는 목적은 뭘까? 서비스를 제공하고 싶기 때문이다. 컨테이너 안에 앱, 애플리케이션이 들어있다. 도커 컴포즈에서는 이런 한 종류의 컨테이너를 service라고 지칭한다. mkdir /com cd /com vi dockercompose.yml dockercompose.yml 이라는 파일명 = 디폴트값 한 개의 서비스로 구성된 도커 컴포즈 파일 편집 services: 내가 띄울 다양한 종류의 컨테이너들 webserver: 서비스의 이름. 내가 원하는대로 정하면 됨. image: nginx ports: '8787:80' publish 기능 networks: webnet 아직 만들진 않았다. 밑에서 만들예정. 놓여질 네트워크 networks: webnet: webnet이라는 이름의 네트워크 생성. 샘플 코드. docker compose up 잘 동작한다. docker compose down 도커 컴포즈 삭제 docker compose up d docker run 과 비슷하게 d (detach) 백그라운드로 동작할 수 있다. 볼륨 구성 호스트의 현재 디렉토리에 vtest라는 디렉토리를 구성한 후 간단한 인덱스 파일을 생성하여 컨테이너에 볼륨 구성을 통해 웹루트디렉토리에 넣어주고 싶다. mkdir ./vtest 경로 생성. echo composevolumetest vtest/index.html 인덱스 파일 생성. vi dockercompose.yml services: 내가 띄울 다양한 종류의 컨테이너들 webserver: 서비스의 이름. 내가 원하는대로 정하면 됨. image: nginx ports: '8787:80' publish 기능 networks: webnet 아직 만들진 않았다. 밑에서 만들예정. 놓여질 네트워크 volumes: ./vtest:/usr/share/nginx/html 호스트의 ./vtest를 컨테이너의 /usr/share/nginx/html에 마운트 networks: webnet: webnet이라는 이름의 네트워크 생성. docker compose up d 마운트가 잘 되었다. dockercompose.yml 옵션들에 대해 알아보자. networks: 네트워크 정의 및 선택 ports: \p, publish 옵션 volumes: \v, 호스트와 컨테이너 마운트 command: CMD environment: \e, 환경변수 dependson: 의존성 설정(컨테이너 띄울 순서)도 가능. ex) node.js 앱(todo, weather, chat)의 경우 몽고디비가 연동이 안되면 앱 자체가 죽어버린다. node.js 서비스를 정의하면서 몽고디비를 depends\on 으로 걸어줘야 한다. /com의 ubun 이라는 경로에서 위 명령어를 활용하여 ubuntu:latest를 동작시키는 compose 파일을 만들어 보자. 네트워크 : ubun\net mkdir ubun cd ubun/ vi dockercompose.yml services: ubun: image: ubuntu:latest networks: ubunnet command: "sleep infinity" networks: ubunnet: docker compose up d docker compose down environment: ENVTEST=test ubun 서비스에 환경변수 추가. docker compose up d docker exec it ubunubun1 bash 환경변수가 잘 들어있다. 도커 컴포즈에서는 —link 를 굳이 명시하지 않아도 서비스의 이름으로 찾아갈 수 있다. wordpress 구성하기! mysql:8, wordpress:latest를 베이스 이미지로 하여, Dockerfile은 쓰지않고, dockercompose.yml 파일을 구성해보자. publish 포트는 wordpress는 1234로 하고, mysql는 따로 publish 하지 않는다. mkdir wp cd wp vi dockercompose.yml services: wp: image: wordpress:latest ports: '1234:80' environment: WORDPRESSDBHOST=dbdb WORDPRESSDBNAME=wpdb WORDPRESSDBUSER=wpuser WORDPRESSDBPASSWORD=1234 networks: wpnet dependson: dbdb dbdb: image: mysql:8 environment: MYSQLROOTPASSWORD: '1234' MYSQLUSER: 'wpuser' MYSQLPASSWORD: '1234' MYSQLDATABASE: 'wpdb' networks: wpnet networks: wpnet: 성공! 기존에 존재하는 네트워크를 사용하고 싶을 때 docker network create mynet driver=bridge 네트워크 생성. vi dockercompose.yml 172.19.0.0 대역에 생성됐다. 빌드한 이미지로 서비스 구성 mkdir build cd build/ vi Dockerfile FROM httpd:latest 도커 파일 생성. vi dockercompose.yml services: myweb: build: . dockercompose.yml 파일이 있는 경로(.)의 Dockerfile을 빌드 도커 컴포즈 파일 생성. docker compose up d echo buildtest index.html index.html 파일 생성. vi Dockerfile 위에서 생성한 index.html 파일을 넣어보자. FROM httpd:latest WORKDIR /usr/local/apache2/htdocs COPY index.html index.html docker compose up d curl localhost:5959 기본 페이지가 뜨고 dockercompose up d 를 했지만 이미지가 빌드되지 않았다. 이미 빌드를 한 적이 있어서 빌드된 이미지가 존재하면 다시 빌드하지 않는다. docker compose down 컨테이너 종료. docker compose up d build —build 옵션을 명시해야 계속 빌드한다. 다시 curl을 찍어보면, 수정한 Dockerfile 대로 다시 빌드가 되었다. docker compose down 컨테이너 종료. 이번엔 빌드를 하 되, 도커파일을 지정해줘보자. vi dockercompose.yml services: myweb: build: dockercompose.yml 파일이 있는 경로(.)의 Dockerfile을 빌드 context: . 디렉토리 지정 dockerfile: Dockerfile 도커파일의 이름 지정. image: myimg:1 빌드해서 나온 이미지의 이름. 단독으로 쓰일때와는 의미가 좀 다르다. ports: '5959:80' context: 도커가 빌드를 시작할 때 참고할 작업 폴더의 위치. context: . 으로 되어있으면 도커는 현재 폴더에 있는 Dockerfile, 소스코드, package.json 등을 모두 빌드 컨텍스트 라는 임시 공간에 담는다. 위 코드 중 context, build 부분 해석 → Dockerfile 란 이름의 도커파일로 빌드를 하는데, 지정한 디렉토리(현재 디렉토리)의 모든 내용을 빌드해라. docker compose scaling —scaling = 로 서비스를 구성하는 컨테이너의 수를 변경할 수 있다. dockercompose.yml 파일에 포트 범위를 명시해준다. 하나의 접속 지점을 통해 로드밸런싱이 됐으면 좋겠지만 docker compose 에서는 그게 불가능하다. 서비스를 구성하는 컨테이너마다 호스트의 포트를 1:1 로 맵핑시켜야 한다. 왜? 도커 컴포즈에서 scale 옵션을 통해 컨테이너 개수를 늘리는 것은 동일한 서비스를 여러 개 복제하여 실행하는 기능에 불과하다. 이 방식은 단순히 물리적인 숫자를 늘려줄 뿐, 외부에서 들어오는 트래픽을 각 컨테이너의 상태나 부하 정도에 맞춰 지능적으로 분산해주는 전문적인 로드밸런싱 기능을 포함하지 않는다. 따라서 여러 개의 컨테이너를 띄우더라도 특정 컨테이너에만 요청이 몰리거나, 장애가 발생한 컨테이너로 접속이 시도되는 등의 한계가 존재한다. 이를 해결하기 위해서는 Nginx나 HAProxy와 같은 별도의 로드밸런서 서비스를 도커 컴포즈 설정에 추가하여 앞단에 배치해야 한다. 전문 로드밸런서는 들어오는 모든 요청을 단일 지점에서 받아 각 컨테이너로 골고루 전달하고, 컨테이너의 생존 여부를 실시간으로 확인하여 정상적인 곳으로만 트래픽을 보내는 가이드 역할을 수행한다. 결과적으로 효율적인 트래픽 분산과 안정적인 서비스 유지를 위해서는 단순한 개수 확장보다는 로드밸런서를 통한 체계적인 관리가 필수적이다.

May 12, 2026Docker
[Docker] Compose 파일 작성법과 주요 옵션 총정리