일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 젠킨스
- spring
- vue
- Jenkins
- login
- Kafka
- 자동
- 클러스터
- Cluster
- EMR
- fastcampus
- 자바
- SpringBoot
- Docker
- Zeppelin
- Mac
- ec2
- Redis
- java
- hive
- aws
- 레디스
- gradle
- 간단
- 설정
- redash
- 예제
- 머신러닝
- config
- 로그인
- Today
- Total
코알못
[kubernetes] Deployment - 배포 전략 Recreate, RollingUpdate 및 롤백 본문
저번시간에 Deployment 배포 전략 두가지에 대해서 간단하게 개념을 배웠고 이번시간 실습을 통해 익혀보도록 하자! 추가로 롤백 하는 방법도 알아보도록 하며 실습 내용은 아래와 같다.
- 배포전략 Recreate 실습
- 배포전략 RollingUpdate 실습
- Revision 을 통한 롤백 실습
우선 배포전략 Recreate 실습을 진행해보자!
아래와 같이 Deployment 오브젝트 yaml 파일을 작성한다.
# deployment-v4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: Recreate
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용한다.
$ kubectl apply -f deployment-v4.yaml
deployment.apps/my-app created
정상적으로 배포 됐는지 상세정보를 확인하며 정상적으로 3개의 파드를 생성하였다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sun, 21 May 2023 16:51:06 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-5d6554bfbf (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 42s deployment-controller Scaled up replica set my-app-5d6554bfbf to 3
이제 배포 과정을 보기 위해 이미지 버전을 1.0 > 2.0으로 변경 해본다.
우선 기존 deployment 파일의 image 부분을 1.0 > 2.0으로 수정한다.
# deployment-v4.yaml
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: Recreate
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:2.0
deployment 상세 설명을 보면 기존 ReplicaSet의 Pod 모두 종료후 새 ReplicaSet의 Pod 생성 하는것을 볼 수 있다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sun, 21 May 2023 16:51:06 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-856cb86fb4 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set my-app-5d6554bfbf to 3
Normal ScalingReplicaSet 63s deployment-controller Scaled down replica set my-app-5d6554bfbf to 0 from 3
Normal ScalingReplicaSet 61s deployment-controller Scaled up replica set my-app-856cb86fb4 to 3
이제 RollingUpdate(점진전 배포 전략)을 실습 해보자!
저번 시간에 간단하게 본 개념을 다시 짚어보자면!
maxUnavaliable은 최대 이용 불가능 파드이며 maxSurge는 한시점 파트 최대 추가 파드 갯수 (최대 파드 수 : replicas + maxSurge) 이다.
예시로 replicas 3, maxUnavaliable 1, maxSurge 1 이라면 최소 떠있어야 하는 파드는 2개(replicas-maxUnavaliable), 최대 파드는 4개(replicas+maxSurge)가 된다.
실습을 위해 deployment 오브젝트의 yaml 파일을 만들고
replicas 5, maxUnavailable 2, maxSurge 1로 최소 3개의 파드, 최대 6개의 파드가 뜰 수 있도록 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 5
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
maxSurge: 1
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용한다.
$ kubectl apply -f deployment-v5.yaml
deployment.apps/my-app created
deployment 의 상세정보를 보면 정상적으로 5개의 pod 를 생성 하였다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Fri, 26 May 2023 21:11:15 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 2 max unavailable, 1 max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-5d6554bfbf (5/5 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 20m deployment-controller Scaled up replica set my-app-5d6554bfbf to 5
파드 항목을 조회하여 정상적으로 떴는지 확인하며
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-5d6554bfbf-5h896 1/1 Running 0 20m
my-app-5d6554bfbf-l5pnz 1/1 Running 0 20m
my-app-5d6554bfbf-pdkns 1/1 Running 0 20m
my-app-5d6554bfbf-vjzmr 1/1 Running 0 20m
my-app-5d6554bfbf-z4kmj 1/1 Running 0 20m
롤아웃이 정상적으로 이뤄졌는지 체크한다.
$ kubectl rollout status deployment/my-app
deployment "my-app" successfully rolled out
이제 replicaset의 상태를 보면 5개가 정상적으로 레디 된것을 볼 수 있다.
$ kubectl get rs -w
NAME DESIRED CURRENT READY AGE
my-app-5d6554bfbf 5 5 5 29m
이제 버전을 1.0 > 2.0 으로 변경하여 배포 전략을 지켜 보도록 하자!
아래와 같이 image 부분을 1.0 > 2.0 으로 변경한다.
# deployment-v5.yaml
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:2.0
클러스터에 적용 한다.
$ kubectl apply -f deployment-v5.yaml
deployment 이벤트를 상세적으로 보면 아래와 같으며 해석 해보면
최소 3개의 파드, 최대 6개의 파드가 있을수 있으니 새로운 파드를 하나 띄우고, 최소 3개의 파드니 기존 파드 2개를 죽이고 그 뒤는 점진적 배포를 진행한다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Fri, 26 May 2023 21:11:15 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=my-app
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 2 max unavailable, 1 max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-856cb86fb4 (5/5 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 32m deployment-controller Scaled up replica set my-app-5d6554bfbf to 5
Normal ScalingReplicaSet 50s deployment-controller Scaled up replica set my-app-856cb86fb4 to 1
Normal ScalingReplicaSet 50s deployment-controller Scaled down replica set my-app-5d6554bfbf to 3 from 5
Normal ScalingReplicaSet 50s deployment-controller Scaled up replica set my-app-856cb86fb4 to 3 from 1
Normal ScalingReplicaSet 40s deployment-controller Scaled down replica set my-app-5d6554bfbf to 2 from 3
Normal ScalingReplicaSet 40s deployment-controller Scaled up replica set my-app-856cb86fb4 to 4 from 3
Normal ScalingReplicaSet 39s deployment-controller Scaled down replica set my-app-5d6554bfbf to 1 from 2
Normal ScalingReplicaSet 39s deployment-controller Scaled up replica set my-app-856cb86fb4 to 5 from 4
Normal ScalingReplicaSet 39s deployment-controller Scaled down replica set my-app-5d6554bfbf to 0 from 1
위에서 확인한 새로운 template hash 번호로 파드가 뜬 것을 확인할 수 있다.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-856cb86fb4-q64gr 1/1 Running 0 4m12s
my-app-856cb86fb4-q7ltx 1/1 Running 0 4m23s
my-app-856cb86fb4-rhsnc 1/1 Running 0 4m23s
my-app-856cb86fb4-stsft 1/1 Running 0 4m23s
my-app-856cb86fb4-zmskv 1/1 Running 0 4m13s
정상적으로 서비스가 되는지 확인 하기 위해 포트 포워딩으로 pod 에 호출 해본다.
$ kubectl port-forward deployment/my-app 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
포트 포워드는 로드 밸런싱 되지 않으니 하나의 파드에만 호출 되며 변경된 이미지의 버전인 v2를 바라보는것을 확인 할 수 있다.
$ curl localhost:8080
Welcome to Version 2!
===== Host Info =====
HostIP: 10.100.2.27
HostName: my-app-856cb86fb4-q7ltx
$ curl localhost:8080
Welcome to Version 2!
===== Host Info =====
HostIP: 10.100.2.27
HostName: my-app-856cb86fb4-q7ltx
Welcome to Version 2!
$ curl localhost:8080
===== Host Info =====
HostIP: 10.100.2.27
HostName: my-app-856cb86fb4-q7ltx%
이제 실습을 종료하며 아래와 같이 label 이 my-app 인 모든 오브젝트를 제거한다.
$ kubectl delete all -l app=my-app
pod "my-app-856cb86fb4-q64gr" deleted
pod "my-app-856cb86fb4-q7ltx" deleted
pod "my-app-856cb86fb4-rhsnc" deleted
pod "my-app-856cb86fb4-stsft" deleted
pod "my-app-856cb86fb4-zmskv" deleted
deployment.apps "my-app" deleted
이제 Revision을 통해 롤백 하는 실습을 진행해보자!
그전에 관련 명령어를 보자!
배포 히스토리를 조회 하는 방법은 아래와 같으며
$ kubectl rollout history deployment/my-app
특정 배포 번호의 Template 확인을 위해서는 아래와 같이 --revision 옵션을 사용하면 된다.
$ kubectl rollout hisotry deployment/my-app --revision=[배포 버전]
롤백 방법은 아래와 같이 두가지가 있다.
아래와 같이 버전을 명시하여 롤백하는 방법이 있으며
$ kubectl rollout undo deployment/my-app --to-revision=[롤백 되길 원하는 배포 버전]
--to-revision 옵션을 주지 않으면 바로 직전으로 롤백된다.
$ kubectl rollout undo deployment/my-app
롤백 사유(배포 변경 사유)는 기본 설정된 값을 사용하며 만약 수정하고 싶다면 아래와 같이 annotate 를 이용하면 된다.
$ kubectl annotate deployment/my-app kubernetes.io/change-cause=[배포 설명]
명령어 학습을 했다면 실습을 진행해보자!
우선 이미지 1.0 으로 배포 후에 2.0 > 1.0 > 2.0 으로 배포 해보도록 한다.
아래와 같이 1.0 배포 파일을 생성한다.
# deployment-v6.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
annotations:
kubernetes.io/change-cause: "image version 1.0"
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용한다.
$ kubectl rollout status deployment/my-app
deployment "my-app" successfully rolled out
롤아웃 히스토리를 확인하면 아래와 같이 배포 버전 1이 생성 된것을 볼 수 있다.
REVISION은 배포 번호로 숫자가 크면 최신이며 CHANGE-CAUSE는 배포 설명이다.
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
1 image version 1.0
이제 이미지의 버전을 2.0으로 변경한다.
$ kubectl set image deployment/my-app my-app=yoonjeong/my-app:2.0
deployment.apps/my-app image updated
정상적으로 2.0으로 변경 되었는지 확인하면 정상적으로 변경 됨을 확인 할 수 있다.
$ kubectl get deployment/my-app -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-app 3/3 3 3 3m3s my-app yoonjeong/my-app:2.0 app=my-app
배포 히스토리를 보면 배포 버전 2가 새로 생성된것을 볼 수 있다. 그러나 배포 설명이 기본으로 yaml 파일에 'annotations' 부분에 정의한 내용으로 동일하게 나오니 배포 사유를 수정 해보도록 하자!
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
1 image version 1.0
2 image version 1.0
아래와 같이 annotate 명령어를 이용하여 배포 설명을 수정한다.
$ kubectl annotate deployment/my-app kubernetes.io/change-cause="image update to 2.0"
deployment.apps/my-app annotated
다시 히스토리를 확인하면 정상적으로 변경 됨을 확인 할 수 있다.
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
1 image version 1.0
2 image update to 2.0
히스토리 상세적으로 보기 위해 --revision 으로 원하는 버전을 입력하여 확인한다.
내용중 pod-template-hash 번호와 현재 파드명의 hash 번호가 일치하여 2버전이 정상 배포됨을 확인 할 수 있다.
% kubectl rollout history deployment/my-app --revision=2
deployment.apps/my-app with revision #2
Pod Template:
Labels: app=my-app
pod-template-hash=856cb86fb4
Annotations: kubernetes.io/change-cause: image update to 2.0
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-856cb86fb4-dq5vv 1/1 Running 0 4m11s
my-app-856cb86fb4-m7l7n 1/1 Running 0 4m11s
my-app-856cb86fb4-zx8tt 1/1 Running 0 4m1s
이제 2.0 > 1.0 으로 롤백을 진행해보자!
아래와 같이 입력하면 revision 을 따로 입력하지 않았기에 바로 직전 배포 버전인 1로 롤백을 진행한다.
$ kubectl rollout undo deployment/my-app
deployment.apps/my-app rolled back
배포 상태 확인시 완료 됐다는 메세지가 나오며
$ kubectl rollout status deployment/my-app
deployment "my-app" successfully rolled out
히스토리를 보면 롤백 되고 배포 버전 1이였던것이 3으로 변경 되었다.
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
2 image update to 2.0
3 image version 1.0
롤백 사유를 입력하기 위해 annotate 명령어를 통해 변경 한다.
$ kubectl annotate deployment/my-app kubernetes.io/change-cause="rollback for some bugs"
deployment.apps/my-app annotated
다시 확인해보면 정상적으로 설명이 변경 되었다!
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
2 image update to 2.0
3 rollback for some bugs
이제 배포 버전 상세 설명의 pod-hash 번호와 현재 파드의 명이 일치 하는지 보면 정상적으로 버전 3으로 배포 됨을 확인할 수 있다.
$ kubectl rollout history deployment/my-app --revision=3
deployment.apps/my-app with revision #3
Pod Template:
Labels: app=my-app
pod-template-hash=5d6554bfbf
Annotations: kubernetes.io/change-cause: rollback for some bugs
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-5d6554bfbf-72p2s 1/1 Running 0 2m33s
my-app-5d6554bfbf-gh26m 1/1 Running 0 2m33s
my-app-5d6554bfbf-wq2tr 1/1 Running 0 2m24s
이제 버전명을 명시하여 배포 버전 2(image 2.0) 롤백을 진행한다.
$ kubectl rollout undo deployment/my-app --to-revision=2
deployment.apps/my-app rolled back
배포 히스토리를 보면 정상적으로 롤백 되고 revision 번호가 4로 새로 부여된것을 확인할 수 있다.
$ kubectl rollout history deployment/my-app
deployment.apps/my-app
REVISION CHANGE-CAUSE
3 rollback for some bugs
4 image update to 2.0
이제 실습을 종료하며 모든 오브젝트를 제거한다.
$ kubectl delete all -l app=my-app
pod "my-app-856cb86fb4-97rh5" deleted
pod "my-app-856cb86fb4-h9vvd" deleted
pod "my-app-856cb86fb4-rjb86" deleted
deployment.apps "my-app" deleted
끝!
'ETC' 카테고리의 다른 글
[kubernetes] Service - NodePort로 Pod 노출 실습 (0) | 2023.05.28 |
---|---|
[kubernetes] Service 소개 및 ClusterIP로 Pod 노출 실습 (1) | 2023.05.27 |
[kubernetes] Deployment 란? (0) | 2023.05.20 |
[kubernetes] ReplicaSet 실습 - pod 수 조정, 롤백 (0) | 2023.05.20 |
[kubernetes] ReplicaSet 실습 - pod 종료, template 수정 (1) | 2023.05.20 |