도커 스웜(Docker Swarm) 클러스터를 세팅하기 전에 인바운드와 아웃바운드, iptable 등 방화벽에 필요한 포트를 열어주면 서비스들을 클러스터 위에 올려서 운영할 수 있다.
도커 스웜에 대한 포스팅을 정리하기 불과 몇개월전에 사내 vxRail 환경에서 스웜 클러스터를 구축하다가 억까당했던 트러블슈팅 경험담을 먼저 공유해본다.
트러블슈팅: VxRail UDP 4789 충돌
인프라팀에 요청해서 vaRail 에서 서버 2대를 전달받았다. 필요한것들을 설치하고 스웜 통신에 필요한 방화벽 등을 확인하고 노드를 조인시킨 후 노드 상태도 Ready로 잘 뜨고 개발용 서비스를 올렸다. 그런데, 서로 다른 노드에 배포된 컨테이너끼리 통신이 되지 않는 문제가 발생했다.
같은 워커 노드 안에 있는 컨테이너끼리는 통신이 잘 되는데, 다른 노드로 넘어가기만 하면 오버레이 네트워크가 통신이 안되고 있었다. iptable 에도 문제가 없었고 설치하는 과정에도 문제가 없을뿐만 아니라 인프라팀에서는 모든 포트가 열려있다고 확답까지 받은 상태였다.

원인: 인프라 레이어의 VXLAN 포트 충돌
도커 스왐하나 구축하지 못한다고 쿠사리를 엄청 먹었다. 이때가 다른 회사와 합병(?)되면서 다른 회사로부터 엔지니어들이 많이 들어와있었을 때였다. 다른 엔지니어에게도 SOS 를 요청했지만 다들 쿠버네티스는 사용해봤는데 도커 스왐은 사용해보지 못해서 해결을 못 해주겠다는 답변이었다. (그래도 쿠사리는 이빠이 먹었ㄷ..)
많은 에피소드가 있었지만 일단 패킷을 뜯어보고 vxRail 이 회사에 배달오던 시절까지 복기를 해보니 원인은 가상화 장비에 있었다. 당시 도커 노드들이 올라가 있는 호스트 인프라는 Dell EMC의 VxRail (VMware HCI) 환경이었다. 이것을 힌트로 구글링을 해보았다.
Docker-swarm overlay network is not working for containers in different hosts
We have a networking problem in docker-swarm. The problem is below; we have virtualized environment over wmware ( vsphere 6.02) our servers are created from vmware say server1 and server2 we have a
stackoverflow.com
도커 스웜은 서로 다른 서버에 있는 컨테이너들을 묶기 위해 오버레이 네트워크를 구성하며, 이 기반 기술로 VXLAN을 사용한다. 스웜의 VXLAN 기본 트래픽 포트는 UDP 4789다.
문제는 VxRail 환경 역시 내부 네트워크 가상화를 위해 VXLAN을 적극 사용하며 기본 포트로 UDP 4789를 점유하고 있었다는 점이다.
스웜이 4789 포트로 패킷을 쏘면, 하단의 VxRail 인프라가 "이거 내 패킷인가?" 하고 가로채거나 알 수 없는 패킷으로 취급해 드랍(Drop)시켜버렸던 것이다.
해결 방안: 스웜 데이터 패스 포트(Data Path Port) 수정
VxRail의 설정을 바꿀 수는 없으니, 내가 할 수 있는 도커 단에서 우회를 해야했다. 도커 스웜은 초기화(swarm init)나 노드 추가(join) 시 --data-path-port 플래그를 통해 오버레이 트래픽 포트를 변경할 수 있다.

vaRail 에서 사용중인 포트4789 에서 다른 포트(예: 7789)로 변경하여 클러스터를 세팅하니 컨테이너 간의 통신이 잘 되었다. 온프레미스 환경에서 원래는 잘 되는건데 잘 안된다면 인프라의 환경도 고려를 해봐야 할 것 같다.
도커 스왐으로 소규모 서비스 운영하기
1. 왜 쿠버네티스(k8s) 대신 스웜인가?
서버가 10~20대 이상이고 트래픽이 예측 가능해 대규모 서비스라면 당연히 쿠버네티스로 가는 것이 교과서적인 답일 수 있다. 물론 그에 따른 엔지니어도 있어야겠지만,,, 하지만 관리해야 할 서버가 10~20대 미만이고, 띄워야 할 서비스가 수십 개 수준인 '소규모 서비스'라면 쿠버네티스의 런닝커브와 유지보수 비용을 고려해보면 배보다 배꼽이 더 커져서 오버 엔지니어링이 되버린다.
반면 도커 스웜은 기존에 쓰던 docker-compose.yml 문법을 거의 그대로 사용할 수 있고, 도커 엔진 자체에 내장되어 있어 별도의 무거운 설치 과정도 필요가 없다. 소규모의 인원으로 빠르게 클러스터링의 이점(고가용성, 무중단 배포)을 누리기에는 스웜만한 가성비가 없다고 생각이 든다.
2. 스웜 클러스터의 라이프 사이클: 배포, 스케일링, 무중단 업데이트
docker-compose 파일 하나로 다중 노드를 아래 시퀀스처럼 관리할 수 있다.

스택(Stack) 배포
스웜 클러스터 전체에 서비스를 배포할 때는 스택(Stack)이라는 개념을 사용한다.
작성해 둔 docker-compose.yml 파일을 매니저 노드에 올려두고 아래 명령어만 치면 끝난다.
$ docker stack deploy -c docker-compose.yml my_service
무중단 롤링 업데이트 (Rolling Update)
서비스를 운영하다 보면 버전 업데이트는 반드시 일어나게 된다. 스웜은 컨테이너를 한 번에 다 끄고 새로 켜는 방식이 아니라, 설정된 비율에 따라 순차적으로 컨테이너를 교체하는 롤링 업데이트를 기본적으로 지원한다.
$ docker service update --image web_service:v2.0 my_service
해당 명령어로 클러스터 내의 컨테이너들은 사용자의 접속 끊김(Downtime) 없이 부드럽게 새 버전으로 교체가 된다. 배포한 이미지에 문제가 있을 경우에는 --rollback 옵션으로 되돌릴 수 있다.
스케일링 (Scale In/Out)
이벤트 등으로 특정 API 서버에 트래픽이 몰린다면, 해당 컨테이너의 개수를 늘려주면 된다. (물론 서버가 감당할 정도의 트래픽이어야..)
$ docker service scale my_service=5
기존에 2개 돌고 있던 컨테이너를 5개로 늘려달라고 요청하면, 스웜은 노드들에게 3개를 더 띄우고 내부 로드밸런서(Ingress)를 통해 트래픽을 고르게 분배시켜준다.
'DevOps > 도커 (Docker)' 카테고리의 다른 글
| [Docker] - 007. Docker Swarm Port 열기 (2376/2377/7946/4789) (0) | 2024.05.06 |
|---|---|
| [Docker] - 006. Docker Swarm 이란 (0) | 2024.05.06 |
| [Docker] - 005. Docker Compose 활용하기 (0) | 2024.05.04 |
| [Docker] - 004. Multi Stage Build 와 Base 이미지 만들기 (0) | 2024.04.19 |
| [Docker] - 003. DockerFile 캐싱 전략 (0) | 2024.04.19 |