저희 팀에서 Docker Swarm을 처음 도입한 계기는 사실 배포 자동화 프로세스 구축하고 싶었기 때문이었습니다.
처음엔 서버가 하나 뿐이여서 컨테이너 오케스트레이션의 묘미를 느끼지 못했는데 관리자, 푸시, 이벤트, 테스트 등등 여러 서버가 붙으면서 여러개의 서버를 관리해야 했는데
미리 구축해놓은 Docker Swarm이 많은 편의 기능을 제공하고 있어서 여러개의 서버를 관리하는 것도 개발자가 부담없이 할 수 있게 되었습니다.
이 슬라이드는 제가 서버를 구축하는 과정에서 겪었던 어려움들을 여러분은 겪지 않길 바라며 제작하게 되었습니다.
만약 이 슬라이드를 보시는 분이 Docker및 Docker Swarm을 처음 접해보시는 거라면 이 자료가 좋은 가이드가 될 수 있을 것 같습니다.
감사합니다.
이도현 드림
2. 안녕하세요. 저는 현재 산업기능요원으로 일하고 있는
소프트웨어 엔지니어입니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
3. 지난 3달간 신규 프로젝트를 진행하면서 저는
클라우드 인프라 구축 및 서버 개발자 역할을 맡았습니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
4. 서버 개발 자체는 경험도 있고 익숙해서 큰 어려움은 없었는데
클라우드 인프라 구축을 직접해 본 건 처음해보는 일이라 초기에 많은 어려움을 겪었습니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
5. 첫째로 공유된 자료가 많이 없어서 직접 부딪쳐가면서 몸으로 배워야 했고,
제가 선택한 방법이 과연 최선인지, 더 나은 방법은 없는지 끝없이 고민할 수 밖에 없었습니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
6. 잘못된 방법으로 구축해버리는 바람에 데이터가 유실되거나
제가 잠든사이 서버가 죽었는데 자동으로 서비스가 복구되지 않는다면 사용자들에게 부정적인 영향을 미치니까요
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
7. 제가 진행한 프로젝트가 금융 서비스라고 부르기는 어렵지만 나름대로 사용자의 자산을 다루는
서비스인 만큼 서버 가용성은 꼭 확보해야 하는 과제였습니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
8. 만약 자신이 DevOps 개발자로 일해야 하는 상황이 왔는데
어디서부터 시작해야하 하는지 모르는 사람들을 위해 이 자료를 준비했습니다.
Docker및 Swarm Mode를
활용한 분산 서버 관리 A부터 Z까지 PART 1.
9. Docker 기본
Docker Swarm 으로 오케스트레이션 하기
아마존 클라우드에서 사용하기
CI/CD로 배포 자동화하기
제가 이야기할 주제는 크게 네가지입니다.
10. Docker 기본
Docker Swarm 으로 오케스트레이션 하기
아마존 클라우드에서 사용하기
CI/CD로 배포 자동화하기
이 번 1부에서는 Docker와 Docker Swarm에 대해 이야기하고
클라우드 플랫폼과 CI와 연동하는 부분은 따로 떼어 2부에서 추가적으로 다룰 예정입니다.
1부
2부
11. Docker 기본
Docker Swarm 으로 오케스트레이션 하기
아마존 클라우드에서 사용하기
CI/CD로 배포 자동화하기
1부 에서도 Docker Swarm의 심화 기능들을 분리하기 위해서
PART 1과 PART 2로 분리하였습니다.
PART 1, PART 2
12. Docker 기본
Docker Swarm 으로 오케스트레이션 하기
아마존 클라우드에서 사용하기
CI/CD로 배포 자동화하기
기본적인 내용을 다루는 PART 1의 내용은 이번 1부에서 다룰 것이고
조금 더 어려운 이야기를 하는 PART 2는 별도로 부록 형식으로 새로 슬라이드를 만들 예정입니다.
PART 1, PART 2
13. 약간 원론적인 얘기이지만 도커에 대해 이야기하기 앞서
가상OS의 개념과 도커 이전의 가상화와 도커가 어떻게 다른지 설명드리겠습니다.
14. 도커가 처음 발표된 건 2013년 이지만 본격적으로 상용화 단계를 거치고
개발자 커뮤니티에서 화제가 된건 불과 2-3년 전입니다.
15. 제가 처음 개발자로 일했던 2012년에는
사내에 준비되어있는 서버 컴퓨터에 접속해서 서버를 구동하는 환경이었습니다.
16. 왼쪽 그림처럼 하나의 서버에 웹서버를 설치해서 실행하곤 했는데요.
이런 방식에는 몇가지 불편한 점이 있습니다.
17. 일단 서버 OS마다 웹서버 설치 및 실행 방법이 다 다릅니다.
apk, yum, rpm 등 리눅스 OS마다 여러 설치 방법이 있죠 설정법도 제각각입니다.
18. 그리고 OS에 이미 다른 서버가 실행중이라면
여타 패키지 충돌, 포트, 설정등을 신경써야 합니다.
19. 가상 OS를 사용하면 완벽히 격리된 공간에서 작업을 할 수 있습니다.
이 때문에 호스트가 어떤 환경에 있던간에 실행을 보장합니다.
23. Hypervisor는 물리적 컴퓨터 위에 Guest OS를 설치해서 앱을 실행합니다.
Guest OS는 하나의 OS를 구성하는 커널 및 시스템 라이브러리 등을 가지고 있습니다.
24. 반면 컨테이너 기반인 도커는 OS수준에서 가상화를 지원합니다.
도커 위에서 동작하는 컨테이너는 따로 커널을 설치하는게 아니라 호스트의 커널을 공유합니다.
25. 그 위에서 필요한 시스템 라이브러리만 설치하면 되기 때문에
Hypervisor와 비교했을 때 이미지 빌드 및 실행이 빠릅니다.
26. 빠르다
빌드도 빠르고(?) 실행도 빠르다
편하다
설치가 간편하고 여러개의 서버를 한번에 실행하는 것도 편하게 할 수 있다
안전하다
격리된 환경에서 설정을 잡을 수 있기 때문에 기존 자원과의 충돌이 없다
e. x.
이미 아파치 서버가 돌고있는 서버 컴퓨터에 아파치 환경에 새로운 웹환경을 만드는 건 꽤 어렵다
유연하다.
서버를 탄력적으로 설계 및 운영할 수 있다.
도커로 서버를 구성하면 얻을 수 있는 장점은
위와 같이 정리할 수 있습니다.
27. 개인적으로는 서버의 구성을 유연하게 가질 수 있다는게 꽤 매력적으로 느꼈는데요.
빠르다
빌드도 빠르고(?) 실행도 빠르다
편하다
설치가 간편하고 여러개의 서버를 한번에 실행하는 것도 편하게 할 수 있다
안전하다
격리된 환경에서 설정을 잡을 수 있기 때문에 기존 자원과의 충돌이 없다
e. x.
이미 아파치 서버가 돌고있는 서버 컴퓨터에 아파치 환경에 새로운 웹환경을 만드는 건 꽤 어렵다
유연하다.
서버를 탄력적으로 설계 및 운영할 수 있다.
28. Micro Service vs Monolitic
서버의 구성을 이분법적으로 나누면 모놀리틱과 마이크로 서비스로 분류할 수 있습니다.
35. Micro Service vs Monolitic
Docker love this!
도커를 사용하면 서버의 확장 및 설치가 간편해졌기 때문에
여러대의 서버를 관리하는것에 대한 부담이 훨씬 덜 해졌습니다.
36. Micro Service vs Monolitic
Docker love this!
이번 프로젝트에서도 메인 API, 관리자, 인증 서버, 푸시 서버, 이벤트 서버 등등
여러대의 마이크로 서비스들을 관리하고 있습니다.
37. 이제 본격적으로 도커의 설치및 기본 사용법에 대해 다루겠습니다.
이 슬라이드를 보고 도커를 처음 접하신 분들을 위해 준비했습니다.
38. 추후에 이어질 Docker Swarm에 대한 이해를 돕기위한 용어 설명 및
간단한 명령어만을 보여주기 때문에 좀 더 자세한 내용은 관련 홈페이지 및 다른 강의를 참고해주세요.
39. 도커 공식 홈페이지에는 각 OS별 설치법이 나열되어있습니다.
저는 맥북에서 작업을 하기 때문에 홈페이지에서 제공하는 설치파일을 통해 도커를 설치했습니다.
https://docs.docker.com/docker-for-mac/install/#what-to-know-before-you-install
40. 이미지 / 컨테이너
도커의 명령어를 배우려면 먼저 이미지와 컨테이너를 분리해서 바라볼 수 있어야 합니다.
41. 이미지 = 클래스
컨테이너 = 객체
객체지향개발에서 쓰이는 말에 비유하면
이미지는 클래스로 컨테이너는 객체로 비유할 수 있습니다.
42. 이미지 = 클래스
컨테이너 = 객체
서버의 구성 및 실행환경을 정의하는 이미지를 가지고
실제로 돌아가는 컨테이너를 여러개 만들 수 있습니다.
50. T
이미지 생성하기
$ cd ~/Projects/helloworld
$ docker build -t helloworld .
$ docker images
Terminal
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest 9cb9a8177c14 3 seconds ago 946MB
도커 이미지는 docker build 명령어를 통해 간단히 만들 수 있습니다.
빌드가 끝나고 난 뒤 docker images명령어를 실행하면 위와같이 설치된 이미지 목록이 나옵니다.
51. T
이미지 생성하기
$ cd ~/Projects/helloworld
$ docker build -t helloworld .
$ docker images
Terminal
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest 9cb9a8177c14 3 seconds ago 946MB
출력 결과로 helloworld라는 이미지가 생성되었음을 알 수 있습니다.
52. T
컨테이너 실행하기
$ docker run -d —p 3000:80 helloworld
Terminal
이제 docker run 명령어로 특정 이미지를 실행할 수 있습니다.
53. T
컨테이너 실행하기
$ docker run -d —p 3000:80 helloworld
Terminal
-d 옵션은 이 컨테이너를 백그라운드로 실행하겠다는 것을 의미합니다.
-d
54. T
컨테이너 실행하기
$ docker run -d —p 3000:80 helloworld
Terminal
-p 옵션으로 호스트의 포트와 도커 컨테이너 내부의 포트를 바인딩 할 수 있습니다.
도커 컨테이너 내부에서는 Nginx서버가 80으로 실행하고 있는데
-p
55. T
컨테이너 실행하기
$ docker run -d —p 3000:80 helloworld
Terminal
호스트에서는 포트 3000번으로 붙겠다는 의미입니다.
-p
56. T
컨테이너 실행하기
$ docker run -d —p 3000:80 helloworld
Terminal
마지막에는 실행시킬 이미지명을 명시합니다.
helloworld
57. T
실행중인 컨테이너 확인
$ docker ps
Terminal
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
36dac4a33de3 helloworld “/entrypoint.sh /sta…” 2 seconds ago
Up 1 second 443/tcp, 0.0.0.0:3000->80/tcp infallible_yonath
리눅스에서 ps명령어로 프로세스를 확인하듯
docker ps 명령어를 통해 실행중인 컨테이너들을 확인할 수 있습니다.
58. T
실행중인 컨테이너 확인
$ curl 127.0.0.1:3000
Terminal
Hello, World!
이제 해당 url로 접속하면 컨테이너가 실행되고 있음을 눈으로 확인할 수 있습니다.
70. Docker에 기본적으로 내장되어있기 때문에
별도의 설치과정이 필요하지 않다.
Docker 1.12.0 이후 버전부터는 Swarm이 내장되어 있어서
별도의 설치과정이 필요하지 않아 바로 사용할 수 있습니다.
71. Docker에 기본적으로 내장되어있기 때문에
별도의 설치과정이 필요하지 않다.
보통 이런 멀티-호스트에서 컨테이너 배포 관리 하는 행위를 오케스트레이션이라고 부릅니다.
72. 도커 스웜 말고도 수많은 오케스트레이션 툴들이 존재합니다.
대표적으로 구글에서 개발한 Kubernetes가 있습니다.
73. 수백대의 서버를 운영하는게 아니라면 어려운 사용법을 공부하느라 피해입을 멘탈 손해가 도입의 이득보다
크기 때문에 처음엔 도커 스웜을 사용하는 것을 추천드립니다.
74. 컨테이너의 배포 및 프로비저닝 자동화
컨테이너가 중지된 상황일 경우 재스케줄링
클러스터 내의 컨테이너의 로드 밸런싱
서비스 외부에 노출시키기
컨테이너와 호스트의 상태 모니터링
…
오케스트레이션 툴들이 자동으로 해주는 일을 위와 같이 나열할 수 있습니다.
앞으로 위와 같은 일들을 하는 걸 ‘오케스트레이션 한다’ 라고 부르겠습니다.
75. 특정 컨테이너를 실행중인 호스트 발견
클러스터 내 네트워크 분리
컨테이너 스케일 아웃-인
롤링 업데이트
…
그 외에도 서버 개발자가 직접 위와 같은 일들을 할 수 있습니다.
78. Manager 노드, Worker 노드
Manager
Worker
Manager
Worker
Worker
도커 스웜 내에서 존재하는 호스트는
매니저 노드, 워커 노드 둘 중 하나가 됩니다.
79. Manager 노드, Worker 노드
Manager
Worker
Manager
Worker
Worker
매니저 노드는 클러스터관리 및 컨테이너 오케스트레이의 의사결정을 하고
워커 노드는 매니저의 지시에 따라 컨테이너를 열심히 실행하는 노예 역할을 합니다.
80. Manager 노드, Worker 노드
Manager
Worker
Manager (Leader)
Worker
Worker
매니저 노드 중에서도 리더로 선출된 인싸가 주요 관리 업무를 맡고
나머지 매니저 노드는 리더가 가지고 있는 오케스트레이션 업무일지를 동일하게 유지합니다.
81. Manager 노드, Worker 노드
Worker
Worker
Worker
만약, 리더로 선출된 노드에 장애가 발생하면
다른 매니저 노드가 리더로 선출되서 기존 업무를 이어갑니다.
Manager (Leader)
82. 실제로 매니저 노드와 워커 노드를 생성해 봅시다.
T
$ docker-machine create —-driver virtualbox manager1
Terminal (Mac)
T
$ docker-machine create —-driver hyperv manager1
Terminal (Windows)
Manager 노드, Worker 노드
83. docker-machine 명령어는 로컬에 도커 호스트를 설치하고 실행하는 명령어입니다.
도커에서 컨테이너를 관리하는 daemon 프로세스를 실행하는 가상머신을 실행합니다.
Manager 노드, Worker 노드
T
$ docker-machine create —-driver virtualbox manager1
Terminal (Mac)
T
$ docker-machine create —-driver hyperv manager1
Terminal (Windows)
84. 설치하는 환경이 Mac이면 위의 명령어를,
Window라면 아래 명령어를 실행하면 됩니다.
Manager 노드, Worker 노드
T
$ docker-machine create —-driver virtualbox manager1
Terminal (Mac)
T
$ docker-machine create —-driver hyperv manager1
Terminal (Windows)
85. 같은 방법으로 manager2, manager3, worker1, worker2, worker3
총 6개의 가상 호스트를 설치했습니다.
T
$ docker-machine create —-driver virtualbox manager2
$ docker-machine create —-driver virtualbox manager3
$ docker-machine create —-driver virtualbox worker1
$ docker-machine create —-driver virtualbox worker2
$ docker-machine create —-driver virtualbox worker3
Terminal
Manager 노드, Worker 노드
86. Manager 노드, Worker 노드
설치가 끝났으면 docker-machine ls 명령어로 실행중인
호스트의 이름과 IP를 확인할 수 있습니다.
T
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL
manager1 - virtualbox Running tcp://192.168.99.100:2376
manager2 - virtualbox Running tcp://192.168.99.101:2376
manager3 - virtualbox Running tcp://192.168.99.102:2376
worker1 - virtualbox Running tcp://192.168.99.103:2376
worker2 - virtualbox Running tcp://192.168.99.104:2376
worker3 - virtualbox Running tcp://192.168.99.105:2376
Terminal
87. Manager 노드, Worker 노드
ssh명령어로 매니저 노드에 접속해서
Swarm 클러스터를 만들어 줍니다.
T
$ docker-machine ip manager1
192.168.99.100
$ docker-machine ssh manager1
docker@manager1:~$ docker swarm init
—-advertise-addr 192.168.99.100
To add a worker to this swarm, run the following command:
docker swarm join —-token SWMTKN……dg06n 192.168.99.100:2377
To add a manager to this swarm,
run ‘docker swarm join-token manager’
and follow the instructions.
Terminal
88. Manager 노드, Worker 노드
최초로 docker swarm init 을 실행한 노드가 자동으로 매니저 노드가 됩니다.
T
$ docker-machine ip manager1
192.168.99.100
$ docker-machine ssh manager1
docker@manager1:~$ docker swarm init
—-advertise-addr 192.168.99.100
To add a worker to this swarm, run the following command:
docker swarm join —-token SWMTKN……dg06n 192.168.99.100:2377
To add a manager to this swarm,
run ‘docker swarm join-token manager’
and follow the instructions.
Terminal
89. $ docker-machine ip manager1
192.168.99.100
$ docker-machine ssh manager1
docker@manager1:~$ docker swarm init
—-advertise-addr 192.168.99.100
To add a worker to this swarm, run the following command:
docker swarm join —-token SWMTKN……dg06n 192.168.99.100:2377
To add a manager to this swarm,
run ‘docker swarm join-token manager’
and follow the instructions.
Manager 노드, Worker 노드
출력 결과가 알려주는 명령어를 다른 호스트에서 사용하면
생성된 스웜 클러스터에 워커 노드!로 참여할 수 있습니다.
T
Terminal
docker swarm join —-token SWMTKN……dg06n 192.168.99.100:2377
90. $ docker-machine ip manager1
192.168.99.100
$ docker-machine ssh manager1
docker@manager1:~$ docker swarm init
—-advertise-addr 192.168.99.100
To add a worker to this swarm, run the following command:
docker swarm join —-token SWMTKN……dg06n 192.168.99.100:2377
To add a manager to this swarm,
run ‘docker swarm join-token manager’
and follow the instructions.
Manager 노드, Worker 노드
매니저 노드!로 참여하려면 하이라이트된 명령어를 실행하고
나오는 결과를 참고해서 따라하면 됩니다.
T
Terminal
docker swarm join-token manager
92. Manager 노드, Worker 노드
보시면 워커 노드로 참여할 때와 매니저 노드로 참여할 때 토큰값이 다른 걸 알 수 있습니다.
T
$ docker-machine ssh manager2
docker@manager2:~$ docker swarm join —-token
SWMTKN……dwznw 192.168.99.100:2377 && exit
$ docker-machine ssh manager3
docker@manager3:~$ docker swarm join —-token
SWMTKN……dwznw 192.168.99.100:2377 && exit
$ docker-machine ssh worker1
docker@worker1:~$ docker swarm join —-token
SWMTKN……dg06n 192.168.99.100:2377 && exit
. . .
Terminal
SWMTKN……dwznw
SWMTKN……dg06n
SWMTKN……dwznw
93. Manager 노드, Worker 노드
다시 manager1로 접속해서 위와 같이 연결된 노드 목록을 확인해 봅시다.
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
94. Manager 노드, Worker 노드
최초로 클러스터를 생성한 manager1노드가 리더로 선출 된 것을 볼 수 있습니다.
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
Tmanager1 Ready Leader
95. Manager 노드, Worker 노드
이렇게 해서 매니저와 워커의 역할로 나눠진 노드를 각각 3개씩 구성했습니다.
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
Tmanager1 Ready Leader
96. Manager 노드, Worker 노드
이제 이전에 같이 만들었던 헬로월드 서버를
스웜 클러스터에 배포하려고 하는데
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
Tmanager1 Ready Leader
97. Manager 노드, Worker 노드
단일 호스트에서는 단순히 docker run 명령어를 통해
한 개의 컨테이너만을 실행시켰지만
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
Tmanager1 Ready Leader
98. Manager 노드, Worker 노드
분산 환경에서는 다수의 컨테이너를 한 번에 실행하고
확장 & 감소를 할 수 있어야 합니다.
T
$ docker-machine ssh manager1
docker@manager1:~$ docker node list
ID HOSTNAME STATUS MANAGER STATUS
r3cdm4280fwopg8ttqmvuyl9k * manager1 Ready Leader
s8v5rm3iajtn5i22m2x4uj5c1 manager2 Ready Reachable
v3vhkxnkxxx2a1upqqksibouw manager3 Ready Reachable
mj7nb6e8zz4dk0oi8p1so2zba worker1 Ready
dp2wzr8zgfp875atxtrc1pjgc worker2 Ready
icnigqqfj081skxi222h60lfi worker3 Ready
Terminal
Tmanager1 Ready Leader
99. Service
몇개의 컨테이너를 실행할 지, 어떤 서버에 할당할 지 등의 정보를 가지면서 분산 환경에서
실행되는 컨테이너들의 논리적 단위를 Service라고 부릅니다
Worker
Manager
Worker
Worker
HelloWorld Service
Number of node: 3
image: helloworld
port: 80->80
. . .
100. Service
이 서비스를 생성해서 헬로월드 서버를
각 노예들에게 배포하도록 하겠습니다.
Worker
Manager
Worker
Worker
HelloWorld Service
Number of node: 3
image: helloworld
port: 80->80
. . .
101. Service
서비스는 docker service create 명령어를 통해 생성할 수 있습니다.
T
docker@manager1:~$ docker service create
--name=helloworld
--publish=3000:80/tcp
--constraint=node.role==worker
--replicas=3
--with-registry-auth
<Docker Hub ID>/helloworld
Terminal
102. Service
명령어 옵션으로 클라우드 외의 노출할 포트, 컨테이너 개수 등을 설정할 수 있습니다.
T
docker@manager1:~$ docker service create
--name=helloworld
--publish=3000:80/tcp
--constraint=node.role==worker
--replicas=3
--with-registry-auth
<Docker Hub ID>/helloworld
Terminal
103. docker@manager1:~$ docker service create
--name=helloworld
--publish=3000:80/tcp
--constraint=node.role==worker
--replicas=3
--with-registry-auth
<Docker Hub ID>/helloworld
Service
명령어 옵션으로 클라우드 외에 노출할 포트, 컨테이너 개수 등
서비스의 각종 설정을 할 수 있습니다.
T
Terminal
-> 서비스 이름
-> 3000 포트를 80포트에 바인딩
-> 워커 노드에만 배포
-> 컨테이너 3개만 실행한다.
104. Service
docker ps 명령어와 비슷하게 docker service ps를 통해 클러스터 내에
실행중인 helloworld 컨테이너 정보를 볼 수 있습니다.
T
docker@manager1:~$ docker service ps helloworld
ID NAME IMAGE NODE
sdlh3fke7cje helloworld.1 helloworld:latest worker1
ib9xs0b6uypx helloworld.2 helloworld:latest worker2
rhogifxyvcjq helloworld.3 helloworld:latest worker3
Terminal
105. Service
총 3개의 컨테이너가 각 워커에 실행 중인 것을 알 수 있습니다.
T
docker@manager1:~$ docker service ps helloworld
ID NAME IMAGE NODE
sdlh3fke7cje helloworld.1 helloworld:latest worker1
ib9xs0b6uypx helloworld.2 helloworld:latest worker2
rhogifxyvcjq helloworld.3 helloworld:latest worker3
Terminal
106. Service
실제로 워커 하나의 IP를 조회 해본 뒤
브라우저로 접속해보면 서버가 실행중인 것을 확인할 수 있습니다.
T$ docker-machine ip worker1
192.168.99.103
Terminal
107. Service
현재 스웜 클러스터를 그림으로 표시하면 위와 같이 나타낼 수 있습니다.
Worker
Manager (Leader)
helloworld
(3000 -> 80)
Worker
helloworld
(3000 -> 80)
Worker
helloworld
(3000 -> 80)
Manager Manager
Docker Swarm
109. Service Scale-Out, Scale-In
scale 명령어를 사용해 기존에 3개만 실행했던 컨테이너를 5개 까지 확장하였습니다.
T
docker@manager1:~$ docker service scale helloworld=5
helloworld scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
Terminal
110. Service Scale-Out, Scale-In
scale 명령어 이후 스웜 클러스터를 도식화하면 위와 같습니다.
현재 워커 노드가 3개뿐이여서 하나의 노드가 두 개의 컨테이너를 실행하는 상황이 연출되었는데
Worker
Manager (Leader)
helloworld
(3000 -> 80)
Worker
helloworld
(3000 -> 80)
Manager Manager
Docker Swarm
helloworld
(3000 -> 80)
Worker
helloworld
(3000 -> 80)
helloworld
(3000 -> 80)
112. Service Update
현재 실행중인 컨테이너를 새로운 버전으로 배포하는 것도
도커 명령어로 손쉽게 할 수 있습니다.
Worker
Helloworld:1
(3000 -> 80)
Helloworld:2
(3000 -> 80)
113. Service Update
사실 저희 프로젝트에서 도커 스웜을 도입한 가장 큰 이유가 자동화의 매력이었는데요
Worker
Helloworld:1
(3000 -> 80)
Helloworld:2
(3000 -> 80)
114. Swarm 도입 이전
배포 프로세스
저희 팀은 도커 스웜 도입 이전에는 직접 AWS 클라우드에서 인스턴스를 생성해
새로운 버전의 도커를 실행해 인스턴스 자체를 교체하는 방식으로 배포를 진행했었습니다.
EC2 Instance
Helloworld:1
(Stopped)
신규 버전이 있을때마다 이렇게 노동했다!..
EC2 Instance
Helloworld:2
115. 도커 스웜 도입 이후에는 CI툴을 이용해서 배포 자동화를 구축 했습니다.
CI Runner에서 매니저 노드에 접속해서 명령어하나만 호출해주면 되기 때문에
Swarm 도입 이후
배포 프로세스
소스 푸시 서비스 업데이트
명령어 호출
새로운 컨테이너로
교체
116. 혹시나 배포 자동화를 고민하고 계신다면 쉽게 도입하실 수 있을 겁니다.
Swarm 도입 이후
배포 프로세스
소스 푸시 서비스 업데이트
명령어 호출
새로운 컨테이너로
교체
117. 서버를 배포하는 방법을 보여드리기 위해 이전에 작성했던
Hello, World 서버에 한글화를 도입했습니다.
Service Update Example
main.py
118. 같은 방식으로 도커 이미지를 생성하고
레지스트리에 업로드 합니다.
Service Update Example
T
$ docker build -t helloworld .
$ docker tag helloworld <Docker Hub ID>/helloworld
$ docker push <Docker Hub ID>/helloworld
Terminal
** <Docker Hub ID> 에는 본인 도커 허브 계정명을 적어주세요.
119. 이제 매니저 노드에 접속해서 service update 명령어를 사용하면
컨테이너가 새로운 버전으로 배포된 걸 확인할 수 있습니다.
Service Update Example
T
docker@manager1:~$ docker service update
--image <Docker Hub ID>/helloworld
—-with-registry-auth helloworld
Terminal
120. CI 파이프라인으로 매니저 노드에서 이 명령어를 실행하면
배포 자동화 프로세스가 완성됩니다
Service Update Example
T
docker@manager1:~$ docker service update
--image <Docker Hub ID>/helloworld
—-with-registry-auth helloworld
Terminal
121. 서비스를 업데이트 할 때 컨테이너를 동시에 교체해버리면 서버가 재시작 되는 시간동안
다운 타임이 발생하기 때문에 사용자 입장에서는 동작이 안되는 것 처럼 보입니다.
무중단 배포
Service Update Example
122. Docker Swarm에서는 컨테이너를 한번에 교체하지 않고
순차적으로 바꾸는 Rolling Update 전략을 지원합니다.
무중단 배포
Service Update Example
123. 서비스 업데이트 명령어에 —update-delay 옵션을 추가 하면
전체 컨테이너가 교체되는 시간을 조절할 수 있습니다.
T
docker@manager1:~$ docker service update
—-update-delay=120s
--image <Docker Hub ID>/helloworld
—-with-registry-auth helloworld
Terminal
—-update-delay=120s
Service Update Example