새소식

독서/시작하세요! 도커 & 쿠버네티스

7. 도커 스웜

  • -

도커 스웜을 사용하는 이유

 앞의 내용은 대부분 하나의 호스트를 기준으로 합니다. docker ps는 하나의 도커 엔진에 존재하는 컨테이너의 목록을 출력하며 create, run 명령어 또한 하나의 도커 엔진에 컨테이너를 생성합니다. 하지만 호스트 머신에서 도커 엔진을 구동하다가 CPU, 메모리 같은 자원이 부족하다면 여러 방법이 있겠지만 가장 많이 사용하는 방법이 여러대의 서버를 클러스터로 만들어 자원을 병렬로 확장하는 것입니다.

 

그러나 여러대의 서버를 하나의 자원 풀로 만드는 것은 쉬운 작업이 아닙니다. 새로운 서버나 컨테이너가 추가됐을 때 이를 발견하는 작업부터 어떤 서버에 컨테이너를 할당 할 것인가에 대한 스케줄러, 로드밸런서, 클러스터 내의 서버가 다운됐을 때 고가용성을 어떻게 보장할지 등이 문제가 남아있습니다. 이러한 문제를 해결하는 여러 솔루션을 오픈소스로 활용할 수 있는데 대표적인것이 도커에서 공식으로 제공하는 도커 스웜스웜모드 입니다.

 

 

스웜 클래식과 도커 스웜 모드

 스웜 클래식과 스웜 모드는 여러 대의 도커 서버를 하나의 클러스터로 만들어 컨테이너를 생성하는 여러 기능을 제공합니다. 다양한 전략을 세워 컨테이너를 특정 도커 서버에 할당할 수 있고, 유동적으로 서버를 확장할 수도 있습니다. 또한 스웜 클러스터에 등록된 서버의 컨테이너를 쉽게 관리할 수 있습니다.

 

도커 스웜에는 2가지 종류가 있습니다. 첫 번째는 도커 버전 1.6 이후부터 사용할 수 있는 컨테이너로서의 스웜, 두 번쨰는 도커 버전 1.12 이후부터 사용할 수 있는 도커 스웜 모드입니다. 뒤에서는 첫 번째를 스웜 클래식, 두 번째를 스웜 모드라고 부르겠습니다. 둘의 가장 큰 차이점은 목적에 있습니다.

 

 스웜 클래식은 여러 대의 도커 서버를 하나의 지점에서 사용하도록 단일 접근접을 제공. 일반적인 도커 명령어와 도커 API로 클러스터의 서버를 제어하고 관리할 수 있는 기능을 제공합니다. (도커 공식문서에서도 레거시로서 언급하고 있다.)

 

 스웜 모드마이크로서비스 아키텍처의 컨테이너를 다루기 위한 클러스터링 기능에 초점을 맞추고 있습니다. 컨테이너를 동시에 여러 개 생성해 필요에 따라 유동적으로 컨테이너의 수를 조절할 수 있으며, 컨테이너로의 연결을 분산하는 로드밸런싱 기능을 자체적으로 지원합니다. (스웜 모드가 안정성, 서비스 확장성 등 여러 측면에서 뛰어나 더 많이 사용함)

 

 스웜 클래식과 스웜 모드의 다른 차이점은 분산 코디네이터, 에이전트와 같은 클러스터 툴이 별도로 구동되느냐 입니다. 여러개의 도커 서버를 하나의 클러스터로 구성하려면 각종 정보를 저장하고 동기화하는 분산 코디네이터, 클러스터 내의 서버를 관리하고 제어하는 매니저, 각 서버를 제어하는 에이전트가 반드시 있어야 합니다.

 스웜 클래식은 분산 코디네이터, 에이전트 등이 별도로 실행돼야 하지만, 스웜 모드는 클러스터링을 위한 모든 도구가 도커 엔진 자체에 내장돼 있기 때문에 더욱 쉽게 서버 클러스터를 구성할 수 있습니다.

 

 

도커 스웜 모드의 구조

 스웜 모드는 매니저 노드워커 노드로 구성돼 있습니다. 워커 노드는 실제로 컨테이너가 생성되고 관리되는 도커 서버이고, 매니저 노드는 워커 노드를 관리하기 위한 도커 서버입니다. 매니저 노드에도 컨테이너가 생성될 수 있고, 매니저 노드는 기본적으로 워커 노드의 역할을 포함하고 있습니다.

 

 만약 매니저 노드 사이에 네트워크 파티셔닝과 같은 현상이 발생했을 경우 짝수 개의 매니저로 구성한 클러스터는 운영이 중단될 수도 있지만, 홀수 개로 구성했을 때는 과반수 이상이 유지되는 쿼럼 매니저에서 운영을 계속할 수 있습니다. 따라서 스웜 매니저는 가능한 한 홀수 개로 구성하는 것을 권장합니다.

 

 

도커 스웜 모드 클러스터 구축

 docker swarm init 명령어로 매니저 역할을 할 서버에서 스웜 클러스터를 시작합니다. --advertise -addr은 다른 도커 서버가 메니저 노드에 접근하기 위한 IP주소를 입력합니다. 즉 매니저의 IP 주소를 입력합니다. 

