Docker Swarm

 

지난 Docker : 컨테이너 오케스트레이션 개요 편에서는 한 서비스가 점차 확장되면서 컨테이너 증가에 따른 관리의 필요성과 다수의 컨테이너를 효과적으로 다룰 수 있는 컨테이너 오케스트레이션 툴에 대한 개요를 설명 하였다. 이번 편에서는 도커스웜의 노드 클러스터링 구축과 스웜 로드밸런서의 기능을 확인해보는 실습을 진행하도록 하겠다.

 

 

도커스웜의 노드 클러스터링

 

노드 클러스터링(Node Clustering)의 노드(Node)는 도커스웜에서 물리적 또는 논리적으로 분리 된 독립적인 서버(Server)를 의미하고 클러스터링(Clustering)은 사전적 의미로 뭉치기라는 뜻을 가지고 있다. 즉 노드 클러스터링은 서버의 군집화라고 표현 할 수 있다. 필자는 3개의 노드를 클러스터링 하기 위해 VirtualBox의 Clone기능을 활용하여 아래와 같이 총 3대의 노드를 생성하였다.

 

스웜 클러스터를 구성하기 위해서는 클러스터의 중심이 되는 노드가 필요한데 필자는 manager01을 매니저 노드로 설정 하였고 나머지 노드를 worker노드로 구분하였다. (색상표기가 된 manager와 worker는 각 노드의 hostname이다)

 

자 이제 클러스터를 생성해보자.

는 잠깐!!

 

포.. 포트포워딩이 아직 안 됐....

클러스터를 생성하기 전 도커스웜에서 사용하는 포트와 서비스로 사용할 포트를 모두 열어주어야 한다. VirturalBox의 포트포워딩 설정과 각 노드의 포트별로 방화벽 해제 처리를 해주자

 

VirtualBox 포트포워딩 설정

// 방화벽 해제
$ sudo firewall-cmd --permanent --add-port=2377/tcp
$ sudo firewall-cmd --permanent --add-port=7946/tcp
$ sudo firewall-cmd --permanent --add-port=7946/udp
$ sudo firewall-cmd --permanent --add-port=4789/udp
$ sudo firewall-cmd --permanent --add-port=80/tcp
$ sudo firewall-cmd --reload

 

포트포워딩이 됐...!!

 

포트포워딩 설정과 방화벽 해제가 완료 되었다면 manager01 노드에서 docker swarm init 명령으로 스웜 클러스터를 생성 해보자. init 뒤에 있는 --advertise-addr 옵션에는 해당 주소로 swarm join 할 수 있도록 IP와 포트를 지정 할 수 있다. 현재 VirtualBox에서 생성한 CentOS 7 환경에서는 Guest의 IP가 10.0.2.15로 잡혀 있으므로 VirtualBox에서 생성된 노드들 끼리 접근이 가능하려면 Host IP인 192.168.37.1로 설정 해야 한다.

# docker swarm init --advertise-addr 192.168.37.1
Swarm initialized: current node (0ba2xn5fqkv1047rc5xa77nl0) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-2aai8y68yz8ju664rktqbxlw88if54rqzx9cv49or7ywnzzpz5-b40gsplzlg9ip0o6s4ofdke29 \
    192.168.37.1:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

스웜 클러스터가 생성되면 친절하게도 위와 같이 docker swarm join 명령어 샘플이 자동으로 생성된다. 바로 아랫줄에 있는 토큰은 manager 노드로 접근하기 위한 일종의 비밀 키 이므로 실무에서 사용하는경우 외부에 노출되지 않도록 주의하길 바란다.

 

이제 각각의 worker 노드에서 join 명령어를 통해 스웜 클러스터에 합류 해보자

# docker swarm join \
> --token SWMTKN-1-2aai8y68yz8ju664rktqbxlw88if54rqzx9cv49or7ywnzzpz5-b40gsplzlg9ip0o6s4ofdke29 \
> 192.168.37.1:2377
This node joined a swarm as a worker.

swarm join이 완료되면 'This node joined a swarm as a worker.' 문구와 함께 참여완료 문구가 뜬다. 이제 다시 manager노드로 이동하여 각 worker노드들이 잘 합류했는지 확인해보자.

 

# docker node ls
ID                           HOSTNAME   STATUS  AVAILABILITY  MANAGER STATUS
0ba2xn5fqkv1047rc5xa77nl0 *  manager01  Ready   Active        Leader
jw2kxdt3v7tiqq9etiaxqw1lt    worker01   Ready   Active
x3kxchadl950q934kuctymzmm    worker02   Ready   Active

3개의 노드를 하나로 묶은 클러스터링이 구축 되었다. 현재 상태를 이미지로 표현하면 아래와 같다.

 

