오토에버 클라우드 2기 39일차
클러스터 관리 및 모니터링
이전에 만든 도커 스웜 클러스터를 이용해서 관리 및 모니터링을 한다
노드 및 토큰 관리
- 워커 노드 제거 (Manager에서 수행): 특정 노드를 클러스터에서 제외
1
2
3
4
# 먼저 노드를 drain 상태로 만들어 실행 중인 컨테이너를 다른 노드로 이동
docker node update --availability drain <워커노드_이름_또는_ID>
# 클러스터에서 노드 제거
docker node rm <워커노드_이름_또는_ID>
- 워커 노드 자진 탈퇴 (Worker에서 수행)
1
docker swarm leave
- 참여 토큰 확인 (Manager에서 수행): 새로운 노드를 추가하기 위해 토큰을 다시 확인
1
2
3
4
# 워커용 토큰 확인
docker swarm join-token worker
# 매니저용 토큰 확인
docker swarm join-token manager
- 참여 토큰 재발급 (Manager에서 수행): 보안을 위해 기존 토큰을 무효화하고 새로 발급
1
docker swarm join-token --rotate worker
시각화 도구를 이용한 모니터링
dockersamples/visualizer 이미지를 사용하여 클러스터에 배포된 서비스의 상태를 웹 UI로 확인
Visualizer 서비스 생성 (Manager에서 수행)
1 2 3 4 5 6
docker service create \ --name=viz_swarm \ --publish=7070:8080 \ --constraint=node.role==manager \ --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ dockersamples/visualizer
확인: 호스트 PC의 웹 브라우저에서
http://<매니저노드_IP>:7070으로 접속하면, 어떤 노드에 어떤 서비스 컨테이너가 실행 중인지 시각적으로 확인할 수 있음

Swarm 서비스 배포 및 관리
Swarm에서 배포의 기본 단위는 서비스(Service) 서비스는 특정 이미지를 기반으로 실행되는 컨테이너들의 집합이며, 복제(replicas), 포트 노출, 네트워크 연결 등의 속성을 가짐
서비스 생성, 조회, 삭제
서비스 생성: 3초마다 메시지를 출력하는 간단한 서비스 생성(매니저 노드)
1 2 3 4 5
docker service create \ --name swarm-replicated \ --replicas 2 \ --constraint node.role==worker \ alpine:3 /bin/ash -c "while true; do echo 'Replicated Service'; sleep 3; done"

서비스 목록 조회: 현재 클러스터에서 실행 중인 모든 서비스 확인
1
docker service ls서비스 상세 정보(컨테이너) 조회: 특정 서비스에 속한 컨테이너들의 상태 확인
1
docker service ps swarm-replicated
서비스 로그 확인: 특정 서비스의 로그를 실시간으로 확인
1
docker service logs -f swarm-replicated서비스 삭제
1
docker service rm swarm-replicated
Nginx 서비스 배포와 로드 밸런싱
Nginx 서비스를 워커 노드에 2개의 복제본으로 배포하고, Swarm의 라우팅 메시(Routing Mesh) 기능을 통해 로드 밸런싱이 동작하는 것을 확인한다
Nginx 서비스 생성 (Manager에서 수행)
1 2 3 4 5 6
docker service create \ --name web-alb \ --constraint node.role==worker \ --replicas 2 \ --publish 8081:80 \ nginx
--replicas 2: 2개의 컨테이너 복제본을 생성--publish 8081:80: 클러스터의 모든 노드에서 8081번 포트를 열고, 이 포트로 들어오는 요청을 Nginx 컨테이너의 80번 포트로 전달--constraint node.role==worker: 워커 노드에만 배포
배포 확인: Visualizer나
docker service ps web-alb명령어로swarm-worker1,swarm-worker2에 컨테이너가 하나씩 배포되었는지 확인
로드 밸런싱 테스트: 각 워커 노드의 Nginx 컨테이너가 다른 내용을 표시하도록 수정하여, 요청이 분산되는지 확인
worker1에서 작업:
1 2 3 4 5 6
# worker1에서 실행 중인 nginx 컨테이너 ID 확인 docker ps # 고유한 HTML 파일 생성 echo "<h1>Hello - Docker Swarm Worker1</h1>" > index.html # 생성한 파일을 컨테이너 내부로 복사 docker cp index.html <worker1의_컨테이너ID>:/usr/share/nginx/html/index.html
worker2에서 작업:
1 2 3 4 5 6
# worker2에서 실행 중인 nginx 컨테이너 ID 확인 docker ps # 고유한 HTML 파일 생성 echo "<h1>Hello - Docker Swarm Worker2</h1>" > index.html # 생성한 파일을 컨테이너 내부로 복사 docker cp index.html <worker2의_컨테이너ID>:/usr/share/nginx/html/index.html
Manager에서 확인:
1 2 3
# manager의 IP로 여러 번 요청하여 결과가 바뀌는지 확인 curl 192.168.56.10:8081 curl 192.168.56.10:8081
호출할 때마다 “Worker1”과 “Worker2”의 메시지가 번갈아 출력

