디플로이먼트(Deployment) 는 파드와 레플리카셋(ReplicaSet)에 대한 선언적 업데이트를 제공한다.
디플로이먼트에서 의도하는 상태를 설명
디플로이먼트 컨트롤러(Controller)는 현재 상태에서 의도하는 상태로 비율을 조정하며 변경한다.
디플로이먼트의 일반적인 유스케이스
레플리카셋을 롤아웃 할 디플로이먼트 생성.
레플리카셋은 백그라운드에서 파드를 생성한다.
롤아웃 상태를 체크해서 성공 여부를 확인한다.
디플로이먼트의 PodTemplateSpec을 업데이트해서 파드의 새로운 상태를 선언한다.
새 레플리카셋이 생성되면, 디플로이먼트는 파드를 기존 레플리카셋에서 새로운 레플리카셋으로 속도를 제어하며 이동하는 것을 관리한다.
각각의 새로운 레플리카셋은 디플로이먼트의 수정 버전에 따라 업데이트한다.
디플로이먼트의 현재 상태가 안정적이지 않은 경우 디플로이먼트의 이전 버전으로 롤백한다.
더 많은 로드를 위해 디플로이먼트의 스케일 업.
롤아웃이 막혀있는지를 나타내는 디플로이먼트 상태를 이용.
더 이상 필요 없는 이전 레플리카셋 정리.
.metadata.name
필드에 따라 nginx-deployment 이름으로 디플로이먼트가 생성된다.
.spec.replicas
필드에 따라 디플로이먼트는 3개의 레플리카 파드를 생성한다.
.spec.selector
필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다.
이 사례에서는 파드 템플릿에 정의된 레이블(app: nginx)을 선택한다.
그러나 파드 템플릿 자체의 규칙이 만족되는 한, 보다 정교한 선택 규칙의 적용이 가능하다.
template
필드에는 다음 하위 필드가 포함되어 있다.
파드는 .metadata.labels
필드를 사용해서 app: nginx
라는 레이블을 붙인다.
파드 템플릿의 사양 또는 .template.spec 필드는 파드가 도커 허브의 nginx 1.14.2 버전 이미지를 실행하는 nginx 컨테이너 1개를 실행하는 것을 나타낸다.
컨테이너 1개를 생성하고, .spec.template.spec.containers[0].name
필드를 사용해서 nginx 이름을 붙인다.
- .spec.selector.matchLabels
필드는{key,value}
의 쌍으로 매핑되어 있다.
matchLabels
에 매핑된 단일{key,value}
은matchExpressions
의 요소에 해당
- key 필드는 "key"에 그리고 operator는 "In"에 대응
- value 배열은 "value"만 포함
- 매칭을 위해서는
matchLabels
와matchExpressions
의 모든 요건이 충족되어야 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
$ kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
> kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
deployment.apps/nginx-deployment created
$ kubectl get deployments
> kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 2m8s
web-deploy 3/3 3 3 6d
NAME
READY
는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
UP-TO-DATE
AVAILABLE
AGE
디플로이먼트에서 3개의 레플리카가 생성되었고, 모든 레플리카는 최신 상태(최신 파드 템플릿을 포함)이며 사용 가능한 것을 알 수 있다.
$ kubectl rollout status deployment/nginx-deployment
> kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
$ kubectl get rs
> kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-7fb96c846b 3 3 3 9m19s
web-deploy-5d9f7ffff8 3 3 3 6d
NAME
DESIRED
디플로이먼트의 생성 시 정의된 의도한 애플리케이션 레플리카 의 수를 표시한다.
의도한 상태 이다.
CURRENT
는 현재 실행 중인 레플리카의 수를 표시한다.
READY
는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
AGE
는 애플리케이션의 실행된 시간을 표시한다.
레플리카셋의 이름은 항상
[DEPLOYMENT-NAME]-[HASH]
형식으로 된 것을 알 수 있다. HASH 문자열은 레플리카셋의 pod-template-hash 레이블과 같다.
$ kubectl get pods --show-labels
> kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
busybox 0/1 Error 0 6d run=busybox
nginx-deployment-7fb96c846b-8jqsn 1/1 Running 0 12m app=nginx,pod-template-hash=7fb96c846b
nginx-deployment-7fb96c846b-q7tgq 1/1 Running 0 12m app=nginx,pod-template-hash=7fb96c846b
nginx-deployment-7fb96c846b-xk2hf 1/1 Running 0 12m app=nginx,pod-template-hash=7fb96c846b
web-deploy-5d9f7ffff8-hz82f 1/1 Running 2 (12m ago) 6d app=web,pod-template-hash=5d9f7ffff8
web-deploy-5d9f7ffff8-r2q7x 1/1 Running 2 (12m ago) 6d app=web,pod-template-hash=5d9f7ffff8
web-deploy-5d9f7ffff8-tkjx4 1/1 Running 2 (12m ago) 6d app=web,pod-template-hash=5d9f7ffff8
pod-template-hash 레이블
디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리카셋에 추가된다.
디플로이먼트의 자식 레플리카셋이 겹치지 않도록 보장한다.
$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
or
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
> kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
deployment.apps/nginx-deployment image updated
디플로이먼트를 edit 해서.
spec.template.spec.containers[0].image
를nginx:1.14.2
에서nginx:1.16.1
로 변경
$ kubectl edit deployment/nginx-deployment
$ kubectl rollout status deployment/nginx-deployment
> kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
> kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 43m
web-deploy 3/3 3 3 6d1h
> kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-68fc675d59 3 3 3 7m31s
nginx-deployment-7fb96c846b 0 0 0 43m
web-deploy-5d9f7ffff8 3 3 3 6d1h
$ kubectl get pods
> kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 0/1 Error 0 6d
nginx-deployment-68fc675d59-mbm4h 1/1 Running 0 12m
nginx-deployment-68fc675d59-xr4x9 1/1 Running 0 12m
nginx-deployment-68fc675d59-xxtm4 1/1 Running 0 12m
web-deploy-5d9f7ffff8-hz82f 1/1 Running 2 (48m ago) 6d1h
web-deploy-5d9f7ffff8-r2q7x 1/1 Running 2 (48m ago) 6d1h
web-deploy-5d9f7ffff8-tkjx4 1/1 Running 2 (48m ago) 6d1h
다음에 이러한 파드를 업데이트 하려면 디플로이먼트의 파드 템플릿만 다시 업데이트 하면 된다.
디플로이먼트는 업데이트되는 동안 일정한 수의 파드만 중단되도록 보장한다.
디플로이먼트는 의도한 파드 수 보다 더 많이 생성되는 파드의 수를 제한한다.
예를 들어, 위 디플로이먼트를 자세히 살펴보면 먼저 새로운 파드를 생성한 다음, 이전 파드를 삭제하고, 또 다른 새로운 파드를 만든 것을 볼 수 있다.
충분한 수의 새로운 파드가 나올 때까지 이전 파드를 죽이지 않으며, 충분한 수의 이전 파드들이 죽기 전까지 새로운 파드를 만들지 않는다.
이것은 최소 3개의 파드를 사용할 수 있게 하고, 최대 4개의 파드를 사용할 수 있게 한다. 디플로이먼트의 레플리카 크기가 4인 경우, 파드 숫자는 3개에서 5개 사이이다.
$ kubectl describe deployments
> kubectl describe deployments
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 19 Jan 2023 16:59:47 +0900
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
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=nginx
Containers:
nginx:
Image: nginx:1.16.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-68fc675d59 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 53m deployment-controller Scaled up replica set nginx-deployment-7fb96c846b to 3
Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 1
Normal ScalingReplicaSet 17m deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 2 from 3
Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 2 from 1
Normal ScalingReplicaSet 17m deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 1 from 2
Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 3 from 2
Normal ScalingReplicaSet 17m deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 0 from 1
디플로이먼트 컨트롤러는 각 시간마다 새로운 디플로이먼트에서 레플리카셋이 의도한 파드를 생성하고 띄우는 것을 주시한다.
만약 디플로이먼트가 업데이트되면, 기존 레플리카셋에서 .spec.selector
레이블과 일치하는 파드를 컨트롤 하지만, 템플릿과 .spec.template
이 불일치하면 스케일 다운이 된다.
결국 새로운 레플리카셋은 .spec.replicas
로 스케일되고, 모든 기존 레플리카셋은 0개로 스케일된다.
만약 기존 롤아웃이 진행되는 중에 디플로이먼트를 업데이트하는 경우 디플로이먼트가 업데이트에 따라 새 레플리카셋을 생성하고, 스케일 업하기 시작한다.
이전에 스케일 업 하던 레플리카셋에 롤오버 한다.
예를 들어 디플로이먼트로 nginx:1.14.2
레플리카를 5개 생성을 한다.
하지만 nginx:1.14.2 레플리카 3개가 생성되었을 때 디플로이먼트를 업데이트해서 nginx:1.16.1 레플리카 5개를 생성하도록 업데이트를 한다고 가정한다.
이 경우 디플로이먼트는 즉시 생성된 3개의 nginx:1.14.2 파드 3개를 죽이기 시작하고 nginx:1.16.1 파드를 생성하기 시작한다.
일반적으로 레이블 셀렉터를 업데이트 하는 것을 권장하지 않으며 셀렉터를 미리 계획하는 것을 권장한다.
API 버전 apps/v1 에서 디플로이먼트의 레이블 셀렉터는 생성 이후에는 변경할 수 없다.
셀렉터 추가
디플로이먼트의 사양에 있는 파드 템플릿 레이블도 새 레이블로 업데이트해야 한다.
이 변경은 겹치지 않는 변경으로 새 셀렉터가 이전 셀렉터로 만든 레플리카셋과 파드를 선택하지 않게 되고, 그 결과로 모든 기존 레플리카셋은 고아가 되며, 새로운 레플리카셋을 생성하게 된다.
셀렉터 업데이트
셀렉터 삭제
디플로이먼트 셀렉터의 기존 키를 삭제하며 파드 템플릿 레이블의 변경을 필요로 하지 않는다.
기존 레플리카셋은 고아가 아니고, 새 레플리카셋은 생성되지 않는다. 그러나 제거된 레이블은 기존 파드와 레플리카셋에 여전히 존재한다는 점을 참고해야 한다.
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.161
> kubectl set image deployment/nginx-deployment nginx=nginx:1.161
deployment.apps/nginx-deployment image updated
$ kubectl rollout status deployment/nginx-deployment
> kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# ctrl + c
> kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-65b59c5f6f 1 1 0 100s
nginx-deployment-68fc675d59 3 3 3 17h
nginx-deployment-7fb96c846b 0 0 0 18h
web-deploy-5d9f7ffff8 3 3 3 6d19h
> kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 0/1 Error 0 6d18h
nginx-deployment-65b59c5f6f-hntb4 0/1 ImagePullBackOff 0 4m20s
nginx-deployment-68fc675d59-mbm4h 1/1 Running 1 (4m41s ago) 17h
nginx-deployment-68fc675d59-xr4x9 1/1 Running 1 (4m41s ago) 17h
nginx-deployment-68fc675d59-xxtm4 1/1 Running 1 (4m41s ago) 17h
web-deploy-5d9f7ffff8-hz82f 1/1 Running 3 (4m41s ago) 6d19h
web-deploy-5d9f7ffff8-r2q7x 1/1 Running 3 (4m41s ago) 6d19h
web-deploy-5d9f7ffff8-tkjx4 1/1 Running 3 (4m41s ago) 6d19h
디플로이먼트 컨트롤러가 잘못된 롤아웃을 자동으로 중지하고, 새로운 레플리카셋의 스케일 업을 중지한다. 이는 지정한 롤링 업데이트의 파라미터(구체적으로 maxUnavailable)에 따라 달라진다. 쿠버네티스는 기본값으로 25%를 설정한다.
> kubectl describe deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 19 Jan 2023 16:59:47 +0900
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 3
Selector: app=nginx
Replicas: 3 desired | 1 updated | 4 total | 3 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.161
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
OldReplicaSets: nginx-deployment-68fc675d59 (3/3 replicas created)
NewReplicaSet: nginx-deployment-65b59c5f6f (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 18h deployment-controller Scaled up replica set nginx-deployment-7fb96c846b to 3
Normal ScalingReplicaSet 17h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 1
Normal ScalingReplicaSet 17h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 2 from 3
Normal ScalingReplicaSet 17h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 2 from 1
Normal ScalingReplicaSet 17h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 1 from 2
Normal ScalingReplicaSet 17h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 3 from 2
Normal ScalingReplicaSet 17h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 0 from 1
Normal ScalingReplicaSet 5m33s deployment-controller Scaled up replica set nginx-deployment-65b59c5f6f to 1
이 문제를 해결하려면 디플로이먼트를 안정적인 이전 수정 버전으로 롤백해야 한다.
$ kubectl rollout history deployment/nginx-deployment
얘는 지원 안하나바,,,
> kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
$ kubectl rollout undo deployment/nginx-deployment
> kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
> kubectl get deployment nginx-deployment NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18h
> kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 19 Jan 2023 16:59:47 +0900
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 4
Selector: app=nginx
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=nginx
Containers:
nginx:
Image: nginx:1.16.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-68fc675d59 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 18h deployment-controller Scaled up replica set nginx-deployment-7fb96c846b to 3
Normal ScalingReplicaSet 18h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 1
Normal ScalingReplicaSet 18h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 2 from 3
Normal ScalingReplicaSet 18h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 2 from 1
Normal ScalingReplicaSet 18h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 1 from 2
Normal ScalingReplicaSet 18h deployment-controller Scaled up replica set nginx-deployment-68fc675d59 to 3 from 2
Normal ScalingReplicaSet 18h deployment-controller Scaled down replica set nginx-deployment-7fb96c846b to 0 from 1
Normal ScalingReplicaSet 13m deployment-controller Scaled up replica set nginx-deployment-65b59c5f6f to 1
Normal ScalingReplicaSet 2m55s deployment-controller Scaled down replica set nginx-deployment-65b59c5f6f to 0 from 1
$ kubectl scale deployment/nginx-deployment --replicas=10
> kubectl scale deployment/nginx-deployment --replicas=10
deployment.apps/nginx-deployment scaled
클러스터에서 horizontal Pod autoscaling를 설정 한 경우 디플로이먼트에 대한 오토스케일러를 설정할 수 있다.
기존 파드의 CPU 사용률을 기준으로 실행할 최소 파드 및 최대 파드의 수를 선택할 수 있다.
$ kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80