Docker Swarm을 사용하여 컨테이너 간 네트워크 통신 설정
프로젝트 진행 중 모니터링 시스템 도입을 위해 각자 다른 인스턴스 내 컨테이너들을 같은 네트워크에 묶어주어야 하는 상황이 발생하였다.
프로메테우스가 메트릭을 가져오기 위해 각 마이크로서비스들에 url을 통해 접근해야 하기 때문이다.
간단하게 퍼블릭 ip를 사용하는 방법도 있었지만, 좀 더 확실한 방법인 Docker Swarm을 통해 여러 컨테이너를 하나의 네트워크로 묶어보고자 한다.
1. Docker Swarm이란?
Docker Swarm은 Docker의 클러스터링 및 오케스트레이션 도구이다. 이를 통해 여러 Docker 호스트를 하나의 가상 Docker 호스트로 관리할 수 있다. Docker Swarm을 사용하면 컨테이너를 클러스터 내의 여러 호스트에 걸쳐 분산시키고, 대규모로 컨테이너를 관리하며, 고가용성을 확보할 수 있는 장점이 있다. 비슷한 오케스트레이션 도구로는 쿠버네티스가 존재하며, 두 가지 모두 오케스트레이션 도구로 많이 사용되고 있다.
또한 Docker Swarm 모드는 Docker 엔진에 내장되어 있으며, 앞서 설명한 것 외 다양한 기능들은 공식 홈페이지에 기재되어 있다.
https://docs.docker.com/engine/swarm/
Swarm mode overview
Docker Engine Swarm mode overview
docs.docker.com
2. Docker Swarm 용어
- Magager Node : 매니저 노드는 클러스터의 상태를 유지하고, 사용자의 명령을 받아 컨테이너의 배치와 관리를 조정하는 역할을 한다.
- 클러스터 관리: 매니저 노드는 클러스터의 모든 노드를 관리하며, 클러스터의 상태와 구성을 유지한다.
- 작업 스케줄링: 매니저 노드는 서비스를 구성하는 작업(컨테이너)을 적절한 워커 노드에 배치하고 스케줄링한다.
- 서비스 오케스트레이션: 매니저 노드는 정의된 서비스의 사양에 따라 작업을 생성하고, 이러한 작업들이 클러스터 내에서 올바르게 실행되도록 관리한다.
- 클러스터 상태의 합의: 매니저 노드는 Raft 합의 알고리즘을 사용하여 클러스터의 상태를 관리한다. 이는 클러스터 내의 모든 매니저 노드가 클러스터의 상태에 대해 일관된 뷰를 갖도록 보장한다.
- 뗏목 합의 알고리즘(Raft Consensus Algorithm)은 분산 시스템 환경에서 모든 노드가 동일한 상태를 유지하도록 하고, 일부 노드에 결함이 생기더라도 전체 시스템이 문제 없이 동작하도록 만들기 위해 고안된 합의 알고리즘(Consensus Algorithm)의 일종이다.
- Worker Node : Docker Swarm에서 워커 노드는 실제로 컨테이너가 배포되고 실행되는 노드이다. 워커 노드는 매니저 노드로부터 배포 명령을 받아 컨테이너를 실행하고, 그 상태를 관리한다.
- 컨테이너 실행: 워커 노드는 매니저 노드로부터 받은 작업 스케줄에 따라 컨테이너를 실행한다. 이는 애플리케이션 서비스를 구성하는 기본 단위이다.
- 상태 보고: 워커 노드는 실행 중인 컨테이너의 상태 정보를 주기적으로 매니저 노드에 알린다. 이를 통해 매니저 노드는 클러스터의 전반적인 상태를 주기적으로 체크할 수 있으며, 문제 발생 시 바로 체크가 가능하다.
- 로드 밸런싱: 워커 노드는 네트워크 트래픽을 받아, 해당 트래픽을 클러스터 내의 다른 컨테이너로 분산할 수 있다. 이는 서비스의 로드 밸런싱을 통해 고가용성과 효율적인 리소스 사용을 가능하게 한다.
- 자원 관리: 워커 노드는 할당된 컴퓨팅 리소스(CPU, 메모리 등) 내에서 컨테이너를 실행한다. 각 노드는 리소스 사용량을 모니터링하여, 리소스가 고갈되지 않도록 관리한다.
- Service : 기본적인 배포 단위다. 하나의 서비스는 하나의 이미지를 기반으로 생성하고 동일한 컨테이너를 한개 이상 실행할 수 있다. 최종적으로 배포되는 서비스는 여러 개의 task로 구성된다.
- Task: 컨테이너 배포 단위다. 각각의 테스크가 컨테이너를 관리한다. 보통 개별 도커 컨테이너를 의미하지만, 컨테이너를 실행할 때 명령어도 포함한다.
3. 도커 스웜 모드 활성화
인스턴스는 두 개이므로 하나는 매니저 노드, 다른 하나는 워커 노드로 설정할 것이다. 먼저 매니저 노드 설정이다.
docker swarm init --advertise-addr <MANAGER-IP>
매니저 노드 추가 후 다음 명령어를 통해 잘 추가되었는지 확인해 볼 수 있다.
docker node ls
정상적으로 잘 되었으면 다음은 매니저 노드에서 워커노드를 위한 조인 토큰을 생성한다.
docker swarm join-token worker
해당 명령어는 워커 노드가 클러스터에 조인하기 위해 사용할 수 있는 토큰과 함께 조인 명령을 출력한다.
조인 명령어는 다음과 같은 형식으로 출력되며, 그대로 복사하여 워커노드에 붙여넣으면 된다.
docker swarm join --token SWMTKN-1-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx <MANAGER-IP>:2377
docker node ls 명령어를 매니저 노드에서 실행시키면 정상적으로 등록된 것을 확인해 볼 수 있다.
4. 도커 스웜 네트워크
스웜 모드는 여러 개의 도커 엔진에 같은 컨테이너를 분산해서 할당하기 때문에 각 도커 데몬의 네트워크가 하나로 묶인 환경이 필요하다.
뿐만 아니라 서비스를 외부로 노출했을 때 어느 노드로 접근하더라도 해당 서비스의 컨테이너에 접근할 수 있게 라우팅 기능이 필요하다.
이러한 네트워크 기능은 스웜모드가 자체적으로 지원하는 네트워크 드라이버를 통해 사용할 수 있다.
다음 명령어를 통해 네트워크를 확인한다.
docker network ls
기존 네트워크에 docker_gwbridge와 ingress 네트워크가 생성된 것을 볼 수 있다.
docker_gwbridge 네트워크는 스웜에서 오버레이 네트워크를 사용할 때 사용되고 ingress 네트워크는 로드 밸런싱과 라우팅 메시지에 사용된다.
ingress 네트워크
ingress 네트워크는 스웜 클러스터를 생성하면 자동으로 등록되는 네트워크로서, 스웜모드를 사용할 때만 유효하다.
ingress 네트워크는 어떤 스웜 노드에 접근하더라도 서비스 내의 컨테이너에 접근할 수 있게 설정하는 라우팅 메시를 구성하고, 서비스 내의 컨테이너에 대한 접근을 라운드 로빈 방식으로 분산하는 로드밸런싱을 담당한다.
오버레이 네트워크
오버레이 네트워크는 Docker Swarm에 참여하는 Docker Daemon 간의 통신을 관리한다. 독립 실행 컨테이너의 네트워크를 생성하는 방법과 동일한 방식으로 생성할 수 있다. 또한 생성한 오버레이 네트워크에 Swarm service를 연결시켜 service 간에 통신을 활성화 할 수 있다.
정리하면 오버레이 네트워크를 통해 클러스터 내 각 컨테이너는 오버레이 네트워크의 서브넷에 해당하는 IP 대역을 할당받고 이를 통해 서로 통신할 수 있게 된다.
5. 오버레이 네트워크 생성
docker network create -d overlay my-overlay
my-overlay라는 이름의 오버레이 네트워크를 생성한다.
# 유레카 서버 서비스 생성
docker service create --name eureka-service --replicas 2 --network my-overlay bes99/eureka-server:latest
# 게이트웨이 서비스 생성
docker service create --name gateway-service --replicas 2 --network my-overlay bes99/gateway-server:latest
# 팀 서비스 생성
docker service create --name team-service --replicas 2 --network my-overlay bes99/team-server:latest
# 유저 서비스 생성
docker service create --name user-service --replicas 2 --network my-overlay bes99/user-server:latest
각 서비스를 생성하면서 my-overay 네트워크에 연결하는 작업이다.
서비스 생성 후 docker service ls 명령어를 통해 서비스가 정상적으로 실행된 것을 확인해 볼 수 있다.
이후 다음 명령어를 통해 오버레이 네트워크를 상세 조회하면서, 정상적으로 모든 컨테이너가 네트워크를 공유하고 있는지 체크해볼 수 있다.
docker network inspect my-overlay
해당 작업까지 완료되면, 각 인스턴스들에서 가동중인 모든 컨테이너들은 같은 도커 네트워크로 묶이게 된 것이다.
이제 프로메테우스를 통해 정상적으로 메트릭 수집이 가능할 것이다.
Reference
https://velog.io/@1996yyk/Docker-Swarm-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C
https://velog.io/@fj2008/%EB%8F%84%EC%BB%A4-%EC%8A%A4%EC%9B%9C-%EA%B0%9C%EB%85%90