Docker Services 고가용성 테스트하기

안녕하세요.

DSG 웹서비스부문 개발 2팀 사원 손다연입니다.

[챕터 5]에서 배운 Service의 상태를 잘 전환해보셨나요?

이번 챕터에서는 Docker 서비스 노드의 고가용성 테스트를 해보도록 합시다.


목차는 다음과 같습니다.

1. Woker Node를 신분 상승시키기
2. Leader Node를 Kill하기
3. Manager Node를 Kill하기
4. Manager Node를 3개 만들기
5. Manager Node가 3개인 상태에서 kill 하기
6. Force 옵션을 사용해서 강제로 균형맞추기


1. Woker Node를 신분 상승시키기

챕터 #5까지 저희가 실습한 노드의 상태는 다음과 같습니다.

Node 상태 확인

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Leader              19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active                                  19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active                                  19.03.1

여기서 보면 Leaderaws-node1 하나입니다.
aws-node2를 승진시켜보겠습니다.

worker를 manager로 승진시키기는 법

$ docker node promote [your-worker-node-name]

worker를 manager로 승진시키기는 예시

ubuntu@aws-node1:~$ sudo docker node promote aws-node2

Node aws-node2 promoted to a manager in the swarm.

권한이 부여되었는지 확인해보기

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Leader              19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active              Reachable           19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active                                  19.03.1

aws-node2MANAGER STATUS 항목에 Reachable이라고 추가되었습니다.

Reachable : 도달 할 수 있는, 닿을 수 있는 …

Node 정보 확인해 보는 방법

$ docker node inspect [your-node-name]
$ docker node inspect --pretty [your-node-name] 

정보를 보는 명령은 inspect를 사용하면 됩니다.
하지만, 정보가 너무 많고 원하는 정보를 쉽게 파악하기 어려워 --pretty 옵션을 사용하면 보기 좋게 나옵니다.

Node 정보 확인해보는 예시

  • aws-node1 정보를 확인해보면,
ubuntu@aws-node1:~$ sudo docker node inspect --pretty aws-node1

ID:			6m0jz67jhevvsk9sbqklna83x
Hostname:              	aws-node1
.
.
Manager Status:
 Address:		172.31.11.179:2377
 Raft Status:		Reachable
 Leader:		Yes

aws-node1Leader 항목에 Yes라고 적혀있습니다.

  • aws-node2 정보를 확인해보면,
ubuntu@aws-node1:~$ sudo docker node inspect --pretty aws-node2
ID:			hqkfbmk7byfsboh0w6v0wjspn
Hostname:              	aws-node2
.
.
Manager Status:
 Address:		172.31.11.0:2377
 Raft Status:		Reachable
 Leader:		No

aws-node2Leader 항목에 No라고 적혀있습니다.
worker 였을때는 없던 Manager Status가 생성되었습니다.
Manager 역할에 도달할 수는(Reachable) 있지만, 진정한 리더는 아닌 것을 확인할 수 있습니다.

Docker-Engine 관점에서 docker의 정보 확인

ubuntu@aws-node1:~$ sudo docker info
.
.
 Swarm: active
  NodeID: 6m0jz67jhevvsk9sbqklna83x
  Is Manager: true
  ClusterID: vkn29q8k3wul464w7xtxvdqkq
  Managers: 2
  Nodes: 3
.
.
  Node Address: 172.31.11.179
  Manager Addresses:
   172.31.11.0:2377
   172.31.11.179:2377

위의 정보에서 볼 수 있듯이,
Manager node의 수가 2개이고 Manager Addresses도 2개 인 것을 확인할 수 있습니다.
위에서 확인한 aws-node1aws-node2의 Address와 같은 주소입니다.

worker인 aws-node3에서 docker info를 확인하면, manager가 아니므로 manager의 정보는 포함하지 않지만
manager Address는 포함하고 있습니다.


2. Leader Node를 Kill하기

원래의 docker-machine의 상태를 확인해봅시다.

docker-macine 상태 확인

[ec2-user@ip-172-31-18-132 ~]$ docker-machine ls

NAME        ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER    ERRORS
aws-node1   -        amazonec2   Running   tcp://54.167.81.43:2376           Unknown   Unable to query docker version: Get 
aws-node2   -        amazonec2   Running   tcp://34.203.31.82:2376           Unknown   Unable to query docker version: Get 
aws-node3   -        amazonec2   Running   tcp://52.1.240.126:2376           Unknown   Unable to query docker version: Get 

