참고
1. Deployment란?
예를 들어, 사용자가 replicas: 5, image: nginx:1.21이라고 선언하면,
- Kubernetes는 현재 상태와 비교해서,
- 파드가 3개밖에 없으면 2개를 추가하고,
- 이미지가
nginx:1.20이면1.21로 순차적으로 업데이트하며
- "의도한 상태"로 만들어줍니다.
즉, 원하는 상태를 YAML로 선언만 하면, 알아서 조정해 주는 것임
Deployment는 단순한 파드 관리 이상의 기능(롤링 업데이트, 롤백, 확장, 일시정지 등)을 제공하는 상위 관리 오브젝트
대신,
Deployment가 생성한 ReplicaSet이나 Pod를 직접 수정하면 안 됨.
수정하고 싶다면 Deployment를 수정해야 함
1.1 유스케이스
Deployment는 배포/업데이트/복구/확장 등 운영에 필요한 기능을 자동화해주는데, 어떻게 사용이 되냐?
- 새로운 ReplicaSet을 생성해서 애플리케이션을 롤아웃(배포)
- Deployment를 만들면, 그에 맞는 ReplicaSet이 생성되고 → ReplicaSet이 파드를 자동으로 생성함
- 배포가 정상적으로 완료됐는지 상태(롤아웃 상태)를 확인할 수 있음
- 애플리케이션을 새 버전으로 업데이트 (rolling update)
- Deployment의
.spec.template을 바꾸면 (예: image 버전 변경),→ 새로운 ReplicaSet이 생성되고, - → 기존 파드를 조금씩 줄이고 새로운 파드를 조금씩 늘리는 롤링 업데이트가 자동으로 일어남
- Deployment의
- 문제가 생기면 이전 버전으로 롤백
- 문제가 발생한 경우, 이전에 잘 동작하던 상태로 되돌릴 수 있음
- 이때도 버전 번호가 올라감 (수정 버전이 자동 관리됨)
- 애플리케이션 수평 확장 (scale up/down)
replicas수치를 변경하면 → 자동으로 파드 수 증가 또는 감소
- 배포 일시 중지 후, 여러 수정 후 재개
- rollout을 pause하고 여러 설정을 수정
- 다 수정하고 나서 resume하면 그때 적용됨
- 배포가 막혀 있는 상태를 알 수 있음
- 예: readiness probe 실패로 새 파드가 준비되지 않으면 롤아웃이 멈춰 있음
- Deployment 상태로 이런 문제를 파악할 수 있음
- 이전 버전의 ReplicaSet 정리
- 오래된 ReplicaSet은 자동으로 정리됨 (디플로이먼트가 관리함)
1.2 YAML
#controllers/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 없으면 기본적으로 1개의 파드만 생성
selector:
matchLabels:
app: nginx # ★ 이게 .spec.selector
template: # ★ 이게 .spec.template (실제 pod 정의)
metadata:
labels:
app: nginx # selector와 꼭 일치해야 함!
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
파일 구성은 ReplicaSet과 다를게 없다.
.spec.selector는 필수
.spec.selector는 한 번 생성하면 수정할 수 없다 (immutable)
.spec.selector와.spec.template.metadata.labels는 꼭 일치
- HPA를 사용할 거면
.spec.replicas는 절대 설정하지 말 것!
대신, 출력을 잘보자.
클러스터에서 디플로이먼트, 레플리카셋, 파드를 점검할 때, 다음 필드가 표시된다.
1.2.1 Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18s
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
READY: 준비된 파드 수 / 원하는 파드 수
UP-TO-DATE: 최신 템플릿 기준으로 생성된 파드 수
AVAILABLE: 사용자 요청 처리 가능한 파드 수
AGE: 생성된 지 얼마나 되었는지
1.2.2 ReplicaSet
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
- 이름은 보통
디플로이먼트이름-HASH
.pod-template-hash라벨과 일치
DESIRED,CURRENT,READY필드로 상태 확인
1.2.3 Pod
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
- 이름도 보통
디플로이먼트이름-HASH-랜덤문자
app=nginx,pod-template-hash=...라벨이 자동 부여됨
1.2.4 파드 템플릿 라벨
여기서, pod-template-hash 라벨이 자꾸 튀어나오는데 무엇이냐면?
ReplicaSet의 문제점이 selector의 라벨이 겹치지 않아야 함.
만약 겹친 경우 여러 ReplicaSet이 관리가 ..해당 파드를 소유하게 될 수 있음.
이와 비슷한 맥락으로 Deployment도 단순한 파드 관리 이상의 기능을 하기 때문에 여러 ReplicaSet을 가짐.
예를 들어 여러 버전의 ReplicaSet을 동시에 가지게 되는데 이때 서로 겹치는 파드를 관리하지 않도록 하기 위해 pod-template-hash 값이 다르게 설정되어 각 ReplicaSet이 자신만의 파드만 관리하도록 하는 것.
즉, Deployment가 ReplicaSet을 유일하게 구분하고 충돌 없이 관리하기 위해 파드 템플릿 내용을 해시한 값입니다. 이 값은 Deployment 컨트롤러가 자동으로 생성하며, 사용자가 직접 수정하면 시스템 동작이 꼬일 수 있기 때문에 변경하면 안 됩니다.
apps/v1에서는 selector가 생성 후에 변경이 아예 불가능;
2. 업데이트
디플로이먼트는 파드를 업데이트할 때 롤링 업데이트 방식으로 점진적으로 업데이트를 수행합니다. 롤링 업데이트는 한 번에 모든 파드를 업데이트하지 않고, 몇 개씩 순차적으로 업데이트하여 서비스의 다운타임을 최소화합니다.
예를 들어, nginx:1.14.2 이미지를 nginx:1.16.1로 업데이트할 때:
- 디플로이먼트는 새 파드를 생성하고 (새로운 레플리카셋으로),
- 기존 파드를 삭제하는 방식으로 업데이트합니다.
이 과정을 통해 서비스가 중단되지 않고 점진적으로 새로운 버전으로 변경됩니다.
2.1 파드 수의 제한
디플로이먼트는 항상 최소 75% 이상의 파드가 동작하도록 보장함.
기본적으로 디플로이먼트는 롤링 업데이트 중에 최대 25%의 파드만 동시에 다운되도록 설정되어 있음.
즉, 디플로이먼트가 업데이트 중일 때, 적어도 75%의 파드는 계속 실행됩니다. 이 설정은 서비스의 가용성을 유지하기 위해 매우 중요함.
maxUnavailable: 롤링 업데이트 중 동시에 다운될 수 있는 파드의 최대 개수입니다. 기본적으로 최대 25%까지 설정됩니다.
maxSurge: 롤링 업데이트 중 동시에 실행되는 파드의 최대 수입니다. 기본적으로 25%까지 설정되어 있으며, 디플로이먼트가 새 파드를 추가할 때 이를 제어합니다.
예시:
- 디플로이먼트의 레플리카 수가 4일 경우, 최소 3개의 파드는 항상 실행되어야 합니다.
maxSurge와maxUnavailable설정에 따라, 최대 5개의 파드가 동시에 실행될 수 있으며, 최소 3개는 항상 실행됩니다.
availableReplicas: 종료 중인(terminating) 파드는 포함되지 않으며, 현재 실행 중인 사용 가능한 파드만 계산됩니다. 롤링 업데이트 중에는 새로 생성된 파드가 완료되기 전까지 이전 파드가 삭제되지 않기 때문에,availableReplicas는 예기치 않게 더 많은 수치를 보일 수 있습니다.
2.3 롤오버(일명 인-플라이트 다중 업데이트)
= 기존 디플로이먼트 업데이트(롤링 중) 도중에 또 다른 업데이트가 발생했을 때의 처리 방식
디플로이먼트는 이전 요청이 완전히 끝나지 않았더라도 최신 요청 기준으로 동작함. 기존 버전(nginx:1.14.2)의 나머지 파드는 더 이상 만들지 않고 중단함 대신 새 버전(nginx:1.16.1)으로 파드를 만들기 시작함 이전 레플리카셋은 스케일 다운되어 사라지고, 새로운 레플리카셋이 스케일 업됨
즉, 롤링 업데이트 중에 또 업데이트가 들어오면, 새로운 버전으로 바로 전환함
3. 롤백
만약 새로운 버전으로 업데이트한 후 오류가 발생하면, 자동으로 중단하거나, 수동으로 롤백함.
. spec.template이 바뀌면 수정 버전(Revision)이 생기는데, 이걸 기준으로 롤백. 대신 수정 버전은 `.spec.template`이 바뀌었을 때만 생성됨.
예를 들어서,
- 오타로 잘못된 이미지 입력
kubectl set image deployment/nginx-deployment nginx=nginx:1.161- 실제로 존재하지 않는 이미지라서
ImagePullBackOff상태로 고착됨
- 실제로 존재하지 않는 이미지라서
- 롤아웃 상태 확인
kubectl rollout status deployment/nginx-deployment- 출력:
1 out of 3 new replicas have been updated...(계속 대기)
- 출력:
kubectl get rs- 새 레플리카셋이 1개 생성되었지만, 파드가 문제로 제대로 실행되지 않음
- 이전 정상 상태의 레플리카셋도 아직 남아있음
- 문제 원인
- 오타로 인해 이미지를 불러올 수 없고
- 쿠버네티스는 기본적으로 25%만 비정상 파드를 허용하므로 롤아웃이 멈춤
- 해결 방법: 롤백
kubectl rollout undo deployment/nginx-deployment- 가장 최근의 정상 상태로 롤백함
3.1 롤아웃 기록
즉, 디플로이먼트가. spec.template이 바뀔 때마다 수정 버전을 하나씩 남기는데 각 버전의 변경 내역을 볼 수 있고, 원하면 특정 버전으로 롤백할 수도 있음.
3.1.1 롤아웃 기록 확인
kubectl rollout history deployment/nginx-deployment
예시 출력:
REVISION CHANGE-CAUSE
1 kubectl apply --filename=...
2 kubectl set image ... nginx=nginx:1.16.1
3 kubectl set image ... nginx=nginx:1.161
- REVISION: 디플로이먼트 버전 번호
- CHANGE-CAUSE: 무엇 때문에 수정되었는지 나타냄
kubectl set image나kubectl apply등의 명령이 표시됨
3.1.2 특정 수정 버전 상세 보기
kubectl rollout history deployment/nginx-deployment --revision=2
4. 스케일링
디플로이먼트도 rs처럼 수동 또는 자동으로 스케일링한다.
4.1 비례적 스케일링
즉, 롤링 업데이트 도중에 기존 파드와 새 파드에 파드 개수를 비율로 잘 분산하는 방식
예를 들어,
롤링 업데이트 중이어서 기존 파드가 10개고 5개를 늘린다고 하면, 새 버전 이미지로 업데이트가 시작됨. 이때 오토스케일러가 개입해서 파드 수 15개로 늘리라고 요청함
기존 RS: 8개 중 3개 추가 → 총 11개
새 RS: 5개 중 2개 추가 → 총 7개
현재 활성 레플리카셋(New + Old)에 비율에 따라 새 파드를 골고루 배분
→ 즉, 업데이트가 아직 완료되지 않았을 때는 분산해서 안전하게 늘림
새 파드가 모두 정상 상태가 되면, 기존 구 버전 파드를 점점 줄이고 최종적으로 모든 파드가 신버전으로 전환됨
5. 일시정지 및 재개(기본값 = false)
.spec.template 안의 내용이 변경되면 롤아웃되는데 파일에서 한 번에 여러 항목을 변경하면 한 번의 롤아웃이 트리거가 됨
근데? 왜 pause/resume을 쓰냐?
CLI 명령어로 여러 번 나눠서 수정하는 경우, 수정할 때마다 롤아웃이 발생함. 그렇기 때문에 일시정지하고 재개하는 것임. 배포 제어하려고
대신, 일시 중지된 디플로이먼트를 재개할 때까지 롤백할 수 없음 ~
spec:
paused: true
- 위와 같이 설정하면, 이후
.spec.template의 이미지나 리소스 등을 바꿔도 롤아웃되지 않음
- 나중에 다음 명령으로 롤아웃 재개:
kubectl rollout resume deployment/nginx-deployment
6. 상태
6.1 진행 중 = 디플로이먼트가 무언가를 바꾸고 있는 중일 때
디플로이먼트 오브젝트의 .status.conditions 항목에 다음과 같은 정보가 들어갑니다:
type: Progressing
status: "True"
reason: NewReplicaSetCreated | FoundNewReplicaSet | ReplicaSetUpdated
kubectl rollout status deployment/nginx
# 출력 예시:
# Waiting for deployment "nginx" rollout to finish: 1 out of 3 new replicas have been updated...
6.2 완료 = 모든 파드가 최신 상태 + 사용 가능 + 이전 버전 없음
.status.conditions :
type: Progressing
status: "True"
reason: NewReplicaSetAvailable
출력 예시:
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx-deployment" successfully rolled out
echo $? # 종료 코드 0
6.3 실패
📌 가능한 실패 원인
- 이미지가 존재하지 않거나 Pull 오류 발생
- readiness probe 실패
- 리소스 부족 (예: CPU, 메모리)
- 권한 부족 (RBAC 등)
- 할당량(quota) 초과
- 잘못된 애플리케이션 설정 등
6.3.1 progressDeadlineSeconds
만약 위 실패 원인으로 롤아웃이 실패가 되기까지 기본값이 600(10분)을 기다려야 함. 그렇기 때문에 문제가 발생했을 때 적절한 조치를 취하기 위해 설정하는 것.
예를 들어서 잘못된 이미지(nginx:typo)로 인해 파드가 ImagePullBackOff 상태인데, 롤아웃 실패로 간주되기까지 10분이나 기다려야 함.
→ progressDeadlineSeconds: 60으로 줄이면, 1분 안에 롤아웃 실패 감지 가능.
예: 60(1분) 동안 롤아웃이 완료되지 않으면 실패 처리
kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":60}}'
즉, 설정하면 더 빠르게 실패로 간주해서 운영 자동화 및 디버깅에 유리하게 된다 ~
디플로이먼트 진행 데드라인을 넘어서면, 쿠버네티스는 진행 컨디션의 상태와 이유를 업데이트함.
.status.conditions :
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded #설정했을 경우
ReplicaFailure True FailedCreate
출력 예시:
kubectl rollout status deployment/nginx-deployment
# 출력:
# error: deployment "nginx-deployment" exceeded its progress deadline
echo $? # 종료 코드 1
progressDeadlineSeconds는 선택 필드
- 만약 설정한다면,
minReadySeconds보다 커야 함(파드가 준비됐다고 간주되기까지 기다리는 시간보다 길어야 한다는 뜻)spec: progressDeadlineSeconds: 300 # 5분 안에 롤아웃 완료 안 되면 실패로 간주 minReadySeconds: 60
7. 그 외
7.1 .spec.revisionHistoryLimit(기본값=10)
디플로이먼트가 새로운 롤아웃(업데이트)을 할 때마다 이전 버전의 ReplicaSet을 하나씩 남기는데 몇 개까지 남길 것인지 결정하는 것. 대신 롤아웃을 성공했을 때만 정리함 → 즉, revisionHistoryLimit보다 오래된 이전 버전들이 자동으로 정리됨
근데?
진행 중이거나 실패 중이면 제한보다 더 많은 이전 버전이 남아 있을 수 있음
근데?
0이면 롤백 못함. 이전 버전 없어서
revisionHistoryLimit: 3 → 가장 최근의 3개 버전까지만 롤백 가능
왜 중요한가?
너무 많은 ReplicaSet을 남기면:
- etcd 저장소 낭비
- kubectl get rs 목록 복잡해짐
너무 적게 설정하면:
- 이전 상태가 없어서 롤백이 어려움
7.2 카나리아 배포
"전체를 한 번에 바꾸지 말고, 조금씩 나눠서 새 버전을 테스트하자"라는 개념
예를 들어:
- 기존 버전 (
v1)을 가진 Deployment가 전체 100개 파드를 운영하고 있음.
- 새 버전(
v2)을 일부만 롤아웃하고 싶을 때:- v2 전용 Deployment를 따로 만들어 10개만 배포
- v1은 90개 그대로 유지
- v2의 동작이 안정적임을 확인한 뒤 → 점진적으로 수를 늘려나감
- v2 30개 / v1 70개 …
- 최종적으로 v2 100개 → v1 완전 제거
7.3 .spec.strategy
기존 파드를 새로운 파드로 어떻게 교체할지를 결정하는 전략 필드
7.3.1 RollingUpdate(기본값)
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 3 # or 30%, 전체 파드 중 최대 3개까지 동시 중단될 수 있음
maxSurge: 3 # or 30%, 전체 파드 10개면 최대 3개를 추가 생성할 수 있음
- maxUnavailable: 새 파드가 준비되기 전에 내려도 되는 기존 파드 수 (기본 25%)
- maxSurge: 의도한 파드 수보다 더 많이 생성해도 되는 새 파드 수 (기본 25%)
7.3.2 Recreate
strategy:
type: Recreate
- 먼저 기존 파드를 모두 종료하고
- 그 다음에 새 파드를 생성함
- 즉, 자원 충돌없이 새 버전만 동작(DB나 단일 인스턴스만 떠야하는 서비스에 적합)
8. 명령어 정리
| 명령어 | 설명 |
kubectl create -f [파일명] or kubectl apply -f [파일] |
리소스 생성 |
kubectl get deployment or kubectl descibe deployment |
디플로이먼트 상태 확인 |
kubectl rollout status deployment/[이름] |
디플로이먼트 진행 상태 확인 |
kubectl rollout status deployment/[deployment name] |
롤아웃 상태 확인 |
kubectl get pods —show-labels |
생성된 파드 라벨 확인 |
kubectl get replicaset or kubectl get rs |
ReplicaSet 목록 조회 |
kubectl rollout undo deployment/[deployment name] |
가장 최근의 이전 버전으로 롤백 |
kubectl rollout undo deployment/[deployment name] --to-revision=2 |
특정 수정 버전(예: 2번)으로 롤백 |
kubectl delete rs [이름] or kubectl delete rs [이름] [이름] |
삭제 및 여러개 삭제 |
kubectl replace -f [파일명] |
리소스 전체 교체 → 이거 뭔말임 |
kubectl edit rs [이름] 후 kubectl delete pod [이름] |
수정 및 반영(수정해도 자동으로 갱신 안됨) |
kubectl scale deployment/[이름] --replicas=N |
확장/축소 |
kubectl autoscale deploymenet/[이름] --min=10 --max=15 --cpu-percent=80 |
HPA |
'Cloud(Infra) > 공부' 카테고리의 다른 글
| [CKA]#6 Namespace (1) | 2025.05.30 |
|---|---|
| [CKA]#5 Service (0) | 2025.05.29 |
| [CKA]#3 쿠버네티스 ReplicaSet이란? 기본 파드보다 나은 이유 (0) | 2025.05.10 |
| [CKA]#2 Pods (0) | 2025.05.10 |
| [CKA]#1 쿠버네티스(Kubernetes)란 무엇인가 – 구성 요소 살펴보기 (0) | 2025.05.05 |
