14. 쿠버네티스 배포 전략(롤링업데이트, 블루그린)

어플리케이션을 컨테이너로 배포하는 시대에 들어오면서 배포 전략에도 변화가 생겼다. 컨테이너의 장점을 살려 작업을 자동화하고 서비스 무중단을 어떻게 유지해야 할지를 고민한다.

롤링 업데이트

디플로이먼트의 파드를 교체하는 전략은 .specs.strategy.type로 정의 되며 RollingUpdate(기본값), Recreate(기존 파드가 모두 삭제된 다음 새로운 파드를 생성함) 중 선택한다.

다음 코드를 통해 서비스와 디플로이먼트를 생성하고 롤링업데이트가 어떻게 진행되는지 보자. 해당 서비스는 get 요청에 버전정보를 리턴하는 서비스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: v1
kind: Service
metadata:
name: echo-version
labels:
app: echo-version
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: echo-version
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-version
labels:
app: echo-version
spec:
replicas: 1
selector:
matchLabels:
app: echo-version
template:
metadata:
labels:
app: echo-version
spec:
containers:
- name: echo-version
image: gihyodocker/echo-version:0.1.0
ports:
- containerPort: 8080

get요청을 지속적으로 보내어 버전정보를 출력하기 위한 파드를 정의하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: update-checker
labels:
app: update-checker
spec:
containers:
- name: kubectl
image: gihyodocker/fundamental:0.1.0
command:
- sh
- -c
- |
while true
do
APP_VERSION=`curl -s http://echo-version/`
echo "[`date`] $APP_VERSION "
sleep 1
done

다음을 입력하여 배포하자.

1
2
$ kubectl apply -f 생성한 파일(디플로이먼트,서비스)
$ kubectl apply -f 생성한 파일(파드)

출력되는 버전정보를 확인해보자.

1
$  kubectl logs -f update-checker

위에 이미지의 버전을 변경해보자. 그리고

1
image: gihyodocker/echo-version:0.1.0 ->image: gihyodocker/echo-version:0.2.0

반영 후 롤링업데이트를 확인해보자.

1
2
3
$ kubectl apply -f 수정된파일.

$ kubectl logs -f update-checker

재배포 과정: 새로운 파드가 생성되고 있을 때 기존 파드는 여전히 Running이다. 이후 새로운 파드가 생성되어 실행상태가 되고 기존파드는 Terminating이 된다. 그 후 기존파드는 완전히 폐기된다.

실행중인 컨테이너에 대한 헬스체크 설정

쿠버네티스의 컨테이너 헬스체크에는 livenessProbe, readinessProbe 기능이 있다.

livenessProbe: 어플리케이션 헬스 체크 기능으로 어플리케이션이 의존하는 컨테이너 안의 파일이 존재하는지를 확인하는 용도로 사용된다.
readinessProbe : 컨테이너 외부에서 HTTP 요청같은 트래픽을 발생시켜 이를 처리할 수 있는 상태인지를 확인하는 기능이다.

헬스체크 기능을 포함한 컨테이너는 Running 상태가 되어도 READY 가 0/1 로 나오다가 모든 헬스 체크를 통과하고 1/1로 된다.

블루그린 배포

롤링업데이트는 강력하지만 새버전, 구버전이 동시에 존재하는 경우도 생길 수 있다. 이는 때로는 부작용을 가져올 수 있다. 이럴 때 사용할 수 있는것이 블루그린 배포인데 블루그린은 새버전, 구버전의 2세트의 서버를 마련하고 한꺼번에 교체하는 배포 방법이다. 이는 로드 밸런서 혹은 서비스 디스커버리 수준에서 참조 대상을 교체하는 방식으로 이뤄지는 배포형태이다. 이는 서버군이 아닌 켄테이너군을 통해 구현되고 배포할 서버군을 2게통으로 유지해야 하므로 롤링 업데이트보다 필요 리소스 양이 늘어난다. 그럼에도 다음 두가지의 장점을 누릴 수 있다.
1.신버전과 구버전이 혼재하는 시간없이 순간적인 교체가능
2.한쪽 서버군을 릴리즈 전 스탠바이 상태로 사용할 수 있음

블루그린 배포 실습

2세트를 미리 만둘어주자.

echo-version-blue.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-version-blue
labels:
app: echo-version
color: blue
spec:
replicas: 1
selector:
matchLabels:
app: echo-version
color: blue
template:
metadata:
labels:
app: echo-version
color: blue
spec:
containers:
- name: echo-version
image: gihyodocker/echo-version:0.1.0
ports:
- containerPort: 8080

echo-version-green.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-version-green
labels:
app: echo-version
color: green
spec:
replicas: 1
selector:
matchLabels:
app: echo-version
color: green
template:
metadata:
labels:
app: echo-version
color: green
spec:
containers:
- name: echo-version
image: gihyodocker/echo-version:0.2.0
ports:
- containerPort: 8080

echo-version-blue / echo-version-green으로 정의한 두개의 디플로이먼트파일을 준비하자. metadata.label을 주목해서 보자.

그 후 다음명령어를 통해 디플로이먼트를 배포하자

1
2
$ kubectl apply -f echo-version-blue.yaml
$ kubectl apply -f echo-version-green.yaml

셀렉터 레이블을 변경해 디플로이먼트를 변경할 수 있다.

echo-version-service.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: echo-version
labels:
app: echo-version
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: echo-version
color: blue


1
2
3
kubectl apply -f echo-service

kubectl logs -f update-checker

위의 명령어를 통해 서비스를 배포하고 업데이트 체크를 해보자.

1
kubectl patch service echo-version -p '{"spec":{"selector":{"color":"green"}}}'

위의 명령어를 입력하여 서비스 대상 디플로이먼트를 변경하자.

이후에 출력되는 버전을 보면 버전이 바뀐것을 확인할 수 있다.

Share