이 상태에서 Leader인 aws-node1을 kill하도록 하겠습니다.

Node Kill 하는 방법

$ docker-machine kill [your-node-name]

kill 명령을 사용하면, docker-machine의 활동을 잠시 멈출 수 있습니다.

Leader Node Kill 예시

[ec2-user@ip-172-31-18-132 ~]$ docker-machine kill aws-node1

Killing "aws-node1"...
Machine "aws-node1" was killed.

docker-machine 확인하기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine ls

NAME        ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER    ERRORS
aws-node1   -        amazonec2   Stopped                                     Unknown   
aws-node2   -        amazonec2   Running   tcp://34.203.31.82:2376           Unknown   Unable to query docker version: Get 
aws-node3   -        amazonec2   Running   tcp://52.1.240.126:2376           Unknown   Unable to query docker version: Get 

aws-node1이 Stopped 된 것을 알 수 있습니다.

Node 다시 살리기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine start aws-node1

Starting "aws-node1"...
Machine "aws-node1" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Node를 다시 살리고 상태를 확인해보겠습니다.

Node 상태 확인하기

ubuntu@aws-node1:~$ sudo docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Reachable           19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active              Leader              19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active                                  19.03.1

원래 Leader였던 aws-node1가 Kill이 되었었기 때문에,
Reachable 이었던 aws-node2Leader가 되었습니다.

하지만, aws-node1은 Manager 권한은 유지하고 있어 ‘Reachable’ 상태가 되었습니다.

Service Task 확인

ubuntu@aws-node1:~$ sudo docker service ps ping
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR       
pyugvp3azqyf        ping.1              alpine:latest       aws-node2           Running             Running 37 minutes ago 
m83j8fkp5ykv        ping.2              alpine:latest       aws-node3           Running             Running 37 minutes ago 
y2jp5lr8d0i7        ping.3              alpine:latest       aws-node1           Running             Running 4 minutes ago  
uqf4pqrsn2ux         \_ ping.3          alpine:latest       aws-node1           Shutdown            Failed 4 minutes ago  "No such container: ping.3.uqf…"
r1gbmn89ydhm        ping.4              alpine:latest       aws-node2           Running             Running 37 minutes ago               

aws-node1이 실행하던 ping.3shuntdown이 되었으나,
aws-node1이 복구된 후에 다시 Running 되었습니다.

챕터 #5와는 다르게,
다른 node가 일을 받아서 하지 않고 aws-node1이 복구된 후 다시 일을 받아서 하게 됩니다.


3. Manager Node를 Kill하기

Leader는 아니지만 Manager의 역할을 하는 aws-node1을 다시 kill 해보겠습니다.

Manager aws-node1 죽이기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine kill aws-node1

Killing "aws-node1"...
Machine "aws-node1" was killed.

Docker-machine 상태 확인하기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine ls

NAME        ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER    ERRORS
aws-node1   -        amazonec2   Stopped                                     Unknown   
aws-node2   -        amazonec2   Running   tcp://34.203.31.82:2376           Unknown   Unable to query docker version: Get https://34.203.31.82:2376/v1.15/version: x509: certificate is valid for 54.242.54.187, not 34.203.31.82
aws-node3   -        amazonec2   Running   tcp://52.1.240.126:2376           Unknown   Unable to query docker version: Get https://52.1.240.126:2376/v1.15/version: x509: certificate is valid for 54.174.125.199, not 52.1.240.126

aws-node1이 Stopped 된 상태인 것을 알 수 있습니다.

Manager node 살리기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine start aws-node1

Starting "aws-node1"...
Machine "aws-node1" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Node 상태 확인하기

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Reachable           19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active              Leader              19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active                                  19.03.1

aws-node1은 Leader가 아닌 단순한 Manager의 역할이었습니다.
그래서 복구하여도 Leader의 권한을 받을 수 없지만, Manager의 역할은 그대로 부여받게 됩니다.

Service Task 확인