# docker swarm init --advertise-addr 192.168.0.100 (예시)

 

 매니저 노드에 2개 이상의 네으퉈크 인터페이스 카드가 있따면, 어느 IP 주소로 매니저에 접근해야 할지 다른 노드에 알려주어야 합니다. 예로 ifconfig 같은 명령어를 입력했을 때 출력된 IP 주소가 172.17.0.5와 192.168.0.100 2개 존재한다면 스웜 클러스터 내에서 사용할 IP 주소를 지정해야 합니다.

 

 위 명령어의 출력 결과 중 docker swarm join 명령어는 새로운 워커 노드를 스웜 클러스터에 추가할 때 사용됩니다. --token 옵션에 사용 된 토큰 값은 새로운 노드를 해당 스웜 클러스터에 추가하기 위한 비밀키입니다

 

 매니저 노드는 일반적인 매니저 역할을 하는 노드와 리더 역할을 하는 노드로 나뉩니다. 리더 매니저는 모든 매니저 노드에 대한 데이터 동기화와 관리를 담당하므로 항상 작동할 수 있는 상태여야 합니다. 리더 매니저의 서버가 다운되는 등의 장애가 생기면 매니저는 새로운 리더를 선출하는데, 이때 Raft Consensus 알고리즘을 사용합니다. 

 

 워커 노드를 삭제하고 싶다면 해당 워커 노드에서 docker swarm leave 명령어를 입력하면 되고, 특정 워커 노드가 leave 명령어로 스웜 모드를 해제하면 매니저 노드는 해당 워커 노드의 상태를 Down으로 인지할 뿐 자동으로 워커 노드를 삭제하지 않습니다. 따라서 매니저 노드에서 docker node rm 명령어로 삭제해야 합니다.

 

 

스웜 모드 서비스

 지금까지 사용해온 도커 명령어의 제어 단위는 컨테이너입니다. docker run 명령어는 컨테이너를 생성하고, docker rm 명령어는 컨테이너를 삭제했던 것처럼 도커 클라이언트에서 사용하는 명령어가 제어하는 것은 컨테이너입니다. 그러나 스웜 모드에서 제어하는 단위는 컨테이너가 아닌 서비스입니다. 서비스는 같은 이미지에서 생성된 컨테이너의 집합이며, 서비스를 제어하면 해당 서비스 내의 컨테이너에 같은 명령이 수햅됩니다. 서비스 내 컨테이너는 1개 이상 존재할 수 있으며, 컨테이너들은 각 워크 노드와 매니저 노드에 할당됩니다. 이러한 컨테이너들을 테스크(Task)라고 합니다.

 

 스웜 스케줄러는 서비스의 정의에 따라 컨테이너를 할당할 적합한 노드를 선정하고, 해당 노드에 컨테이너를 분산해서 할당합니다. 각 노드에 하나씩 할당되지 않을 수도 있고, 이렇게 함께 생성된 컨테이너를 레플리카라고 하며, 서비스에 설정된 레플리카의 수만큼의 컨테이너가 스웜 클러스터 내에 존재해야 합니다.

 

 또한 서비스는 롤링 업데이트 기능도 제공합니다. 서비스 내 컨테이너 이미지를 일괄적으로 업데이트해야 할 때 컨테이너들의 이미지를 순서대로 변경해 서비스 자체가 다운되는 시간 없이 컨테이너의 업데이트를 진행할 수 있습니다.

 

 

서비스 생성 예제

 서비스를 사용하기 위한 명령어는 docker service로 시작합니다. 서비스를 생성하려면 docker service create 사용하며, ubuntu:14.04 이미지로 서비스 내 컨테이너를 생성하며 컨테이너가 시작할 때 실행할 명령어로 'hello world' 출력하는 셀 명령어를 설정하겠습니다.

 

 이는 우분투 컨테이너를 생성해 컨테이너 내부에서 단순히 'hello world'를 출력하도록 설정했으나, 서비스의 레플리카셋을 정의하지 않았으므로 1개의 컨테이너만 생성됐습니다. 이번에는 docker service create 명령어에 --replica 옵션을 추가하고 Nginx 웹 서버 이미지를 이용해 서비스를 외부에 노출해보겠습니다.

 컨테이너가 정상적으로 생성되면 스웜 클러스터 내 노드 중 하나를 선택해 80번 포트로 접근해 Nginx 웹 서버가 구동되고 있는 것을 확인할 수 있습니다. 스웜 클러스터 내의 어떤 노드로 접근해도 위 서비스의 웹 서버에 접근할 수 있습니다.  

 

  잘 들어가지는 모습을 확인할 수 있습니다. (저는 http:localhost로 들어가서 확인했습니다~) 그렇다면 서비스 내의 Nginx 컨테이너를 늘리면? docker service scale 명령어를 이용해 레플리카셋의 수를 늘리거나 줄일 수 있습니다. 컨테이너가 각 컨테이너들이 호스트의 80번 포트에 연결된 것이 아니라 실제로는 각 노드의 80번 포트로 들어온 요청을 위 컨테이너 중 1개로 리다이렉트 하기 때문입니다.

'독서 > 시작하세요! 도커 & 쿠버네티스' 카테고리의 다른 글

6. 도커 데몬  (2) 2023.12.07
5. Dockerfile 명령어  (3) 2023.12.02
4. Dockerfile 빌드  (0) 2023.11.30
3. 도커 이미지  (0) 2023.11.29
2. 도커 볼륨 & 도커 네트워크  (1) 2023.11.28
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.