📌Index
- Deployments란?
- Deployment Rollback 및 Rollout 기록 조회
- Deployment 업데이트
✔️ Deployments란?
디플로이먼트(deployment)란 K8s에서 애플리케이션 단위를 관리하는 Controller이며,
Kubernetes의 최소 유닛인 Pod에 대한 기준 spec을 정의한 Object이다.
Kubernetes에서는 각 Object를 독립적으로 생성하기 보다는
Deployment를 통해서 생성하는 것을 권장하고 있으며, Pod와 ReplicaSet의 기준 정보를 지정할 수 있다.
ReplicaSets에 대한 자세한 설명은 ReplicationController와 ReplicaSets에서 확인할 수 있다.
이러한 Deployment는
- Pod의 scale in / out 되는 기준을 정의한다.
- Pod의 배포되고 update되는 모든 버전을 추적할 수 있다.
- 배포된 Pod에 대한 rollback을 수행할 수 있다.
즉, 개념적으로 Deployment = ReplicaSet + Pod + history이며 ReplicaSet 을 만드는 것보다
더 윗 단계의 선언(추상표현)이다.
정리하면 Deployment가 ReplicaSets을 만들고, ReplicaSets이 Pod를 만든다.
즉, Deployment만 선언하면 ReplicaSets부터 Pod까지 만들어진다.
이러한 이유로 ReplicaSets를 직접 생성하는 것보다는 일반적으로 Deployment를 많이 사용한다.
리소스 확인
$ kubectl api-resources| grep deployment
deployments deploy apps/v1 true Deployment
리소스 정의 방법 확인
$ kubectl explain deployment.spec
필수 Field
- Deployments의 설정 정보 (apiVersion, kind, metadata)
- ReplicaSets의 설정 정보 (replicas, selector)
- Pod의 설정 정보 (template)
strategy
- deployment strategy : 이전 파드를 새로운 파드로 대체하는 전략을 명시
deploy.spec.strategy
$ kubectl explain deploy.spec.strategy
KIND: Deployment
VERSION: apps/v1
RESOURCE: strategy <Object>
DESCRIPTION:
The deployment strategy to use to replace existing pods with new ones.
DeploymentStrategy describes how to replace existing pods with new ones.
FIELDS:
rollingUpdate <Object>
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.
type <string>
Type of deployment. Can be "Recreate" or "RollingUpdate". Default is
RollingUpdate.
Recreate
: 모든 것을 삭제하고 다시 시작한다.rollingUpdate
(default) : 한번에 n개씩 Pod를 순차적으로 업데이트한다. (무중단 배포)maxSurge
: rolling update 중 deployment에 설정되어 있는 기본 pod개수보다 여분의 pod가 몇개가 더 추가될 수 있는지를 설정 (default는 25%)
maxUnavailable
: 업데이트하는 동안 몇 개의 pod가 이용 불가능하게 되어도 되는지를 설정- rolling update 중 unavailable 상태인 Pod의 최대 개수(default는 25%)
- maxSurge와 maxUnavailable 값이 동시에 0이 될 수 없다.
$ kubectl explain deploy.spec.strategy.rollingUpdate
KIND: Deployment
VERSION: apps/v1
RESOURCE: rollingUpdate <Object>
DESCRIPTION:
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.
Spec to control the desired behavior of rolling update.
FIELDS:
maxSurge <string>
The maximum number of pods that can be scheduled above the desired number
of pods. Value can be an absolute number (ex: 5) or a percentage of desired
pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number
is calculated from percentage by rounding up. Defaults to 25%. Example:
when this is set to 30%, the new ReplicaSet can be scaled up immediately
when the rolling update starts, such that the total number of old and new
pods do not exceed 130% of desired pods. Once old pods have been killed,
new ReplicaSet can be scaled up further, ensuring that total number of pods
running at any time during the update is at most 130% of desired pods.
maxUnavailable <string>
The maximum number of pods that can be unavailable during the update. Value
can be an absolute number (ex: 5) or a percentage of desired pods (ex:
10%). Absolute number is calculated from percentage by rounding down. This
can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set
to 30%, the old ReplicaSet can be scaled down to 70% of desired pods
immediately when the rolling update starts. Once new pods are ready, old
ReplicaSet can be scaled down further, followed by scaling up the new
ReplicaSet, ensuring that the total number of pods available at all times
during the update is at least 70% of desired pods.
☁️ 참고
데몬셋도 updateStrategy가 존재한다.
설정 방법은 Deployment의 strategy와 동일하다.
단, 데몬셋은 노드당 1개씩 존재하기 때문에, 중간에 다운타임이 발생할 수 있다.
$ kubectl explain ds.spec.updateStrategy
KIND: DaemonSet
VERSION: apps/v1
RESOURCE: updateStrategy <Object>
DESCRIPTION:
An update strategy to replace existing DaemonSet pods with new pods.
DaemonSetUpdateStrategy is a struct used to control the update strategy for
a DaemonSet.
FIELDS:
rollingUpdate <Object>
Rolling update config params. Present only if type = "RollingUpdate".
type <string>
Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is
RollingUpdate.
minReadySeconds
pod의 status가 ready가 될 때까지의 최소 대기 시간이다. (default는 0)
pod가 실행된 후, .spec.minReadySeconds
에 설정된 시간동안은 트래픽을 받지 않는다.
그러나 readinessProbe가 세팅되어있으면,
readinessProbe가 완료된 후 minReadySeconds는 무시되기 때문에,
minReadySeconds 보다는 readinessProbe를 사용하는 것을 더 권장한다.
$ kubectl explain deploy.spec.minReadySeconds
KIND: Deployment
VERSION: apps/v1
FIELD: minReadySeconds <integer>
DESCRIPTION:
Minimum number of seconds for which a newly created pod should be ready
without any of its container crashing, for it to be considered available.
Defaults to 0 (pod will be considered available as soon as it is ready)
revisionHistoryLimit
rollback을 위해 보유할 이전 버전 ReplicaSets(history)의 최대 개수이다.
default는 10이고, history는 최대 10개까지 남아있을 수 있다.
$ kubectl explain deploy.spec.revisionHistoryLimit
KIND: Deployment
VERSION: apps/v1
FIELD: revisionHistoryLimit <integer>
DESCRIPTION:
The number of old ReplicaSets to retain to allow rollback. This is a
pointer to distinguish between explicit zero and not specified. Defaults to
10.
💻 실습 : Deployment + Service(LB) 생성하기
myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
spec:
replicas: 3 #RS 설
selector:
matchLabels:
app: web
template: #Pod 설정
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
myweb-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
$ kubectl create -f myweb-deploy.yaml -f myweb-svc-lb.yaml
Deployment, ReplicatSets, Pod 그리고 Service와 Enpoints 까지 정상적으로 생성된 것을 확인할 수 있다.
$ kubectl get deploy,rs,po,svc,ep
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myweb-deploy 3/3 3 3 8h
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-deploy-5d9fc76b4d 0 0 0 8h
replicaset.apps/myweb-deploy-7857988545 0 0 0 8h
replicaset.apps/myweb-deploy-7d649cccb8 3 3 3 7h58m
NAME READY STATUS RESTARTS AGE
pod/myweb-deploy-7d649cccb8-mjqkd 1/1 Running 1 (82m ago) 7h58m
pod/myweb-deploy-7d649cccb8-qt8rt 1/1 Running 1 (82m ago) 7h58m
pod/myweb-deploy-7d649cccb8-xn7d9 1/1 Running 1 (81m ago) 7h58m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 4d9h
service/myweb-svc-lb LoadBalancer 10.233.8.211 192.168.100.240 80:30786/TCP 6s
NAME ENDPOINTS AGE
endpoints/myweb-svc-lb 10.233.90.140:8080,10.233.92.55:8080,10.233.96.156:8080 6s
✔️ Deployment Rollback 및 Rollout 기록 조회
$ kubectl rollout [커맨드] deploy [디플로이먼트 이름]
Command
history
: rollout history를 확인pause
: 리소스를 일시중지restart
: 리소스를 재시작resume
: 중지된 리소스를 다시 시작status
: deployment의 rollout 상태를 확인- 변환하는 과정을 확인할 수 있다.
undo
: deployment를 rollback- 이전 상태로 되돌아가도 버전(revision)은 업그레이드한다.
--to-revision
으로 버전을 지정 가능하다.- 버전(revision)을 지정하지 않으면 바로 이전 단계로 되돌아간다.
예시
deployment 상태 확인 : status
$ kubectl rollout status deploy myweb-deploy
deployment "myweb-deploy" successfully rolled out
deployment history 및 revision 확인 : history
$ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
1 <none>
deployment 버전 되돌리기 : undo
$ kubectl rollout undo deploy myweb-deploy --to-revision=2
✔️ Deployment 업데이트
$ kubectl set image deployment [디플로이먼트이름] [컨테이너이름]=[이미지]:[버전]
$ kubectl set image deployment/[디플로이먼트이름] [컨테이너이름]=[이미지]:[버전]
이미지를 수정하는 방법에는 patch, apply, edit 등등 여러가지 방법이 있지만,
deployment는 kubectl set image
명령어를 사용할 수 있다.
예시
$ kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record
kubectl rollout history
명령 시 출력되는 CHANGE-CAUSE
(사유)는 --record
옵션을 사용한 경우만 기록된다.
--record
옵션을 사용하지 않으면 <none>
으로 기록된다.
CHANGE-CAUSE는 나중에 추적할 때에 필요할 수 있으므로 --record
옵션을 붙여주는 것이 좋다.
단, 파일 내용을 확인하지는 못하기 때문에, 파일을 수정하는 경우는 annotaions을 사용하는 것을 권장한다.
annotation 사용 예시는 뒤의 실습2 에서 확인할 수 있다.
$ kubectl rollout history -f myweb-deploy.yaml
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
5 kubectl apply --filename=myweb-deploy.yaml --record=true
6 Change Go Myweb version from 3 to 4
--revision
옵션을 사용하면 상세정보를 볼 수 있다
💻 실습 1 : Deployment의 롤백, 롤아웃, 업데이트
myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb:v1.0
ports:
- containerPort: 8080
$ kubectl create -f myweb-deploy.yaml -f myweb-svc-lb.yaml
$ curl 192.168.100.240
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 61 100 61 0
0 15250 0 --:--:-- --:--:-- --:--:-- 15250
===Version 1.0===
Hello World!
myweb-deploy-7d649cccb8-9hqj6 Left Speed
myweb-deploy의 이미지를 변경(업데이트)해보자.
$ kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record
kubectl rollout status
명령어를 통해 과정을 확인할 수 있다.
$ kubectl rollout status deploy myweb-deploy
Waiting for deployment "myweb-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
버전이 2.0으로 업데이트 되고,
$ curl 192.168.100.240
===Version 2.0===
Hello World!
myweb-deploy-7d649cccb8-9hqj6 Left Speed
history를 확인할 수 있다.
$ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
myweb-deploy를 롤백한 뒤 history를 살펴보면,
원래 상태(이전)으로 돌아갔지만 REVISION이 증가한 것을 확인할 수 있다.
$ kubectl rollout undo deploy myweb-deploy
deployment.apps/myweb-deploy rolled back
$ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
2 kubectl set image deployment myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
3 <none>
이번에는 set image 대신, yaml 파일을 수정하고apply
명령어를 통해 이미지를 3.0
으로 업데이트해보자.
myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb:v3.0 #버전 수정
ports:
- containerPort: 8080
$ kubectl apply -f myweb-deploy.yaml --record
$ curl 192.168.100.240
===Version 3.0===
Hello World!
myweb-deploy-744cb77cb6-ct27v
이제 history를 확인해보면, CHANGE-CAUSE에 명령어가 저장된 것을 확인할 수 있다.
$ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
2 kubectl set image deployment myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
3 <none>
4 kubectl apply --filename=myweb-deploy.yaml --record=true
kubectl set image
명령을 통해 이미지를 변경했을 때에는 변경된 내용을 history를 보고 알 수 있지만,
파일 내용을 수정하고 kubectl apply
하게 되면 history를 보고 이미지를 무엇으로 바꿨는지를 알 수 없다.
따라서 파일을 수정할 때는 annotations를 사용하는 것을 권장한다.
💻 실습 2 : Annotation을 활용한 버전 업그레이드
annotation을 설정한 뒤, 이미지 버전을 업그레이드하고 history를 확인해보자.
myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
annotations: #annotaion
kubernetes.io/change-cause: "Change Go Myweb version from 3 to 4"
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb:v4.0 #버전 수정
ports:
- containerPort: 8080
단, annotaion을 사용하는 경우는 --record
옵션을 사용하지 말아야한다.
$ kubectl apply -f myweb-deploy.yaml
$ curl 192.168.100.240
===Version 4.0===
Hello World!
myweb-deploy-54948b568c-vvb5c
history를 확인해보면, annotation이 CHANGE-CAUSE로 기록된 것을 확인할 수 있다.
$ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
2 kubectl set image deployment myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
3 <none>
6 kubectl apply --filename=myweb-deploy.yaml --record=true
7 Change Go Myweb version from 3 to 4
참고