쿠버네티스에는아래 그림과 같이 두가지 배포방법이 있습니다
Recreate
Recreate 방식은 이전버전 A를 종료시킨후 신규버전 B를 롤아웃 시키는 방식입니다.
pros
- 가장 쉬운 배포방법
- 클라우드 리소스 비요이 적음
cons
- A가 중지되고 B가 배포되기전까지 서비스가 중단되어 사용자에게 악영향을 줌
Rolling Update
-
기존서버를 순차적으로 중지시키며 순차적으로 업그레이드 시키는 방식으로, kubernetes에서 spec.strategy.type을 지정하지 않으면 기본적으로 RollingUpdate를 사용합니다.
-
처음 쿠버네티스에 입문하였을때 replicaset과, deployment의 차이점은 yaml파일로만 놓고 봤을때는 다른점이 kind 부분 말고는 없었습니다. 똑같이 파드를 적정갯수 만큼 생성해주고, crash되면 다시 복구시켜주는 점에서는 말이죠.
오늘은 배포방식에 대해 공부하면서 왜 deployment를 사용하여 pod을 배포하는가에 대한 궁금증을 풀 수 있었습니다.
Deployment를 사용하여 pod을 배포 하게되면 롤아웃을 생성합니다. 그리고 이 롤아웃은 새로운 배포 버전(revision)을 생성합니다. 이말이 잘 이해가 안 되실수도 있는데
자세한 설명은 실습을 진행하면서 하도록 하겠습니다.
아래와같이 deployment definition을 작성한 yaml파일이 있습니다.
#depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
아래의 명령어를 사용하여 deployment를 생성하게되면
kubectl apply -f depl.yaml
myapp-deployment라는 이름을가진 deployment와, myapp-deployment-hash값 을 가진 replicaset, 그리고 deployment를 통해 생성된 replicaset에 의해 생성된 pod을 확인할 수 있습니다.
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/myapp-deployment-7df67f74c5-4nkmq 1/1 Running 0 5m27s
pod/myapp-deployment-7df67f74c5-bnl9r 1/1 Running 0 5m27s
pod/myapp-deployment-7df67f74c5-jsd9p 1/1 Running 0 5m27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d2h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myapp-deployment 3/3 3 3 5m27s
NAME DESIRED CURRENT READY AGE
replicaset.apps/myapp-deployment-7df67f74c5 3 3 3 5m27s
아직까지는 별 차이가 없지요, deployment가 생겼다는것 외에는 말입니다.
하지만 사실은 이외에도 revision
이라는 것을 생성합니다.
이는 해당 deployment를 업데이트 할때마다 생기고, 이전 revision
의 정보도 가집니다. 또한, 새로운 버전의 replicaset
을 생성하고, 이전버전의 replicaset
의 정보를 남겨놓습니다.
만약에 업데이트후에 문제가 생겼을시에 롤백을 가능케 하기 위해서 입니다. 그리고 이러한점이 deployment를 사용해서 pod을 배포했을때랑 replicaset을 사용했을때의 가장 큰 차이점이 아닐까 싶습니다.
Rollout 상태확인
deployment를 사용하여 pod을 배포하게되면 rollout을 생성한다고 했었는데
추가로 사용할 수 있는 커맨드도 생깁니다. rollout
이라는 커맨드인데요.
rollout 커맨드를 통하여 deployment의 revision및 history를 확인할 수 있습니다
kubectl rollout status deployment
커맨드를 사용하여 다음과 같이 롤아웃 생성의 상태를 확인할 수 있습니다.
$ kubectl rollout status deployment/myapp-deployment
Waiting for deployment "myapp-deployment" rollout to finish: 0 of 3 updated replicas are available...
Waiting for deployment "myapp-deployment" rollout to finish: 1 of 3 updated replicas are available...
Waiting for deployment "myapp-deployment" rollout to finish: 2 of 3 updated replicas are available...
deployment "myapp-deployment" successfully rolled out
Rollout history 확인
또한 kubectl rollout history deployment
커맨드를 사용하면 아래와 같이 리비전 정보를 확인할 수 있는데요
$ kubectl rollout history deploy/myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
1 <none>
하나의 revision 밖에 보이지않습니다. 그 이유는 depl.yaml을 이용하여 처음으로 배포한 버전이기 때문입니다.
Rollout update
해당 deployment를 업데이트하면 어떤일이 생기는지 보도록 하겠습니다.
우선 yaml파일을 수정해줍니다
#depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx:1.20-alpine <----- 바뀐부분
replicas: 3
selector:
matchLabels:
type: front-end
이미지를 바꿀때에는 간단하게 set image를 통해서도 가능하지만 개인적으로 변경상황을 이력으로 남기는게 좋다고 생각하여 해당 방법을 사용합니다.
변경사항을 적용시켜줍니다.
$ kubectl apply -f depl.yaml
deployment.apps/myapp-deployment configured
그다음 replicaset과 revision을 확인해봅시다
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-79896f8f68 3 3 3 5m14s
myapp-deployment-7df67f74c5 0 0 0 5m42s
replicaset이 하나더 생겼으며,
revision도 하나더 생긴것을 확인할 수 있습니다.
$ kubectl rollout history deploy myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
2 <none>
1 <none>
하지만 change-cause가 None 으로 되있으면 무엇이 바뀌었는지 알 수 가없는데, 아래 커맨드를 이용하면 따로 설정이 가능합니다.
kubectl annotate deployment.v1.apps/[deployment name] kubernetes.io/change-cause="reason of update"
해당커맨드를 사용하여 주석을 달고 다시 확인해봅시다
$ kubectl annotate deployment.v1.apps/myapp-deployment kubernetes.io/change-cause="image updated to 1.20"
deployment.apps/myapp-deployment annotated
$ kubectl rollout history deployment myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
1 <none>
2 image updated to 1.20
주석이 잘 달린것을 확인할 수 있습니다.
Rollback
만약에 새로운 버전으로 업데이트를 했는데 문제가 생겼을때 이전 버전 으로 돌아갈 수 있는 기능입니다.
kubeclt rollout undo deployment
커맨드를 사용하여 롤백 시킬 수 있습니다.
직접 실습해봅시다.
$ kubectl rollout undo deployment myapp-deployment
deployment.apps/myapp-deployment rolled back
성공적으로 롤백 되었다고 뜹니다.
우선 image가 다시 원래대로 돌아왔는지 확인해봅니다
$ kubectl describe deployment myapp-deployment
Name: myapp-deployment
Namespace: default
CreationTimestamp: Wed, 02 Jun 2021 07\:05\:06 +0000
Labels: app=myapp
type=front-end
Annotations: deployment.kubernetes.io/revision: 3
kubernetes.io/change-cause:
Selector: type=front-end
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=myapp
type=front-end
Containers:
nginx-container:
Image: nginx <------- 1.20 에서 다시 원래대로 돌아온것을 확인할 수 있습니다.
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: myapp-deployment-7df67f74c5 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 1
Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 2
Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 2
Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 1
Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 3
Normal ScalingReplicaSet 23m deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 0
Normal ScalingReplicaSet 4m28s deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 1
Normal ScalingReplicaSet 4m24s deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 2
Normal ScalingReplicaSet 4m24s deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 2
Normal ScalingReplicaSet 4m20s (x2 over 24m) deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 3
Normal ScalingReplicaSet 4m20s deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 1
Normal ScalingReplicaSet 4m16s deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 0
그럼 replicaset과 revision은 어떨까요?
#이미지 1.20으로 업데이트후 replicaset 상태
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-79896f8f68 3 3 3 5m14s
myapp-deployment-7df67f74c5 0 0 0 5m42s
#롤백후 replicaset상태
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-79896f8f68 0 0 0 25m
myapp-deployment-7df67f74c5 3 3 3 26m
revision
$ kubectl rollout history deployment myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
2 image updated to 1.20
3 <none>
replicaset은 이전 버전의 replicaset으로 바뀐것을 확인할 수가 있는데 revision은 1로돌아가는것이아닌 1이 증가한 것을 확인할 수 있습니다. 여기서 궁금한점이 생겼습니다.
undo를 여러번하면 어떻게될까요?
$ kubectl rollout history deployment myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
3 <none>
4 image updated to 1.20
결과
$ kubectl describe deployment myapp-deployment
Name: myapp-deployment
Namespace: default
CreationTimestamp: Wed, 02 Jun 2021 07\:05\:06 +0000
Labels: app=myapp
type=front-end
Annotations: deployment.kubernetes.io/revision: 4
kubernetes.io/change-cause: image updated to 1.20
Selector: type=front-end
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=myapp
type=front-end
Containers:
nginx-container:
Image: nginx:1.20
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: myapp-deployment-79896f8f68 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 1
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 2
Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 2
Normal ScalingReplicaSet 14m (x2 over 33m) deployment-controller Scaled up replica set myapp-deployment-7df67f74c5 to 3
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 1
Normal ScalingReplicaSet 13m deployment-controller Scaled down replica set myapp-deployment-79896f8f68 to 0
Normal ScalingReplicaSet 2m13s (x2 over 33m) deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 1
Normal ScalingReplicaSet 2m9s (x2 over 33m) deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 2
Normal ScalingReplicaSet 2m9s (x2 over 33m) deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 2
Normal ScalingReplicaSet 2m5s (x2 over 33m) deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 1
Normal ScalingReplicaSet 2m5s (x2 over 33m) deployment-controller Scaled up replica set myapp-deployment-79896f8f68 to 3
Normal ScalingReplicaSet 2m1s (x2 over 33m) deployment-controller Scaled down replica set myapp-deployment-7df67f74c5 to 0
undo 를 여러번하니 nginx <-> nginx:1.20 왔다 갔다 하는 모습을 보여줍니다.
history
history를 보아도 두줄의 결과만 보여주기도했고, 정말 바로 이전단계까지만 이동할 수 있는건지도 궁금했습니다.
궁금한건 못참기에 바로 kubernetes.io를 찾다보니 원하는 revision으로 가려면 –to-revision=[resion-number] 를 입력해야되는것을 알 수 있었습니다.
deployment 의 spec 밑에 revisionHistoryLimit: 10 으로 설정되어 있는것도 확인했으며 이 또한 수정할 수 있었군요 ㅎㅎ
바로 이전 단계만 이동 가능하다고 포스트 올렸다가 호다닥 수정하네요
그나저나 history에는 왜 사람 햇갈리게 두줄만을 보여줬던 걸까요?
kubernetes는 상당히 똑똑했기 때문입니다.
이미 기억하고있는 replicaset랑 다름이 없기에 새로운 replicaset을 생성하지 않는것이었습니다.
history에 없는 다른 버전의 nginx의 이미지로 바꾸어주니 replicaset과 history 각각 하나씩 더 생기는것을 확인할 수 있었습니다.
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-54d59f8648 3 3 3 17m
myapp-deployment-79896f8f68 0 0 0 117m
myapp-deployment-7df67f74c5 0 0 0 118m
$ kubectl rollout history deploy myapp-deployment
deployment.apps/myapp-deployment
REVISION CHANGE-CAUSE
3 image updated to 1.20
4 <none>
5 <none>