[Kubernetes] Deployments (디플로이먼트)
✔️ Deployment
Deployment는 ReplicaSet의 상위 오브젝트로 Deployment를 생성하면 해당 Deployment에 대응하는 ReplicaSet도 함께 생성된다. 따라서 Deployment를 사용하면 Pod, ReplicaSet을 직접 생성할 필요가 없다.
✔️ Deployment 사용 이유 ?
그렇다면 쿠버네티스는 ReplicaSet이 아닌 상위 개념인 Deployment를 사용해 간접적으로 ReplicaSet을 생성하는 것일까 ?
Deployment를 사용하는 핵심 이유는 어플리케이션의 업데이트와 배포를 더욱 편하게 만들기 위해서이다.
Deployment는 이름처럼 컨테이너 어플리케이션을 배포하고 관리하는 역할을 담당한다.
예를 들어 어플리케이션의 버전 업데이트를 할 때 ReplicaSet의 변경 사항을 저장하는 Revision을 남겨 Rollback를 가능하게 하고 무중단 서비스를 위해 Pod의 RollingUpdate 전략을 지정할 수도 있다.
vagrant@k8s-node1 ~ kubectl api-resources | grep deployment
deployments deploy apps/v1 true Deployment
shortname은 deploy
이며 apps
그룹이며 NS를 사용하고 kind는 Deployment
이다.
vagrant@k8s-node1 ~ kubectl explain deploy.spec
rs.spec
과 유사하다.
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
ports:
- containerPort: 8080
vagrant@k8s-node1 ~/deploy kubectl create -f myweb-deploy.yaml
deployment.apps/myweb-deploy created
vagrant@k8s-node1 ~/deploy kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myweb-deploy 3/3 3 3 6s
vagrant@k8s-node1 ~/deploy kubectl get rs
NAME DESIRED CURRENT READY AGE
myweb-deploy-7d649cccb8 3 3 3 35s
vagrant@k8s-node1 ~/deploy kubectl get po
NAME READY STATUS RESTARTS AGE
myweb-deploy-7d649cccb8-476t8 1/1 Running 0 37s
myweb-deploy-7d649cccb8-jbfll 1/1 Running 0 37s
myweb-deploy-7d649cccb8-lnlnp 1/1 Running 0 37s
Deployment
라는 리소스가 RS를 만들고 RS가 파드를 만든다.
우리는 Deploy
만 선언했으나 알아서 RS도 만들고 파드도 만든다.
그래서 쿠버네티스에서는 파드를 만들때 Deployment
를 사용하는 것이 일반적이다.
Deployment
도 결국 복제본을 만들기 때문에 기본적인 기능은 RS와 유사하다.
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
myweb-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
vagrant@k8s-node1 ~/deploy kubectl get deploy,rs,po,svc,ep
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myweb-deploy 3/3 3 3 19s
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-deploy-7d649cccb8 3 3 3 19s
NAME READY STATUS RESTARTS AGE
pod/myweb-deploy-7d649cccb8-2g5zj 1/1 Running 0 19s
pod/myweb-deploy-7d649cccb8-89qf9 1/1 Running 0 19s
pod/myweb-deploy-7d649cccb8-cs2b9 1/1 Running 0 19s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 42h
service/myweb-svc-lb LoadBalancer 10.233.61.172 192.168.100.240 80:32154/TCP 19s
NAME ENDPOINTS AGE
endpoints/k8s-sigs.io-nfs-subdir-external-provisioner <none> 26h
endpoints/kubernetes 192.168.100.100:6443 42h
endpoints/myweb-svc 10.233.90.79:8080,10.233.90.83:8080,10.233.92.120:8080 + 3 more... 5h44m
endpoints/myweb-svc-lb 10.233.90.79:8080,10.233.90.83:8080,10.233.92.120:8080 + 3 more... 19s
✔️ Rollout
vagrant@k8s-node1 ~/deploy kubectl rollout
Manage the rollout of a resource.
Valid resource types include:
* deployments
* daemonsets
* statefulsets
Available Commands:
history View rollout history
pause Mark the provided resource as paused
restart Restart a resource
resume Resume a paused resource
status Show the status of the rollout
undo Undo a previous rollout
rollout
으로 확인할 수 있는 리소스 타입은 deployments
, daemonsets
, statefulsets
이다.
가능한 명령은 history
, pause
, restart
, resume
, status
, undo
이다.
✔️ status
vagrant@k8s-node1 ~/deploy kubectl rollout status deploy myweb-deploy
deployment "myweb-deploy" successfully rolled out
status
로 배포가 완료된 상태임을 확인할 수 있다.
✔️ history
vagrant@k8s-node1 ~/deploy kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
1 <none>
history 정보를 볼 수 있다.
kubectl rollout history deployment/nginx-deployment --revision=2
상세 정보를 보려면 --revision
옵션으로 번호를 지정하면 된다.
📌 Tip : 다양한 이미지 교체 방법replace
, apply
, edit
, patch
+ set
vagrant@k8s-node1 ~/deploy kubectl set
Configure application resources.
These commands help you make changes to existing application resources.
Available Commands:
env Update environment variables on a pod template
image Update the image of a pod template
resources Update resource requests/limits on objects with pod templates
selector Set the selector on a resource
serviceaccount Update the service account of a resource
subject Update the user, group, or service account in a role binding or cluster role binding
set
을 사용한 이미지 업데이트 방법
vagrant@k8s-node1 ~ kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/myweb-deploy image updated
vagrant@k8s-node1 ~ kubectl rollout status deploy myweb-deploy
...
deployment "myweb-deploy" successfully rolled out
rollout
과정을 확인할 수 있다.
===Version 2.0===
Hello World!
myweb-deploy-59b4f448d5-fdq2n
모두 2.0으로 rollout
되었다.
vagrant@k8s-node1 ~ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
다음과 같이 변경의 사유가 출력되는데 이는 set
명령 실행 시 --record
옵션을 붙일때만 출력된다. --record
옵션을 붙이지 않으면 None
이 출력된다.
✔️ undo
vagrant@k8s-node1 ~ kubectl rollout undo deploy myweb-deploy
deployment.apps/myweb-deploy rolled back
vagrant@k8s-node1 ~ kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
2 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
3 <none>
2.0에서 1.0으로 undo
, 되돌리는 것이지만 표기에서는 3.0으로 표기된다.
즉 다시 되돌아간 상태를 1.0이 아닌 3.0으로 본다.
===Version 1.0===
Hello World!
myweb-deploy-7d649cccb8-9r7sj
버전이 변경되었다.
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-deploy-59b4f448d5 0 0 0 10m
replicaset.apps/myweb-deploy-7d649cccb8 3 3 3 25m
rollback
을 위해 1.0 버전인 myweb-deploy-7d649cccb8
를 지우지 않는다. DESIRED
만 0으로 설정해놓는다.
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-deploy-59b4f448d5 3 3 3 14m
replicaset.apps/myweb-deploy-7d649cccb8 0 0 0 29m
여기서 다시 2.0 버전으로 rollout
을 실행하면 myweb-deploy-59b4f448d5
의 DESIRED
와 CURRENT
가 3 / 3으로 변경된다. 그리고 history를 살펴보면 4.0으로 표기된다.
vagrant@k8s-node1 ~/deploy kubectl apply -f myweb-deploy.yaml --record
Flag --record has been deprecated, --record will be removed in the future
Warning: resource deployments/myweb-deploy is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
deployment.apps/myweb-deploy configured
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-deploy-59b4f448d5 0 0 0 17m
replicaset.apps/myweb-deploy-744cb77cb6 3 3 3 16s
replicaset.apps/myweb-deploy-7d649cccb8 0 0 0 31m
myweb-deploy.yaml
에서 이미지를 v1.0 → v3.0으로 수정한뒤 apply
명령으로 변경하면 3.0 이므로 새로운 myweb-deploy-744cb77cb6
가 생성된다.
===Version 3.0===
Hello World!
myweb-deploy-744cb77cb6-6bcfk
트래픽을 확인하면 모두 3.0 버전으로 rollout
됐음을 확인할 수 있다.
vagrant@k8s-node1 ~/deploy kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
3 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v1.0 --record=true
4 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
그리고 history를 확인하면 5.0으로 표기된다.
kubectl rollout undo deployment/nginx-deployment --to-revision=2
--to-revision
옵션으로 번호를 지정하면 해당 버전으로 undo
한다.
번호를 지정하지 않으면 바로 직전 버전으로 undo
한다.
📌 annotation
활용하기
set
명령을 사용하면 이미지가 어떻게 변경됐는지 알수 있지만 apply
명령은 어떻게 변경됐는지 알기 힘들다.
파일을 수정할 때는 다른 방법을 사용하는 것을 권장한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
annotations:
kubernetes.io/change-casue: "Change Go Myweb version from 3 to 4"
...
다음과 같이 annotations
을 지정한다.
vagrant@k8s-node1 ~/deploy kubectl apply -f myweb-deploy.yaml
deployment.apps/myweb-deploy configured
vagrant@k8s-node1 ~/deploy kubectl rollout history deploy myweb-deploy
deployment.apps/myweb-deploy
REVISION CHANGE-CAUSE
3 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v1.0 --record=true
6 kubectl set image deployments myweb-deploy myweb=ghcr.io/c1t1d0s7/go-myweb:v2.0 --record=true
7 kubectl apply --filename=myweb-deploy.yaml --record=true
8 Change Go Myweb version from 3 to 4
annotations
을 지정했을 때는 apply
명령에 --record
옵션을 붙이지 않는다.Change Go Myweb version from 3 to 4
해당 문구가 변경 사유에 출력된다.
✔️ Max Surge & Max Unavailable
maxSurge
: 롤링 업데이트 도중 전체 파드의 개수가Deploy
의replicas
값보다 얼마나 더 많이 존재할 수 있는지 설정한다.maxUnavailable
: 롤링 업데이트 도중 사용 불가능한 상태가 되는 파드의 최대 개수를 설정한다.
vagrant@k8s-node1 ~/deploy kubectl explain deploy.spec.strategy
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.
vagrant@k8s-node1 ~/deploy kubectl explain deploy.spec.strategy.rollingUpdate
FIELDS:
maxSurge <string>
maxUnavailable <string>
maxSurge
와 maxUnavailable
는 absolute number 또는 percentage로 표기할 수 있다.
기본 maxSurge
, maxUnavailable
는 모두 25%이다.
만약 Deploy의 replicas가 3개라면 3 * 0.25 = 0.75의 올림 수인 1개가 된다.
myweb-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
annotations:
kubernetes.io/change-casue: "Change Go Myweb version from 3 to 4"
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
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
- Deployment의 replicas에 설정된 파드 개수 : 4개
maxUnavailable
: 1 (전체 파드 개수가 3개 이하로 떨어지지 않음)maxSurge
: 2 (전체 파드 개수는 4 + 2 = 6개를 넘을 수 없음)
- t0 : 롤링 업데이트 전 v1, 4개의 포드가 있다.
- t1 :
maxUnavailable
의 값이 1이기 때문에 최대 1개의 파드까지는 사용 불가능한 상태가 허용된다. 따라서 적어도 4 - 1 = 3개의 파드는 실행 중이어야 하며, 이에 따라 1개의 v1 파드가 삭제된다. - t2 :
maxSurge
의 값이 2이기 때문에 파드의 개수는 4 + 2 = 6개까지 존재할 수 있다. 따라서 t1에서 v1 파드가 삭제됨과 동시에, v2 버전의 파드가 전체 파드 개수의 상한선까지 생성된다. 이때, v1 파드가 아직 3개 존재하기 때문에 새롭게 생성될 수 있는 파드의 개수는 6 - 3 = 3개이며, 이에 따라 v2 파드는 3개만 생성된다. - t3 : 전체 파드의 최소 개수인 3개를 벗어나지 않는 선에서 v1 파드를 삭제한다. 남아있는 v1 파드 3개를 모두 삭제해도 최소 개수를 벗어나지 않기 때문에, v1 파드를 모두 삭제한다.
- t4 : 원래 replicas에 설정된 파드 개수만큼 v2 파드르 생성해 롤링 업데이트를 마무리한다.
📌 그 밖의 다른 필드
deploy.spec.minReadySeconds
: Ready
상태가 될 때까지 조금 기다린다.
기본 값은 0이다. RS에 의해 파드가 만들어질 때 Ready 상태가 되어야 다음 파드를 만들 수 있는데 값을 60초라고 지정하면 Ready 상태가 될 때까지 최대 60초를 기다린다.
프로브를 사용하면 minReadySeconds
는 사용할 필요가 없으면 프로브를 사용할 수 없을 때 대신해서 사용한다.
deploy.spec.revisionHistoryLimit
: rollback
을 허용하기 위해 보유할 이전 ReplicaSet
의 수다.
rollout history
는 기본적으로 10개까지만 나온다.