4
4
5
5
### WAR를 빌드하고 톰캣에 넣어서 배포
6
6
- 장점:
7
- - 단점:
7
+ - 단점: 톰캣을 미리 설치해둬야한다.그리고 톰캣 스크립트가 복잡하다.
8
8
9
9
### JAR를 빌드하고 JAR를 실행해서 배포
10
- - 장점:
11
- - 단점:
10
+ - 장점: 자바만 설치되어 있다면 어디서든 실행가능하다.
11
+ - 단점: 스케일링이 안된다. 무중단 배포하려면 복잡한 스크립트가 필요하다. 또한 여러 프로세스를 실행하게 되면 로드 밸런서가 필요하다.
12
12
13
13
### 위의 것들을 도커이미지로 만들어서 실행
14
- - 장점:
15
- - 단점:
14
+ - 장점: 단순한 자바 애플리케이션은 그냥 도커로 실행하나 JAR로 실행하나 큰 차이가 없지만, OS에 종속적인 네이티브 기능들을 사용할 때 도커 이미지로 만들면 유용하다.
15
+ - 단점: 위와 마찬가지의 단점이 있다.
16
16
17
17
## 필요한 기능
18
18
- 무중단 배포
19
19
- 스케일 관리
20
20
21
21
## 도커 스웜 소개
22
22
### 도커 엔진과 통합된 클러스터 관리
23
- 다른 부가적인 설치 없이 도커를 설치하고 도커의 CLI를 이용하여 도커 스웜 클러스터를 구축할 수 있습니다.
23
+ 다른 부가적인 설치 없이 도커를 설치하고 도커의 CLI를 이용하여 도커 스웜 클러스터를 구축할 수 있습니다.
24
24
25
25
### 분산 설계
26
+ 노드들은 네트워크가 연결된 채로 분산되어 있고, ` manager ` , ` worker ` 두가지 역할을 가질 수 있습니다.
26
27
27
28
### 선언적 서비스 모델
29
+ 선언적으로 서비스의 원하는 상태를 정의하고 구성합니다.
28
30
29
31
### 스케일링 (확장과 축소)
32
+ 애플리케이션의 복제의 개수도 서비스의 상태로서 선언적으로 정의되며 개수를 변경하게 되면 자동으로 스케일링합니다.
30
33
31
34
### 상태 조정(회복)
35
+ 선언적으로 정의한 상태를 자동으로 회복합니다. 예를 들어, 복제본의 개수가 3개이고 컨테이너를 실행하던 특정 노드가 알 수 없는 이유로 종료될 경우 자동으로 다른 노드에 컨테이너를 실행하여 복제본의 개수를 맞춥니다.
32
36
33
37
### 멀티 호스트 네트워킹 (오버레이 네트워크)
38
+ 오버레이 네트워크를 이용하여 멀티 호스트 환경에서 마치 같은 호스트처럼 네트워크 환경을 구성할 수 있습니다.
34
39
35
40
### 서비스 검색
41
+ 서비스들은 도커 스웜의 DNS에 특정 이름으로 할당되고 스웜 내 서비스들은 그 이름을 가지고 네트워킹이 가능합니다.
36
42
37
43
### 로드 밸런싱
44
+ 복제본의 개수가 여러개일 때 도커 스웜이 자동으로 로드밸런싱을 합니다.
38
45
39
46
### 기본 보안
47
+ 기본적으로 노드간 통신에서 TLS를 강제합니다.
40
48
41
49
### 롤링 업데이트
50
+ 여러 복제본을 가진 서비스들은 기본적으로 롤링업데이트를 하며, 이를 이용하여 무중단 배포가 가능합니다.
42
51
43
52
## 실습
44
53
### 시나리오
45
54
46
- 쇼핑몰을 운영하고 있습니다. ` 쇼핑몰 프론트 서비스 ` 는 ` 상품 백앤드 서버스 ` 와 ` 쿠폰 백앤드 서비스 ` 로 구성되어 있습니다.
47
- 이 세 서비스는 각각 도커라이즈 되어있다. 노드가 세개인 도커 스웜을 이용하여 배포하여 아래의 목표를 달성해본다 .
55
+ 쇼핑몰을 운영하고 있습니다. ` 쇼핑몰 프론트 서비스 ` 는 ` 상품 백앤드 서버스 ` 와 ` 쿠폰 백앤드 서비스 ` 로 구성되어 있습니다. ` 쇼핑몰 프론트 서비스 ` 에서 상품 상세 API는 상품, 쿠폰 백앤드에서 각 정보를 조회하고 조합하여 응답을 보내줍니다.
56
+ 이 세 서비스는 각각 도커라이즈 되어있다. 노드가 세개인 도커 스웜을 이용하여 배포하여 아래의 목표를 달성해봅니다 .
48
57
49
58
- 트래픽에 따라 스케일이 조정되어야 한다.
50
59
- 무중단으로 배포되어야 한다.
@@ -62,19 +71,236 @@ docker swarm init --advertise-addr 172.26.8.153
62
71
docker swarm join --token SWMTKN-1-1ppzdtuuy3rpulzm34w9hyqc1d1ykl2i638igpynyvjlgf6qps-9hprisuy8zhpgjglhyw1uxddb 172.26.8.153:2377
63
72
```
64
73
74
+ ### 프로젝트 클론
75
+ ```
76
+ git clone https://github.com/voyagerwoo/demo-shoppingmall-msa
77
+ cd demo-shoppingmall-msa
78
+ ```
79
+
80
+ ### 오버레이 네트워크 생성
81
+
82
+ ```
83
+ docker network create -d overlay --attachable backend
84
+ docker network create -d overlay --attachable frontend
85
+ ```
86
+
87
+ #### 오버레이 네트워크
88
+ ![ ] ( ./ingress-routing-mesh.png )
89
+
90
+ 호스트가 달라도 마치 같은 노드에 있는 것처럼 접근할 수 있게 해주는 네트워크 방식입니다.
65
91
66
92
### 상품 백앤드 서비스 배포
67
93
94
+ #### docker stack
95
+ ```
96
+ version: "3.6"
97
+ services:
98
+ app:
99
+ image: voyagerwoo/demo-shoppingmall-prod-service:${IMG_TAG:-latest}
100
+ networks:
101
+ backend:
102
+ aliases:
103
+ - prod.api
104
+ deploy:
105
+ mode: replicated
106
+ replicas: ${REPLICAS:-2}
107
+ update_config:
108
+ parallelism: 1
109
+ order: start-first
110
+ failure_action: rollback
111
+ resources:
112
+ limits:
113
+ memory: 200M
114
+ reservations:
115
+ memory: 100M
116
+ healthcheck:
117
+ test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
118
+ interval: 10s
119
+ timeout: 5s
120
+ retries: 3
121
+ start_period: 10s
122
+
123
+ networks:
124
+ backend:
125
+ external: true
126
+ name: backend
127
+ ```
128
+
129
+ #### 배포
130
+
131
+ ```
132
+ docker stack deploy -c={도커 컴포즈 파일} {스택 이름}
133
+ ```
134
+
135
+ ```
136
+ cd prod_service
137
+ docker stack deploy -c=docker-stack.yml prod
138
+ ```
139
+
140
+ #### 배포확인
141
+ > 기본적으로 서비스의 전체 이름은 ` {스택이름}_{서비스이름} ` 이다.
142
+ > 예를 들어, 스택이 ` prod ` 서비스가 ` app ` 이면 ` prod_app `
143
+
144
+ - 전체 서비스 확인
145
+ ```
146
+ docker service ls
147
+ ```
148
+ - 특정 서비스 컨테이너 확인
149
+ ```
150
+ docker service ps prod_app
151
+ ```
152
+ - watch를 이용해서 모니터링 하기
153
+ ```
154
+ watch docker service ps prod_app
155
+ ```
156
+ - 완전 자세히 보기
157
+ ```
158
+ docker service inspect prod_app
159
+ ```
160
+
161
+ #### 서비스
162
+ 이미지의 실행 방식(사용할 포트, 배포 방식, 리소스 등)에 대한 정의를 담고 있는 논리적인 객체를 의미합니다. 위의 도커 스택에서는 `app`이라는 서비스가 정의되어 있습니다.
163
+
164
+ #### 스택
165
+ 스택은 서비스들의 집합으로 각 서비스가 의존하는 객체들을 정의하고 공유합니다. 위의 도커 스택은 `app`이라는 서비스와 서비스에서 사용하는 네트워크를 정의하고 있습니다.
68
166
69
167
### 쿠폰 백앤드 서비스 배포
168
+ #### docker stack
169
+ ```
170
+ version: "3.6"
171
+ services:
172
+ app:
173
+ image: voyagerwoo/demo-shoppingmall-coupon-service:${IMG_TAG:-latest}
174
+ networks:
175
+ backend:
176
+ aliases:
177
+ - coupon.api
178
+ deploy:
179
+ mode: replicated
180
+ replicas: ${REPLICAS:-2}
181
+ update_config:
182
+ parallelism: 1
183
+ order: start-first
184
+ failure_action: rollback
185
+ resources:
186
+ limits:
187
+ memory: 200M
188
+ reservations:
189
+ memory: 100M
190
+ healthcheck:
191
+ test: [ "CMD", "curl", "-f", "http://localhost:3002/health "]
192
+ interval: 10s
193
+ timeout: 5s
194
+ retries: 3
195
+ start_period: 10s
196
+
197
+ networks:
198
+ backend:
199
+ external: true
200
+ name: backend
201
+
202
+ ```
203
+ #### 배포
204
+
205
+ ```
206
+ cd coupon_service
207
+ docker stack deploy -c=docker-stack.yml coupon
208
+ ```
70
209
71
210
### 쇼핑몰 프론트 서비스 배포
211
+ #### docker stack
212
+ 백앤드용 서비스들과는 다르게 프론트 앤드 서비스는 포트를 정의하여 외부에 오픈합니다.
213
+
214
+ ```
215
+ version: "3.6"
216
+ services:
217
+ app:
218
+ image: voyagerwoo/demo-shoppingmall-front-service:${IMG_TAG:-latest}
219
+ ports:
220
+ - "80:8080"
221
+ networks:
222
+ frontend:
223
+ deploy:
224
+ mode: replicated
225
+ replicas: ${REPLICAS:-2}
226
+ update_config:
227
+ parallelism: 1
228
+ order: start-first
229
+ failure_action: rollback
230
+ resources:
231
+ limits:
232
+ memory: 200M
233
+ reservations:
234
+ memory: 100M
235
+ healthcheck:
236
+ test: [ "CMD", "curl", "-f", "http://localhost:8080/health "]
237
+ interval: 10s
238
+ timeout: 5s
239
+ retries: 3
240
+ start_period: 10s
241
+
242
+ networks:
243
+ frontend:
244
+ external: true
245
+ name: backend
72
246
247
+ ```
248
+
249
+ #### 배포
250
+
251
+ ```
252
+ cd front_service
253
+ docker stack deploy -c=docker-stack.yml front
254
+ ```
73
255
### 테스트
256
+ 상품 상세 API를 호출해봅니다.
257
+
258
+ 
74
259
75
260
### 스케일인아웃
261
+ 도커 스택을 정의할 때, 환경변수로 `REPLICAS`를 만들고 기본값은 2를 넣었습니다. 이를 이용하여 복제본의 개수를 변경해봅니다.
262
+
263
+ ```
264
+ export REPLICAS=4 && docker stack deploy -c=docker-stack.yml front
265
+ watch docker service ps front_app
266
+ ```
267
+
268
+ ### 서비스 업데이트와 무중단
269
+ ```
270
+ deploy:
271
+ mode: replicated
272
+ replicas: ${REPLICAS:-2}
273
+ update_config:
274
+ parallelism: 1
275
+ order: start-first
276
+ failure_action: rollback
277
+ ```
278
+ 위 코드는 이 서비스가 어떻게 배포될지에 대해서 정의하고 있습니다. 복제본이 여러개 있는 모드로 배포가 되며 복제본의 개수만큼 복제됩니다.
279
+
280
+ 업데이트가 될때 동시에 하나씩 업데이트가 되고 종료 후 하나씩 배포되는 것이 아니라 먼저 배포하고 컨테이너가 완전히 올라오면(헬스 체크가 성공하면) 기존의 컨테이너는 종료됩니다. 만약 헬스 체크가 실패하면 롤백됩니다.
281
+
282
+ 도커 스택에 이미지 태그를 환경변수로 넣었습니다. 이를 이용하여 상품에 매핑된 쿠폰으로 가격을 계산하여 보여주는 기능이 추가된 서비스를 배포해보겠습니다.
283
+
284
+ ```
285
+ export IMG_TAG=2 && docker stack deploy -c=docker-stack.yml front
286
+ ```
287
+ 계속 API를 호출하여 중단이 있느지 테스트합니다.
288
+
289
+ 
290
+
291
+ ### 불편한점
292
+ - 로그 보기
293
+ - 컨테이너의 묶음을 하나의 단위로 관리하고 싶을때
76
294
77
- ### 서비스 무중단 업데이트
78
295
79
296
## 정리
297
+ - 도커만 설치했다면 간단하게 스웜 클러스터 구축 가능
298
+ - 도커 스택을 이용하여 스택과 서비스의 상태를 정의
299
+ - 도커 스웜이 정의된 상태를 확인하고 조정
300
+ - 오버레이 네트워크를 통해서 여러 호스트간 네트워킹 가능
301
+ - 롤링 업데이트를 통해서 기본적으로 무중단 배포를 지원
80
302
303
+ ## 참고 자료
304
+ - https://docs.docker.com/get-started/part3/
305
+ - https://docs.docker.com/compose/compose-file
306
+ - https://subicura.com/2017/02/25/container-orchestration-with-docker-swarm.html
0 commit comments