3개의 리눅스 서버를 이용하여 도커 스웜 클러스터 구성하기
Virtual Box에서 3개의 리눅스 서버를 만들어서, 도커 스웜 클러스터를 구성해보는 실습을 정리해보았다.
우분투 서버 하나를 복제하여 총 3개를 만들고, 한 대의 컴퓨터에서 실습을 진행하기 때문에 이 3개의 서버는 다른 ip를 가져야 실습을 정상적으로 진행할 수 있다. 따라서 네트워크 설정을 통해 ip를 바꿔줘야 한다. 이렇게 설정한 리눅스 서버 3개를 가지고 도커 스웜 클러스터를 구성하고, 도커 스웜 모드를 활용하여 분산된 클러스터 환경에서 애플리케이션을 효과적으로 배포하고 관리하는 방법을 알아보겠다.
1. Virtual Box를 이용한 3개의 리눅스 서버 만들기
1) 복제
VM을 중지하고 [파일] 메뉴에서 [복제]를 선택한다.
- 이름 설정
- 완전한 복제 선택
- MAC 주소 정책에서 모든 네트워크 어댑터의 새 MAC 주소 설정
▷ 두 번 복제해서, 총 3개의 리눅스 서버를 만든다.
2) IP 설정
먼저 자신의 호스트 컴퓨터에서 IP와 서브넷 마스크, 그리고 Gateway를 확인한다 : `ifconfig`
리눅스 서버의 GUI 환경에서 네트워크 설정을 한다.
GUI 환경에서는 상단의 맨 오른쪽 아이콘을 누르고, [Wired Connecting] 또는 [유선 연결]에서 [유선 네트워크 설정]을 클릭한다.
설정 아이콘을 클릭한다.
IPv4 > 수동 > 주소 입력
3) Hostname 변경
- hostname 변경: 각 서버에서 아래 명령어로 호스트 이름을 변경한다.
sudo hostnamectl set-hostname 호스트이름 (예: swarm-manager, swarm-worker1, swarm-worker2)
- 변경 확인 후 서버 재부팅:
cat /etc/hostname
sudo reboot now
- ping 테스트: 각 서버에서 다른 서버의 이름으로
ping
명령을 실행하여 통신이 되는지 확인한다.
4) DNS 설정
- /etc/hosts 파일 수정: 각 서버에서
/etc/hosts
파일을 수정하여 서버 간 통신이 가능하도록 설정한다.
sudo nano /etc/hosts
swarm-manager에서:
(앞서 192.168.203.200, 201, 202가 잘 안 돼서 ip를 192.168.137.100, 101, 102로 바꿔서 진행했다.)
127.0.1.1 swarm-manager
192.168.137.100 swarm-manager
192.168.137.101 swarm-worker1
192.168.137.102 swarm-worker2
`ifconfig` 명령으로 확인해보면, ip가 바뀐 것을 확인할 수 있다.
- swarm-worker1과 swarm-worker2에서도 비슷하게 수정한다.
- ping 테스트: 각 서버에서 다른 서버의 이름으로
ping
명령을 실행하여 통신이 되는지 확인한다.
2. 다중 호스트 기반 도커 스웜 모드 클러스터
1) 도커 스웜 모드 개요
- 도커 스웜 모드는 물리적 서버 클러스터를 통해 컨테이너를 확장하는 도구이다. 여러 서버에 분산된 워크로드를 쉽게 구현할 수 있다.
- 여러 클러스터에 컨테이너화 된 애플리케이션 기반의 마이크로서비스를 배포해서 다양한 런타임 환경에서 애플리케이션의 가용성과 효율성을 높일 수 있다.
- 동일한 컨테이너를 공유하는 여러 클러스터 내의 노드에서 애플리케이션을 원활하게 실행할 수 있도록 하는 도커 자체의 컨테이너 오케스트레이션 도구이다.
- 스웜(Clustering): 클러스터화 된 서버들의 도커 엔진을 하나의 자원 풀로 묶어 스웜을 형성한다.
- 예전 버전에서는 별도의 스웜 엔진을 가지고 있었지만, 지금은 도커 엔진으로 통합되어 기본 도커 오케스트레이션 도구 모델로 사용되기 시작했다.
2) 도커 스웜 모드 주요 기능
- 도커 엔진과 통합된 클러스터 환경: 별도의 오케스트레이션 도구 없이도 다중 서버 클러스터 환경에서 컨테이너 애플리케이션 서비스를 배포하고 관리할 수 있다.
- 분산 설계와 역할 분리:
- 다중 서버를 클러스터에 합류시키면, 모든 도커 스웜 모드의 노드는 각각 다른 역할을 수행한다.
- Manager Node: 클러스터의 관리 역할을 하며, 컨테이너 스케줄링 및 상태 유지 등을 담당한다.
- Worker Node: 컨테이너를 실행하는 역할만 수행한다.
- Leader Node: 여러 매니저 노드 중 리더로 설정되어 관리 기능을 수행한다.
- 단일 관리자 환경이라면 Manager Node 와 Worker Node로만 나누게 되지만,
- 다중 매니저 모드로 구성하게 되면 매니저 중 하나를 Leader Node로 설정해서 수행한다.
- 도커 스웜 vs. 쿠버네티스: 쿠버네티스에서는 마스터 노드가 서비스 컨테이너를 실행하지 않지만, 도커 스웜의 관리자 노드는 작업자 노드처럼 서비스 컨테이너도 실행할 수 있다.
- 관리 역할을 수행하는 노드의 부하를 고려해서 각 역할을 분리해 사용하는 것을 권장한다.
- 매니저 노드에 서비스 컨테이너를 수행하지 않도록 역할 분리를 수행하는 방법은 도커 서비스 생성 시 `--constraint node.role!=manager` 옵션을 사용하면 된다.
서비스 확장 및 원하는 상태 조정
- 서비스 복제 및 확장: 도커 스웜 모드에서 서비스 생성 시 복제본(replica)을 여러 개 배포하여 서비스의 안정성을 확보할 수 있다. 초기 구성 후에도 스웜 관리자를 통해 서비스의 확장 및 축소를 애플리케이션 가용성에 영향을 주지 않고 수행할 수 있다.
- 모니터링 및 장애 대응: 서비스가 배포되면 매니저 노드가 지속적으로 모니터링을 수행한다. 만약 서비스 장애(노드 장애 또는 서비스 실패)가 발생하면, 장애가 발생한 서비스를 대체할 복제본을 자동으로 생성하여 지속적으로 서비스를 제공한다. 이를 요구 상태 관리(Desired State Management)라고 하며, 대부분의 오케스트레이션 도구들의 주요 목적이다.
서비스 스케줄링
- 작업 단위 배포: 스웜 모드에서 클러스터 내의 노드에 작업(task) 단위의 서비스 컨테이너를 배포하는 과정을 서비스 스케줄링이라 한다.
- 스케줄링 전략:
- spread 전략: 모든 작업자 노드에 균등하게 할당하는 방식.
- binpack 전략: 작업자 노드의 자원 사용량을 고려하여 할당하는 방식.
- random 전략: 임의의 노드에 할당하는 방식.
- 스케줄링 전략은
swarm manage --strategy
옵션을 이용해 변경할 수 있다.
- 고가용성 분산 알고리즘: 도커 스웜 모드는 고가용성 분산 알고리즘을 사용하여, 생성되는 서비스의 복제본을 여러 작업자 노드에 분산 배포한다. 복제본이 가장 적은 작업자 노드를 우선 선택하며, 이미 스케줄링된 다른 서비스 컨테이너가 적은 작업자 노드도 우선 배포 대상이 된다.
로드 밸런싱
- 인그레스 네트워크(Ingress Network): 도커 스웜 모드를 초기화하면 자동으로 생성되는 네트워크 드라이버로, 노드 간의 로드 밸런싱 및 외부 서비스 노출을 담당한다.
- 포트 설정 및 서비스 연결: 도커 스웜 모드는 서비스 컨테이너에 Published Port를 자동으로 할당하거나, 수동으로 노출할 포트를 구성할 수 있다. 서비스 컨테이너가 포트를 오픈하면, 모든 노드에서 동일한 포트가 열리며, 클러스터 내의 어떤 노드에 요청을 전달하더라도 실행 중인 서비스 컨테이너에 자동으로 연결된다.
- 라우팅 메쉬: 도커 스웜 모드의 라우팅 메쉬 기능을 통해 노드 간의 요청이 적절히 전달되며, 이를 통해 로드 밸런싱이 가능해진다.
인그레스의 역할이 무엇인가?
**인그레스(Ingress)**는 도커 스웜 모드에서 노드 간의 로드 밸런싱과 외부 네트워크에서 내부 서비스로의 트래픽 라우팅을 담당하는 네트워크 드라이버입니다. 인그레스 네트워크를 통해 클러스터 내의 모든 노드에서 동일한 포트가 열리며, 클러스터에 속한 어느 노드로 요청이 들어오더라도, 실행 중인 서비스 컨테이너로 적절하게 요청이 전달됩니다. 이 과정은 라우팅 메쉬(Routing Mesh) 기능을 통해 이루어지며, 서비스의 고가용성과 확장성을 유지할 수 있습니다."
서비스 검색 기능
- DNS 기반 서비스 검색: 도커 스웜 모드는 자체 DNS 서버를 통해 서비스 검색(service discovery) 기능을 제공한다. 매니저 노드는 클러스터에 속한 모든 노드의 서비스에 고유한 DNS 이름을 할당하며, 이 DNS 이름을 통해 클러스터 내에서 실행 중인 모든 컨테이너를 조회할 수 있다. 이를 통해 클러스터 내 서비스 간의 연결을 쉽게 관리할 수 있다.
롤링 업데이트
노드 단위로 점진적인 업데이트를 수행하는 것
- 점진적 업데이트: 롤링 업데이트는 각 작업자 노드에서 실행 중인 서비스 컨테이너를 순차적으로 업데이트하는 방식이다. 하나의 작업자 노드에서 기존 컨테이너를 중지하고 새로운 버전의 컨테이너를 생성한 후, 설정된 지연 시간 동안 대기한 후 다음 작업자 노드에서 같은 작업을 반복한다. 이를 통해 서비스 중단 없이 점진적인 업데이트가 가능하다.
- 지연 시간 설정 및 롤백: 롤링 업데이트는 업데이트 지연 시간을 설정할 수 있어, 각 작업자 노드에서 순차적으로 업데이트를 수행한다. 또한, 업데이트 실패 시 자동으로 중지하거나 이전 버전으로 롤백하는 기능도 제공하여 안정성을 보장한다.
**롤링 업데이트**는 소프트웨어의 새 버전을 점진적으로 배포하는 방식이다. 서버나 컨테이너를 하나씩 업데이트하여 새 버전과 구버전을 동시에 유지하며 비교할 수 있다. 문제가 발생하면 중간부터 롤백이 가능하다. 쇼핑몰 이벤트처럼 점진적 적용이 필요한 상황에서 많이 사용된다.
3) 도커 스웜 모드 초기 연결 구성
도커 스웜 모드 초기화 (매니저에서 작업)
먼저, 스웜 모드가 활성화되어 있는지 확인해야 한다. 이를 위해 다음 명령어를 실행한다:
docker info | grep Swarm
현재 상태가 inactive
이면 스웜 모드가 비활성화되어 있는 것이다.
초기화 명령
스웜 모드를 활성화하려면 초기화 명령을 입력해야 한다. 여기서 --advertise-addr
옵션 뒤에는 매니저 노드의 IP 주소를 입력한다:
docker swarm init --advertise-addr 192.168.200.200
이 명령을 실행하면 노드가 참여할 때 사용할 수 있는 토큰 값이 출력된다.
포트 개방
스웜 모드가 활성화되면, 다음과 같은 포트들이 개방된다:
- 2377번 포트: 스웜 관리용
- 7946번 포트: 작업자 노드 간의 통신용
- 4789번 포트: 인그레스 네트워크용
이 포트들이 제대로 개방되었는지 확인하려면 다음 명령어를 사용한다:
sudo netstat -nlp | grep dockerd
도커 스웜 모드 작업자 노드 연결
작업자 노드를 스웜에 연결하려면, 아래와 같이 토큰 값과 매니저 IP를 사용하여 명령어를 입력한다:
docker swarm join --token 토큰값 192.168.137.100:2377
매니저에서 토큰 확인
현재 사용 중인 작업자 노드의 조인 토큰을 확인하려면 다음 명령어를 사용한다:
docker swarm join-token worker
다중 매니저 노드 구성
매니저 노드를 추가하고 싶다면, 다음 명령어로 매니저 노드의 조인 키를 조회할 수 있다:
docker swarm join-token manager
노드 확인
현재 연결된 노드를 확인하려면 다음 명령어를 사용한다:
docker node ls
도커 정보 확인
스웜 정보도 포함한 도커의 전체 정보를 확인하려면 다음 명령어를 사용한다:
docker info
새로 만들어진 네트워크 확인
현재 활성화된 네트워크 목록을 보려면 아래 명령어를 사용한다:
docker network ls
이 명령어를 실행하면 다음과 같은 결과를 얻을 수 있다:
NETWORK ID NAME DRIVER SCOPE
4810e3536dea bridge bridge local
af6a7225f58d docker_gwbridge bridge local
fb625edba68e host host local
du2xxydflei5 ingress overlay swarm
b1a4049e1ff1 none null local
운영 도중 노드 확장
운영 중에 노드를 추가하고 싶다면 새로운 토큰이 필요할 수 있다. 이 경우, 다음 두 가지 명령어를 통해 토큰을 받을 수 있다:
docker swarm join-token --rotate worker
docker swarm join-token -q worker
접속 에러 처리
만약 접속 중에 Error response from daemon: rpc error...
같은 에러가 발생한다면, 이는 방화벽 때문일 수 있다. 방화벽을 비활성화하려면 아래 명령어를 사용한다:
sudo ufw disable
현재 방화벽 상태를 확인하고 싶다면 다음 명령어를 사용한다:
sudo ufw status
또한, firewalld 서비스를 중지하려면 다음 명령어를 사용할 수 있다:
sudo systemctl stop firewalld.service
노드 연결 중지
작업자 노드가 스웜에서 빠져나가기를 원할 경우, 아래와 같이 입력한다:
docker swarm leave
이렇게 하여 도커 스웜 모드의 초기 연결 구성을 완료할 수 있다.
도커 스웜 시각화 도구
docker service create --name=viz_swarm -p 7070:8080 --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock dockersmaples/visualizer
스웜모드를 GUI로 관리하기 위한 도구
docker run -it --rm --name swarmpit --volume /var/run/docker.sock:/var/run/docker.socket swarmpit/install
4) 서비스 배포
docker run
대신에 docker service create
를 이용하는데, docker run
명령과 거의 유사하다.
5) 서비스 생성 실습
1. 사전 준비: 이미지 다운로드
- Swarm Manager 컴퓨터에서 인터넷 연결을 설정한 후, 필요한 이미지(
nginx
,busybox
,alpine:3
)를 다운로드한다
docker pull nginx
docker pull busybox
docker pull alpine:3
2. Docker Swarm 초기화
- Swarm 모드를 초기화한다. Swarm Manager에서 다음 명령을 실행:
docker swarm init --advertise-addr 매니저IP
3. 서비스 생성 (Alpine 이미지)
alpine:3
이미지를 이용하여 다음과 같은 서비스를 생성한다:
이 명령은 무한 루프로 텍스트를 출력하는 서비스 컨테이너를 만든다.
docker service create --name swarm-start alpine:3 /bin/sh -c "while true; do echo 'Docker Swarm mode Start.'; sleep 3; done"
4. 서비스 및 컨테이너 확인
- 생성된 서비스를 확인한다:
docker service ls
- 서비스에 대한 컨테이너 정보를 확인한다:
docker service ps swarm-start
5. 로그 확인
- 서비스의 로그를 실시간으로 확인한다:
docker service logs -f 컨테이너ID
6. 서비스 중지
- 서비스 중지를 원할 때는 다음 명령으로 서비스 제거:
docker service rm swarm-start
Docker Compose와 Docker Swarm의 차이점
- Docker Compose --scale 옵션:
- 하나의 노드(단일 Docker 엔진)에서 여러 개의 컨테이너를 생성한다.
- 여러 컨테이너가 동일한 이미지를 사용할 경우, 각 컨테이너에 고유한 포트를 매핑해야 한다.
- Docker Swarm Replicas:
- 여러 Docker 엔진(노드)에 분산된 컨테이너를 생성한다.
- 노드 개수보다 더 많은 컨테이너를 요청할 경우, 특정 노드에 여러 개의 컨테이너가 배치된다.
docker-compose에서 scale 옵션을 이용해서 하나의 이미지로 여러 개의 컨테이너로 만들 때 주의할 점은 포트를 외부로 노출한다면 포트 여러 개를 매핑해야 한다.
services:
mydb:
image: mysql
ports:
- 3306:3306
docker-compose up -d --scale mydb=2
이렇게 하면 에러가 난다.
포트가 3306:3306인 것을 2개를 만드려고 해서 충돌이 나기 때문이다.
ports를 3306-3307:3306으로 해줘야 한다.
swarm-manager에서 nginx 서비스를 2개 생성
docker service create --name web-alb --constraint node.role==worker --replicas 2 --publish 8001:80 nginx
여러 개의 서비스를 만들고자 하는 경우에는 `replicas` 옵션을 이용한다.
이때, 노드의 개수보다 더 많은 서비스 개수를 요청하면 특정 노드에 여러 개가 배치된다.
7. Nginx 서비스 생성 (Replicas 설정)
nginx
서비스를 2개의 복제본(Replica)으로 생성한다:--replicas 2
: 2개의 복제본을 생성.--constraint node.role==worker
: 워커 노드에서만 서비스가 실행되도록 설정.
docker service create --name web-alb --constraint node.role==worker --replicas 2 --publish 8001:80 nginx
8. Global Mode 서비스
- 모든 노드에 컨테이너를 배치하려면
global
모드를 사용한다:- 새로운 노드가 추가되면 자동으로 해당 노드에도 서비스가 배치된다.
docker service create --name global-service --mode global nginx
9. 자동 복구 기능
replicas
를 이용해 생성한 컨테이너는 장애가 발생할 경우 자동 복구 기능을 제공하여 서비스 중단을 최소화한다.
Docker Swarm 에 대한 도커 공식 문서
https://docs.docker.com/engine/swarm/
Swarm mode
Docker Engine Swarm mode overview
docs.docker.com