ubuntu@aws-node1:~$ sudo docker service ps ping
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR       
pyugvp3azqyf        ping.1              alpine:latest       aws-node2           Running             Running 54 minutes ago   
m83j8fkp5ykv        ping.2              alpine:latest       aws-node3           Running             Running 54 minutes ago   
33p1xota7q5p        ping.3              alpine:latest       aws-node1           Running             Running 3 minutes ago    
y2jp5lr8d0i7         \_ ping.3          alpine:latest       aws-node1           Shutdown            Failed 3 minutes ago     "No such container: ping.3.y2j…"   
uqf4pqrsn2ux         \_ ping.3          alpine:latest       aws-node1           Shutdown            Failed 21 minutes ago    "No such container: ping.3.uqf…"   
r1gbmn89ydhm        ping.4              alpine:latest       aws-node2           Running             Running 54 minutes ago              

장애를 복구한 후에, aws-node1의 ping.3이 다시 Running 되었다는 것을 알 수 있습니다.

그런데, aws-node1이 복구될때까지
ping.3은 다른 node가 작업하지않고 가만히 aws-node1을 기다리는 거라면 이것은 좋은 해결 방법은 아닙니다.


4. Manager Node를 3개 만들기

Swarm의 가용성 환경의 지침에 따르면, Manager가 3개 이상인 경우 고가용성 환경에 적합하다고 합니다.
그럼 aws-node3도 Manager로 만들어보겠습니다.

aws-node3에 manager 권한 부여하기

참고 : 1. Woker Node 신분 상승시키기

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Reachable           19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active              Leader              19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active              Reachable           19.03.1

다음과 같이, 모든 node가 manager로 신분이 상승했습니다.

service 복제본 3개 만들기

참고 : 서비스 생성하기

ubuntu@aws-node1:~$ sudo docker service create --name ping --replicas 3 alpine ping docker.com
x6b4c8otschmfhjtd0f0gxomu
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

서비스 복제본 3개가 잘 만들어졌는지 확인해보겠습니다.

service 생성 확인하기

ubuntu@aws-node1:~$ sudo docker service ps ping
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR       
suddl3r28391        ping.1              alpine:latest       aws-node2           Running             Running 2 minutes ago               
3yg2hsr5fogx        ping.2              alpine:latest       aws-node3           Running             Running 2 minutes ago               
tw78ddexdprw        ping.3              alpine:latest       aws-node1           Running             Running 2 minutes ago     

5. Manager Node가 3개인 상태에서 kill 하기

현재 Leader인 aws-node2를 kill 해보겠습니다.

[ec2-user@ip-172-31-18-132 ~]$ docker-machine kill aws-node2

Killing "aws-node2"...
Machine "aws-node2" was killed.

Node 확인하기

Leader를 죽인 후, node를 확인해보겠습니다.

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Reachable           19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Down                Active              Unreachable         19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active              Leader              19.03.1

Leader가 Down 되어서 aws-node3이 Leader의 권한을 부여받았습니다.
현재 죽은 상태인 aws-node2는 Unreachable 상태가 되었습니다.

Task 상태 확인하기

ubuntu@aws-node1:~$ sudo docker service ps ping
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR       
i4kgvr3x2q6z        ping.1              alpine:latest       aws-node1           Running             Running 3 minutes ago               
suddl3r28391         \_ ping.1          alpine:latest       aws-node2           Shutdown            Running 8 minutes ago               
3yg2hsr5fogx        ping.2              alpine:latest       aws-node3           Running             Running 8 minutes ago               
tw78ddexdprw        ping.3              alpine:latest       aws-node1           Running             Running 8 minutes ago            

위에서 했던 실습과는 조금 다릅니다.
aws-node2가 shutdown 되었는데 task가 node를 기다리지 않고
다른 노드인 aws-node1ping.1의 업무를 하고 있습니다.
그런데, 조금 이상한 부분은 아직 CURRENT STATERunning 이라는 입니다.


죽은 Node 살리기

[ec2-user@ip-172-31-18-132 ~]$ docker-machine start aws-node2
Starting "aws-node2"...
Machine "aws-node2" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Node 상태 확인하기

ubuntu@aws-node1:~$ sudo docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6m0jz67jhevvsk9sbqklna83x *   aws-node1           Ready               Active              Reachable           19.03.1
hqkfbmk7byfsboh0w6v0wjspn     aws-node2           Ready               Active              Reachable           19.03.1
sexjhrlvhuyxjgu6w5tuwfimk     aws-node3           Ready               Active              Leader              19.03.1

