이번 글은 쿠버네티스 공식문서를 참고하여 디플로이먼트에 대해 설명하고자 합니다.
https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/
디플로이먼트
디플로이먼트(Deployment) 는 파드와 레플리카셋(ReplicaSet)에 대한 선언적 업데이트를 제공한다. 디플로이먼트에서 의도하는 상태 를 설명하고, 디플로이먼트 컨트롤러(Controller)는 현재 상태에서 의
kubernetes.io
디플로이먼트는 파드(Pod)와 레플리카셋(Replicaset)의 생명주기를 관리하는 고수준의 컨트롤러입니다.
사용자가 특정 리소스에 대하여 원하는 상태를 선언하면, 디플로이먼트는 현재 클러스터의 상태를 그에 맞게 자동으로 조절합니다.
(앞서 파드 관련 글에서 설명 드렸던 이상적인 상태(Desired state)를 유지하는 것이 이에 속합니다)
이러한 기능을 제공하기 위해서 디플로이먼트는 다음의 개념을 준수합니다.
주요 개념
1. 선언적 상태 관리 (Declarative State Management) : 사용자는 YAML 파일을 통해 애플리케이션의 최종 상태를 정의
디플로이먼트 컨트롤러는 이렇게 선언된 상태를 지속적으로 모니터링하고, 현재 상태가 선언된 상태와 다를 경우 자동으로 필요한 조치를 취하여 상태를 일치시키려고 시도
2. 레플리카셋(Replicaset)을 통한 파드 관리 : 파드를 직접 관리하지 않고, 레플리카셋이라는 중간 컨트롤러를 통해 파드 관리
업데이트가 발생할 때마다 디플로이먼트는 새로운 레플리카셋을 생성.
→ 버전 관리와 롤백에 용이 (각 레플리카셋은 특정 버전의 파드 그룹을 책임짐)
상기 개념을 기반으로 먼저 디플로이먼트 생성부터 살펴보겠습니다.
디플로이먼트 생성
다음은 공식문서에서 제공하는 디플로이먼트 예시입니다.
앞으로 디플로이먼트를 다룬다는 가정 하에 공식문서의 예시가 여러 요소를 설명하기 좋다고 생각되어 그대로 차용했습니다 :)
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
쿠버네티스에서 디플로이먼트를 사용할 때는 상기 내용과 같이 YAML 파일을 작성합니다.
다음은 YAML 내 각 요소에 대한 설명입니다.
.apiVersion: apps/v1 : 쿠버네티스가 발행한 첫 stable release API
.kind : 쿠버네티스가 기본적으로 제공하는 리소스 중 사용할 리소스
.metadata
.name : 디플로이먼트의
.label : 여러 파드를 부분 집합 형태로 관리하기 위한 {key-value} 쌍
.spec : 디플로이먼트가 관리할 대상의 특징을 명세
.replicas : 레플리카셋의 개수
.selector : 생성된 레플리카셋이 관리할 파드를 찾는 방법
.matchlabels : 관리할 파드가 가지는 라벨
.template : 관리할 파드가 지켜야 할 상태
.labels : 관리할 파드가 속한 부분 집합
.spec : 파드가 가질 특징 명세
.containers : 파드 내 컨테이너가 가질 특징 명세
- name : 컨테이너 명
- image : 컨테이너에서 작동시킬 이미지 명
- ports.containerPorts : 컨테이너가 개방할 포트 번호
여기에 명세되진 않았지만 파드 템플릿에는 .spec.strategy가 존재합니다.
strategy는 이전 파드를 새로운 파드로 대체하는 전략을 명시합니다.
여기에는 재생성 또는 롤링 업데이트가 될 수 있는데, 디폴트는 롤링 업데이트입니다.
만약 재생성, 즉 .spec.strategy.type=Recreate이면 새 파드가 생성되기 전에 기존의 파드들은 모두 죽습니다.
이를 통해 업그레이드 생성 이전에 파드 종료를 보장할 수 있게 됩니다.
이제 위와 같은 방식으로 명세된 YAML을 가지고 디플로이먼트를 생성할 때는 다음의 명령어를 사용합니다.
kubectl apply -f <본인이 만든 YAML 파일명>
# 디플로이먼트 생성 이후 생성 여부 확인 명령어
kubectl get deployments -ns <해당 디플로이먼트가 속한 네임스페이스 명>
# 명령어 사용 결과 예시
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 0 0 1s
위와 같이 디플로이먼트 생성 이후 명령어를 통해 디플로이먼트 정상 생성 여부를 확인할 수 있는데, 출력된 내용의 의미는 다음과 같습니다.
| NAME | 네임스페이스에 있는 디플로이먼트 이름 목록 |
| READY | 사용자가 사용할 수 있는 애플리케이션의 레플리카 수 |
| UP-TO-DATE | 의도한 상태를 얻기 위해 업데이트 된 레플리카 수 |
| AVAILABLE | 사용자가 사용할 수 있는 애플리케이션 레플리카 수 |
| AGE | 애플리케이션의 실행된 시간 |
앞서 설명 드린 내용에서 디플로이먼트는 파드 관리를 위해 레플리카셋을 사용한다고 말씀드렸습니다.
이 레플리카셋은 쿠버네티스의 kubectl rollout 명령어와 함께 안정적인 배포 및 업데이트 기능을 제공합니다.
롤아웃(rollout)은 다음과 같은 주된 목적을 가집니다.
1. 무중단 업데이트 : 사용자가 서비스를 이용하는 중에 업데이트가 발생해도 서비스 중단 없이 새 버전으로 전환
2. 통제된 변경 관리 : 업데이트 과정을 예측하고 제어 가능 (한 번에 전부 바꾸는 것이 아닌 정해진 규칙에 따라 점진적 변경)
3. 신속한 복구 (Rollback) : 만약 새로 배포한 버전에 심각한 버그나 문제가 발견된 경우, 이전의 안정적인 버전으로 전환 가능
온전한 업데이트 및 관리를 위해서 디플로이먼트에는 파드 템플릿 레이블과 적절한 셀렉터를 반드시 명시해야 합니다.
또한 레이블 혹은 셀렉터가 다른 컨트롤러와 겹치지 않아야 하는데, 이는 쿠버네티스 자체는 해당 명세 사항들이 겹치는 것을 딱히 방지해주지 않으며, 만약 다중 컨트롤러가 같은 셀렉터를 가지는 경우 해당 컨트롤러들의 충돌 또는 예상에서 벗어난 동작을 야기할 수 있기 때문입니다.
이번에 디플로이먼트에 대해 작성하게 되면서 흥미로웠던 점이 있었는데, 바로 Pod-template-hash 레이블이었습니다.
해당 레이블은 디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리카셋에 추가된다고 공식문서에 적혀 있었는데요, 간단히 말씀드리자면 특정 디플로이먼트가 가지는 레플리카들의 고유 식별 번호입니다.
해당 레이블을 통해 디플로이먼트 예하의 자식 레플리카셋이 겹치지 않도록 보장할 수 있는데요, 레플리카셋의 PodTemplate를 해싱하고, 해시 결과를 레플리카셋 셀렉터, 파드 템플릿 레이블 및 레플리카셋이 가질 수 있는 기존의 모든 파드에 레이블 값으로 추가해서 사용하도록 생성합니다.
쿠버네티스를 사용해보셨다면 아시겠지만 파드나 디플로이먼트를 생성해보면 파드 이름 옆에 이상한 숫자들이 붙는걸 종종 보셨을텐데, 이 숫자가 바로 Pod-template-hash 레이블에 명세된 내용입니다.
이를 확인하는 명령어와 확인 결과는 다음과 같습니다.
# 'my-app'이라는 레이블을 가진 파드들의 모든 레이블을 확인
kubectl get pods -l app=my-app --show-labels
# 출력 예시
NAME READY STATUS RESTARTS AGE LABELS
my-app-deployment-5f8f4f4f4f-abcde 1/1 Running 0 2m app=my-app,pod-template-hash=5f8f4f4f4f
my-app-deployment-5f8f4f4f4f-fghij 1/1 Running 0 2m app=my-app,pod-template-hash=5f8f4f4f4f
디플로이먼트 업데이트
말 그대로 디플로이먼트가 관리하는 파드에 새로운 상태가 갱신되었을 때 디플로이먼트가 취하는 조치가 디플로이먼트 업데이트입니다.
여기서 중요한 점은 업데이트 과정은 디플로이먼트의 파드 템플릿(.spec.template)이 변경된 경우에만 디플로이먼트의 롤아웃이 야기된다는 점입니다.
따라서 디플로이먼트의 실행 중인 파드 개수를 동적으로 줄이는 과정인 스케일링과 같은 다른 업데이트는 롤아웃을 야기하지 않아야합니다.
디플로이먼트의 업데이트는 다음의 명령어를 통해 진행할 수 있습니다.
kubectl set image <현재 네임스페이스에서 수정할 디플로이먼트 명> <수정할 이미지 명>
# 실행 결과
<현재 네임스페이스에서 수정된 디플로이먼트 명> image updated
# kubectl edit 명령어를 통해 현재 실행중인 디플로이먼트의 명세 또한 수정 가능
# 수정하고 싶은 파드 템플릿의 내용이 수정 완료되면 esc -> :wq로 변경 사항 저장 (linux vi 사용법)
kubectl edit <현재 네임스페이스에서 수정할 디플로이먼트 명>
# 수정 후 결과
<현재 네임스페이스에서 수정된 디플로이먼트 명> edited
롤아웃 과정을 확인하려면 다음의 명령어를 실행합니다.
kubectl rollout status <현재 네임스페이스에서 수정한 디플로이먼트 명>
# 롤아웃 적용중일 때 출력문 예시
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
# 롤아웃이 모두 적용되었을 때 출력문 예시
deployment "nginx-deployment" successfully rolled out
# 롤아웃 성공 이후 kubectl get -ns <롤아웃을 진행한 디플로이먼트의 네임스페이스 명> deployments 결과
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 36s
# 롤아웃 성공 이후 kubectl get -ns <롤아웃을 진행한 디플로이먼트의 네임스페이스 명> rs 결과
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 3 3 3 6s
nginx-deployment-2035384211 0 0 0 36s
# 롤아웃 성공 이후 kubectl get -ns <롤아웃을 진행한 디플로이먼트의 네임스페이스 명> pods 결과
NAME READY STATUS RESTARTS AGE
nginx-deployment-1564180365-khku8 1/1 Running 0 14s
nginx-deployment-1564180365-nacti 1/1 Running 0 14s
nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
이때 롤아웃 이후 kubectl get -ns <롤아웃을 진행한 디플로이먼트의 네임스페이스 명> pods 명령어를 사용하면 기존 레플리카셋은 스케일 아웃(Sclae Out)되고, 새로운 레플리카셋이 스케일 인(Scale In)되기 때문에 기본적으로 명령어 실행 결과는 새로운 레플리카셋만 출력합니다.
배포된 디플로이먼트의 세부 정보는 kubectl describe -ns <해당 디플로이먼트가 존재하는 네임스페이스 명> deployment 명령어를 통해 확인할 수 있으며, 이에 대한 출력 예시는 다음과 같습니다.
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 30 Nov 2017 10:56:25 +0000
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
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-2035384211 to 3
Normal ScalingReplicaSet 24s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 1
Normal ScalingReplicaSet 22s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 2
Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 2
Normal ScalingReplicaSet 19s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 1
Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 3
Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 0
배포된 디플로이먼트의 기존 명세 뿐 만 아니라 해당 리소스의 생성 과정 및 결과를 확인할 수 있는 Events 또한 제공됩니다..
여기서 쿠버네티스가 availableReplicas 수를 계산할 때, 종료 중인(terminating) 파드는 포함하지 않고, 이 수는 replicas - maxUnavailable 와 replicas + maxSurge 사이에 존재합니다.
따라서 롤아웃 중에는 파드의 수가 예상보다 많을 수 있고, 종료 중인 파드의 terminationGracePeriodSeconds(default : 30초)가 만료될 때까지는 디플로이먼트가 소비하는 총 리소스가 replicas + maxSurge 이상일 수 있습니다.
이때 maxUnavailable과 maxSurge의 정의는 다음과 같습니다.
1. maxUnavailable : 업데이트 과정에 spec.replicas 수 기준 최대 이용 불가능 파드 수
2. maxSurge : 업데이트 과정에서 spec.replicas 수 기준 최대 새로 추가되는 파드 수
롤오버(인-플라이트 다중 업데이트)
디플로이먼트 컨트롤러는 각 시간마다 새로운 디플로이먼트이 의도한 파드를 생성 및 배포하는 것을 주시합니다.
만약 디플로이먼트가 업데이트 된다면, 기존 레플리카셋에서 .spec.selector 레이블과 일치하는 파드를 컨트롤하게 되는데, 만약 이 명세가 불일치 하다면 스케일 다운됩니다. 결론적으로 새 레플리카셋은 .spec.replicas로 스케일 되고, 모든 기존 레플리카셋은 0개로 스케일됩니다.
이에 따라 만약 기존에 롤아웃이 진행되던 중 디플로이먼트가 업데이트 되면 해당 업데이트를 기준으로 새 레플리카셋을 생성하고 스케일 업하게 되면서 기존 레플리카셋에 롤오버하게 됩니다.
디플로이먼트 롤백
버전을 관리하며 개발을 진행하다 보면 디플로이먼트의 롤백을 원하는 경우가 생길수도 있습니다.
이때 롤백을 위해선 기존에 롤아웃이 진행 되었어야 하는데, 앞서 설명드린 바와 같이 디플로이먼트의 업데이트는 파드 템플릿의 내용이 수정 되었을 시에만 가능하고, 이에 따라 디플로이먼트의 스케일링과 같은 다른 변경 사항으로는 디플로이먼트의 수정 버전을 배포할 수 없습니다.
따라서 롤백 또한 디플로이먼트에 명세된 파드 템플릿에 해당하는 부분만 진행됩니다.
디플로이먼트의 롤아웃 기록 확인
롤백을 하기에 앞서 디플로이먼트의 수정 사항을 확인합니다.
kubectl rollout history -ns <해당 디플로이먼트가 존재하는 네임스페이스 명>
# 출력 예시
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.161
# 각 수정 버전의 세부 정보 열람 명령어
kubectl rollout history deployment/nginx-deployment --revision=2
# 출력 예시
deployments "nginx-deployment" revision 2
Labels: app=nginx
pod-template-hash=1159050644
Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
Containers:
nginx:
Image: nginx:1.16.1
Port: 80/TCP
QoS Tier:
cpu: BestEffort
memory: BestEffort
Environment Variables: <none>
No volumes.
이전 수정 버전으로 롤백
다음의 과정을 통해 롤백을 진행합니다.
# 롤백 명령어
# -> kubectl rollout undo -ns <해당 디플로이먼트가 존재하는 네임스페이스 명> deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
# 출력 예시
deployment.apps/nginx-deployment rolled back
# 특정 버전으로의 롤백
kubectl rollout undo -ns <해당 디플로이먼트가 존재하는 네임스페이스 명> deployment/nginx-deployment --to-revision=2
# 출력 예시
deployment.apps/nginx-deployment rolled back
# 롤백 이후 디플로이먼트 정상 작동 여부 확인
kubectl get deployment -ns <해당 디플로이먼트가 존재하는 네임스페이스 명> nginx-deployment
# 출력 예시
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 30m
디플로이먼트 스케일링
다음 명령어를 통해 디플로이먼트의 스케일을 조정할 수 있습니다.
kubectl scale -ns <해당 디플로이먼트가 배포된 네임스페이스 명> deployment/nginx-deployment --replicas=10
# 출력 결과
deployment.apps/nginx-deployment scaled
# 오토 스케일의 경우 레플리카의 최대 / 최소 개수를 cpu 사용률에 따라 조정 가능
kubectl autoscale -ns <해당 디플로이먼트가 배포된 네임스페이스 명> deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80
# 출력 결과
deployment.apps/nginx-deployment scaled
비례적 스케일링(Proportional Scaling)
디플로이먼트 롤링 업데이트는 여러 버전의 애플리케이션을 동시에 실행할 수 있도록 지원합니다.
개발자나 오토 스케일러가 롤아웃 중에 있는 디플로이먼트 롤링 업데이트를 스케일링 하는 경우, 디플로이먼트 컨트롤러는 위험을 줄이기 위해 기존 활성화된 레플리카셋의 추가 레플리카의 균형을 조절하는데, 이를 비례적 스케일링이라고 부릅니다.
공식문서 예시에서의 내용이 조금 와닿지 않는거 같아서 제가 이해한 바로 설명해보겠습니다.
비례적 스케일링이라는 표현이 강조되는 이유는 바로 레플리카의 수를 각각의 버전이 배포되어 있는 개수를 기준으로 어떤 레플리카를 불용할 것인지 정하기 때문입니다.
예를 들어 기존에 디플로이먼트가 10개의 레플리카를 배포하고 있었다고 가정합니다.
여기서 비례적 스케일링을 적용하기 위해 maxUnavailable = 2, maxSurge = 3으로 실행합니다.
또한 기존의 레플리카가 다음의 버전으로 실행되고 있었다고 가정합니다.
이후 5개의 레플리카에 대한 업데이트가 새로운 버전으로 진행되었다고 가정합니다.
ver.1 4개 ver.2 3개 ver.3 3개
이때 최대로 추가 가능한 레플리카의 개수가 3개이기 때문에 3개는 먼저 추가됩니다.
이후 최대로 불용 조치 가능한 레플리카의 개수가 2개이기 때문에 기존 레플리카 중 2개를 불용 처리해야 합니다.
이때 불용 처리되는 기준은 '기존의 버전 중 레플리카 총 개수 중 차지하고 있는 비율'이 됩니다.
이러한 기준으로 인해,
ver1 : 4개 → 4 / 10 = 0.4
ver2 : 3개 → 3 / 30 = 0.33...
이때 불용 처리해야 할 최대 개수가 2개이므로 각 비율을 가중치라 가정하고 곱하면,
0.4 * 2 = 0.8 → 반올림 해서 1개
0.33 * 2 = 0.66... → 반올림 해서 1개
이므로 ver1과 ver2 에서 각각 1개씩 불용 처리합니다.
이후 새롭게 추가되는 레플리카의 버전은 사용자가 명시하기 나름입니다.
이에 따라 레플리카의 각 버전에 대한 비율이 상이해질 수 있습니다.
디플로이먼트 롤아웃 일시 중지와 재개
디플로이먼트를 업데이트할 때, 하나 이상의 업데이트를 시작하기 전에 해당 디플로이먼트에 대한 롤아웃을 일시 중지할 수 있고, 만약 변경 사항을 적용할 준비가 되었다면, 디플로이먼트 롤아웃을 재개합니다.
이와 같은 방식으로 불필요한 롤아웃을 진행하지 않고도 롤아웃 일시 중지와 재개 사이에 여러 수정 사항을 적용할 수 있습니다.
롤아웃 일시 중지 및 재개는 다음과 같은 플로우로 진행됩니다.
# 디플로이먼트 상세 정보 출력 명령어
kubectl get deploy
# 출력 예시
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 3 3 3 3 1m
# 롤아웃 상태 호출
kubectl get rs
# 출력 예시
NAME DESIRED CURRENT READY AGE
nginx-2142116321 3 3 3 1m
# 롤아웃 일시 정지 명령어
kubectl rollout pause deployment/nginx-deployment
# 출력 예시
deployment.apps/nginx-deployment paused
# 디플로이먼트 이미지 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
# 출력 예시
deployment.apps/nginx-deployment image updated
# 새로운 롤아웃 시작되지 않음
kubectl rollout history deployment/nginx-deployment
# 출력 예시
deployments "nginx"
REVISION CHANGE-CAUSE
1 <none>
# 기존 레플리카셋의 변경 여부 확인 명령어
kubectl get rs
# 출력 예시
NAME DESIRED CURRENT READY AGE
nginx-2142116321 3 3 3 2m
# 디플로이먼트 리소스 업데이트 명령어 예시
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
# 출력 결과
deployment.apps/nginx-deployment resource requirements updated
# 디플로이먼트 롤아웃 재개 명령어
kubectl rollout resume deployment/nginx-deployment
# 출력 예시
deployment.apps/nginx-deployment resumed
# 롤아웃 완료까지 상태 관찰 명령어
kubectl get rs -w
# 출력 예시
NAME DESIRED CURRENT READY AGE
nginx-2142116321 2 2 2 2m
nginx-3926361531 2 2 0 6s
nginx-3926361531 2 2 1 18s
nginx-2142116321 1 2 2 2m
nginx-2142116321 1 2 2 2m
nginx-3926361531 3 2 1 18s
nginx-3926361531 3 2 1 18s
nginx-2142116321 1 1 1 2m
nginx-3926361531 3 3 1 18s
nginx-3926361531 3 3 2 19s
nginx-2142116321 0 1 1 2m
nginx-2142116321 0 1 1 2m
nginx-2142116321 0 0 0 2m
nginx-3926361531 3 3 3 20s
# 디플로이먼트 롤아웃 최신 상태 출력 명령어
kubectl get rs
# 출력 예시
NAME DESIRED CURRENT READY AGE
nginx-2142116321 0 0 0 2m
nginx-3926361531 3 3 3 28s
디플로이먼트 상태
디플로이먼트는 라이프사이클 동안 다양한 상태로 전환됩니다.
이때 상태는 새 레플리카셋을 롤아웃하는 동안 진행 중이 될 수도 있고, 완료이거나 진행 실패일 수도 있습니다.
디플로이먼트 진행 중
쿠버네티스는 다음 작업 중 하나를 수행할 때 디플로이먼트를 진행 중으로 표시합니다.
1. 디플로이먼트로 새 레플리카셋을 생성
2. 디플로이먼트로 새로운 레플리카셋을 스케일 업
3. 디플로이먼트로 기존 레플리카셋을 스케일 다운
4. 새 파드가 준비되거나 이용할 수 있음
롤아웃이 진행 중인 상태라면, 디플로이먼트 컨트롤러는 디플로이먼트의 .status.conditions에 다음 속성을 포함하는 컨디션을 추가합니다.
type: Progressing
status: "True"
reason: NewReplicaSetCreated | reason: FoundNewReplicaSet | reason: ReplicaSetUpadated
디플로이먼트 완료
쿠버네티스는 다음과 같은 특성을 가지게 되면 디플로이먼트를 완료로 표시 합니다.
1. 디플로이먼트와 관련된 모든 레플리카가 지정된 최신 버전으로 업데이트 되었을 때 (요청한 모든 업데이트가 완료될 시)
2. 디플로이먼트와 관련된 모든 레플리카를 사용할 수 있을 때
3. 디플로이먼트에 대해 이전 복제본이 실행되고 있지 않을 때
롤아웃이 완료 상태라면, 디플로이먼트 컨트롤러는 디플로이먼트의 .status.conditions에 다음 속성을 포함하는 컨디션을 추가합니다.
type: Progressing
status: "True"
reason: NewReplicaSetAvailable
디플로이먼트 실패
새 레플리카셋이 완료되지 않은 상태에서 배포를 시도하면 고착될 수 있습니다.
이러한 문제는 다음의 요인들로 인해 발생할 수 있습니다.
1. 할당량 부족
2. 준비성 프로브(readiness probe)의 실패
3. Image Pull 에러
4. 권한 부족
5. 범위 제한
6. 애플리케이션 런타임의 잘못된 구성
이 조건들을 찾을 수 있는 방법은 디플로이먼트 스펙에서 데드라인 파라미터를 지정하는 것입니다.
.spec.progressDeadlineSeconds는 디플로이먼트의 진행이 정지되었음을 나타내는 디플로이먼트 컨트롤러가 대기하는 시간을 나타냅니다.
이를 쉽게 말하면, progressDeadlineSeconds
에서 설정한 시간 내에 롤아웃이 진행중이던 레플리카셋에 의미있는 변화가 일어나지 않으면 업데이트에 실패했다고 판단하여 디플로이먼트 롤아웃의 상태를 실패로 수정하게 됩니다.
type: Progressing
status: "False"
reason: ProgressDeadlineExceeded
이 컨디션은 오히려 progressDeadlineSeconds가 채 되기도 전에 롤아웃에 실패하여 더 이른 시점에 적용될 수 있습니다.
이런 경우 ReplicaSetCreateError를 이유로 상태값을 "False"로 설정합니다.
또한 디플로이먼트 롤아웃이 완료되면 데드라인은 더이상 고려되지 않습니다.
이때 progressDeadlineSeconds 필드는 .spec.minReadySeconds보다 커야합니다.
.spec.minReadySeconds란 새롭게 생성된 파드의 컨테이너가 어떤 것과도 충돌하지 않고 사용할 수 있도록 준비되어야 하는 최소 시간을 지정하는 선택적 필드입니다.
이 필드는 기본적으로 파드는 즉시 생성 되어야 하는 것으로 간주되기에 0으로 설정되어 있습니다.
이상으로 디플로이먼트에 대한 설명을 마치겠습니다.
긴 글 읽어주셔서 감사합니다!
'쿠버네티스' 카테고리의 다른 글
| 온프레미스 K8s 환경 구축 - 기본 목표 및 개념 설명 (2) | 2024.12.26 |
|---|---|
| 온프레미스 K8s 환경 구축 - 개발 동기 (1) | 2024.12.23 |