이제 스웜 클러스터도 생성 되었고 스웜 로드벨런싱 기능을 확인하기 위해 간단한 실습을 진행 해보도록 하겠다. 먼저 manager 노드에 docker service로 nginx를 설치 해보자.

# docker service create \
--name my-web \
--publish published=80,target=80 \
--replicas 1 \
nginx

# docker service ls
ID            NAME    MODE        REPLICAS  IMAGE
x4njngtukyfk  my-web  replicated  1/1       nginx:latest

# docker service ps my-web
ID            NAME      IMAGE         NODE      DESIRED STATE  CURRENT STATE        ERROR  PORTS
m05xzf46mz8t  my-web.1  nginx:latest  worker01  Running        Running 2 hours ago
  • docker service create 옵션설명
    • --name: 생성할 service의 이름을 지정한다.
    • --replicas: 생성할 컨테이너 갯수
    • --publish: 서비스에서 사용되는 포트를 오픈한다.
      1. published: 도커 컨테이너로 전달할 외부 포트
      2. target: 도커 컨테이너 내부 포트

 

서비스 생성 후 192.168.37.1, 2, 3번 각각 접근 해보자

현재 192.168.37.1 manager 노드 하나에만 nginx 컨테이너가 활성화 되어있는데 어떻게 다른 노드로 접근해도 같은 페이지가 뜨는 것일까? 스웜 클러스터가 구축 되면 ingress network가 생성되는데 이것은 어떤 노드에 접근하더라도 서비스중인 컨테이너에 접근 가능하도록 Routing mesh를 구성하고 있고 스웜 로드밸런서에 서비스가 활성화 되어있는 노드에 라운드 로빈(Round Robin)방식으로 로드 밸런싱 된다.

 

  • Routing mesh: 서비스에서 포트가 오픈되면 모든 노드에도 동일한 포트가 오픈되며 어떤 노드에 요청을 보내더라도 현재 서비스가 실행중인 노드의 컨테이너로 요청을 전달한다.
  • 라운드 로빈(Round Robin): 스케쥴링의 한 방식으로 리스트의 맨 위에서 아래로 가며 하나 씩 순차적으로 진행 하고 끝나면 다시 맨 위로 돌아가는 식으로 진행된다.

 

 

Round Robin 방식의 적절한 예

 

이 ingress network와 스웜 로드벨런서 덕분에 어떤 노드를 호출해도 같은 페이지를 보는것이 가능하다.

만약 현재의 상태로 manager 노드의 컨테이너가 죽는다면 어떤 노드로 접근한다 해도 페이지는 먹통일 것이다. 노드 클러스터링의 목적은 과도한 트래픽이 몰릴 경우를 대비한 트래픽 분산도 있지만 하나의 컨테이너가 죽더라도 다른 컨테이너로 대체 할 수 있도록 위험분산의 목적도 가지고 있다. 이번에는 전체 node에 골고루 분포 되도록 Replica의 갯수를 6개로 늘려보도록 하자.

# docker service scale my-web=6
my-web scaled to 6
# docker service ps my-web
ID            NAME          IMAGE         NODE       DESIRED STATE  CURRENT STATE               ERROR  PORTS
0mouqz0t89nz  my-web.1      nginx:latest  worker01   Running        Running about a minute ago
xx2lsv3uwcrp  my-web.2      nginx:latest  worker02   Running        Running 51 seconds ago
h6kjhoyvfpyl  my-web.3      nginx:latest  worker01   Running        Running 52 seconds ago
nszaz7kkg8wc  my-web.4      nginx:latest  manager01  Running        Running 51 seconds ago
wdgjoyib63ue  my-web.5      nginx:latest  manager01  Running        Running 51 seconds ago
zwqsm1yus5os  my-web.6      nginx:latest  worker02   Running        Running 51 seconds ago

 

NODE항목의 각 노드 갯수를 보면 manager와 worker들의 노드 갯수가 2개씩 배정이 되어 있는것을 확인 할 수 있고 세개의 노드 중 두개가 죽더라도 서비스에는 지장이 없게 되었다.

 

여기까지 도커스웜 클러스터 구축과 manager노드 및 worker노드의 생성, ingress network의 개요와 스웜 로드밸런서를 통한 로드밸런싱 기능을 확인 해보았다.

 

 

Docker : 도커스웜 클러스터 구축 편

끝.

 

'Docker' 카테고리의 다른 글

Docker : 도커스웜 클러스터 구축 편  (0) 2019.05.17
Docker : 컨테이너 오케스트레이션 개요 편  (0) 2019.04.19
Docker : Dockerfile 실습 편  (0) 2019.03.22
Docker : Dockerfile 편  (0) 2019.03.07
Docker : 이미지 편  (0) 2019.02.22
Docker : 컨테이너 편  (1) 2019.02.15
Posted by DevStream

댓글을 달아 주세요