서비스 확장(Scaling)
실행 중인 서비스의 컨테이너 수를 동적으로 조절
1
2
3
4
5
# web-alb 서비스의 컨테이너 수를 5개로 확장
docker service scale web-alb=5
# web-alb 서비스의 컨테이너 수를 3개로 축소
docker service scale web-alb=3
롤링 업데이트 및 유지보수
롤링 업데이트 (Rolling Update)
서비스 중단 없이 애플리케이션의 버전을 업데이트하는 기능이다 Swarm은 새 버전의 컨테이너를 순차적으로 배포하고 이전 버전의 컨테이너를 제거하는 방식으로 무중단 업데이트를 수행
이전 버전 서비스 생성: Redis 6.0 버전으로 서비스 생성
1
docker service create --name my-database --replicas 3 redis:6.0-alpine
롤링 업데이트 수행: 이미지 버전을 6.2.5로 변경하여 서비스 업데이트
1
docker service update --image redis:6.2.5-alpine my-database
확인:
docker service ps my-database명령어를 주기적으로 실행하면, 기존 6.0 컨테이너가 순차적으로 종료되고 새로운 6.2.5 컨테이너가 실행되는 과정을 볼 수 있음
노드 유지보수 (Drain)
특정 노드의 하드웨어 교체나 점검 등 계획된 유지보수를 위해, 해당 노드에서 실행 중인 모든 서비스를 다른 노드로 안전하게 이동시키고 새로운 서비스가 스케줄링되지 않도록 설정한다
worker2 노드를
drain상태로 변경:1
docker node update --availability drain swarm-worker2상태 확인:
docker node ls를 실행하면swarm-worker2의AVAILABILITY가Drain으로 변경된 것을 확인서비스 업데이트 또는 생성: 이 상태에서 서비스를 업데이트하거나 새로 생성하면,
swarm-worker2를 제외한 다른 노드에만 컨테이너가 배포됨drain상태 해제: 유지보수 완료 후, 노드를 다시 활성 상태로 변경1
docker node update --availability active swarm-worker2
애플리케이션 스택(Stack)
지금까지는 docker service create 명령어로 서비스를 하나씩 배포했다 하지만 실제 애플리케이션은 웹, API, 데이터베이스 등 여러 서비스가 복잡하게 얽혀있기 때문에 스택(Stack)은 이렇게 관련된 여러 서비스들을 하나의 논리적인 애플리케이션 단위로 묶어, docker-compose.yml과 유사한 파일 하나로 전체 애플리케이션을 정의하고 관리하는 기능을 사용한다
스택(Stack) 파일과 docker-compose.yml의 차이점
deploy키: Swarm 모드에 특화된 배포 옵션(복제본 수, 배치 제약, 업데이트 정책 등)은 반드시deploy키 아래에 정의build키 무시:docker stack deploy명령어는build지시어를 무시 스택으로 배포할 모든 이미지는 반드시 사전에 빌드하여 Docker Hub와 같은 이미지 레지스트리에 업로드되어 있어야 한다
스택 파일 기본 구조 및 작성법
스택 파일은 docker-compose.yml 파일 형식(버전 3 이상)을 사용하지만, Swarm 클러스터 환경에 맞게 deploy 키를 사용하는 것이 핵심
version: YAML 파일 형식의 버전을 지정 (예: '3.9')
services: 배포할 각 서비스들을 정의하는 공간image: 서비스에서 사용할 컨테이너 이미지 (반드시 레지스트리에 업로드된 이미지여야 함)ports: 외부에 노출할 포트를 지정 (예:"8080:80")networks: 연결할 오버레이 네트워크를 지정volumes: 사용할 볼륨을 지정deploy: Swarm 모드에 특화된 배포 옵션을 지정replicas: 서비스 복제본 수placement.constraints: 서비스 컨테이너를 배포할 노드의 제약 조건 (예:[node.role == manager])restart_policy: 컨테이너 실패 시 재시작 정책 (예:condition: on-failure)update_config: 롤링 업데이트 시의 동작 방식 (예:parallelism: 1,delay: 10s)
networks: 서비스들이 사용할 오버레이 네트워크를 정의volumes: 데이터 영속성을 위해 사용할 볼륨을 정의
스택 배포 및 관리 명령어
스택 배포: 작성한 YAML 파일을 사용하여
mystack이라는 이름의 스택을 배포합니다.1
docker stack deploy --compose-file my-stack.yml mystack스택 관련 명령어:
스택 목록 확인:
1
docker stack ls스택에 포함된 서비스 확인:
1
docker stack services mystack
스택에 포함된 컨테이너(Task) 확인:
1
docker stack ps mystack
스택 제거: 스택과 관련된 모든 리소스(서비스, 네트워크 등)를 한 번에 삭제합니다.
1
docker stack rm mystack