Task 상태 확인하기

ubuntu@aws-node1:~$ sudo docker service ps ping

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                 ERROR 
i4kgvr3x2q6z        ping.1              alpine:latest       aws-node1           Running             Running 9 minutes ago               
suddl3r28391         \_ ping.1          alpine:latest       aws-node2           Shutdown            Shutdown about a minute ago         
3yg2hsr5fogx        ping.2              alpine:latest       aws-node3           Running             Running 15 minutes ago              
tw78ddexdprw        ping.3              alpine:latest       aws-node1           Running             Running 15 minutes ago    

앞에서 확인한 Task와 똑같지만, CURRENT STATE가 변하였습니다.
Running에서 Shutdown으로 변하였습니다.


6. Force 옵션을 사용해서 강제로 균형맞추기

새로운 서비스를 생성하여보겠습니다.

참고 : 서비스 생성하기

새로운 서비스 생성하기

새로운 서비스를 생성하면, 가용하였던 모든 Node를 이용하여 작업을 할당하게 됩니다.
그래서 새로운 서비스를 하나 생성해보도록 하겠습니다.

ubuntu@aws-node1:~$ sudo docker service create -q --name ping2 --replicas 3 alpine ping docker.com

s7e63lf0uc7q7gi38v31pkctz

서비스 상태 확인하기

ubuntu@aws-node1:~$ sudo docker service ps ping2
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR   
sln6hwwf9sde        ping2.1             alpine:latest       aws-node2           Running             Running about a minute ago    
wm9lwrnhby5w        ping2.2             alpine:latest       aws-node3           Running             Running about a minute ago    
9ugwmrdnok92        ping2.3             alpine:latest       aws-node1           Running             Running about a minute ago    

node에 골고루 작업 분배가 된 것을 볼 수 있습니다.

강제로 서비스를 update 시키는 방법

$ sudo docker service update --force [service-name]

update 명령을 사용하며 --force 옵션을 사용하면,
변경이 필요하지 않은 경우에도 업데이트를 강제로 적용하게 됩니다.

강제로 서비스를 update 시키기 예시

ubuntu@aws-node1:~$ sudo docker service update --force ping

ping
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

--force 옵션을 사용하여 강제로 ping 서비스를 update 시켜서 정리합니다.

서비스 부하 균형 확인하기

ubuntu@aws-node1:~$ sudo docker service ps ping
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                 ERROR 
1h2axxsydikh        ping.1              alpine:latest       aws-node3           Running             Running 50 seconds ago               
i4kgvr3x2q6z         \_ ping.1          alpine:latest       aws-node1           Shutdown            Shutdown 51 seconds ago             
suddl3r28391         \_ ping.1          alpine:latest       aws-node2           Shutdown            Shutdown 9 minutes ago              
fikg0u1vpfhu        ping.2              alpine:latest       aws-node2           Running             Running about a minute ago          
3yg2hsr5fogx         \_ ping.2          alpine:latest       aws-node3           Shutdown            Shutdown about a minute ago        
h1biwmz81icn        ping.3              alpine:latest       aws-node1           Running             Running 38 seconds ago             
tw78ddexdprw         \_ ping.3          alpine:latest       aws-node1           Shutdown            Shutdown 39 seconds ago           

aws-node1은 ping.3 , aws-node2는 ping.2, aws-node3은 ping.1의 task를 맡게 되면서,
모두 골고루 일을 분배받아서 부하 균형이 맞춰지게 되었습니다.


지금까지 Docker-Swarm의 기본 개념에 대한 학습을 완료하였습니다.

학습을 진행하다 추가할 사항이나, 어려운 점이 있다면 댓글을 남겨주세요.
감사합니다!

배운 내용 복습 하기
1. Woker Node를 신분 상승시키기
2. Leader Node를 Kill하기
3. Manager Node를 Kill하기
4. Manager Node를 3개 만들기
5. Manager Node가 3개인 상태에서 kill 하기
6. Force 옵션을 사용해서 강제로 균형맞추기

이전 단계로 돌아가기 : 서비스 상태 전환하기
튜토리얼 첫 번째로 돌아가기 : Docker 만들기