Deployment | ROAD TO CKA ☸️
Deployment를 사용하는 이유
일반적으로는 모든 파드를 죽이고 새로운 버전으로 다시 띄우는 replicaset 과는 다르게 롤링 업데이트의 이점을 활용하기 위해서 사용합니다.
| 기능 | 설명 |
|---|---|
| 롤백 (Rollback) | 업데이트 중 문제가 생기면 kubectl rollout undo 명령 한 번으로 이전 버전으로 즉시 되돌릴 수 있습니다. |
| 상태 기록 (History) | 어떤 변경 사항이 있었는지 버전을 기록하고 관리합니다. |
| 셀프 힐링 (Self-healing) | 파드가 죽으면 Deployment가 감지하고 설정된 개수만큼 다시 살려냅니다. |
| 스케일링 (Scaling) | 명령 하나로 파드의 개수를 늘리거나 줄이는 것이 매우 간편합니다. |
yaml 생성이 번거로운 경우 Tip
Create an NGINX Pod
kubectl run nginx --image=nginx
Generate POD Manifest YAML file (-o yaml). Don’t create it(–dry-run)
kubectl run nginx --image=nginx --dry-run=client -o yaml
Create a deployment
kubectl create deployment --image=nginx nginx
Generate Deployment YAML file (-o yaml). Don’t create it(–dry-run)
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml
Generate Deployment YAML file (-o yaml). Don’t create it(–dry-run) and save it to a file.
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml
Make necessary changes to the file (for example, adding more replicas) and then create the deployment.
kubectl create -f nginx-deployment.yaml
OR
In k8s version 1.19+, we can specify the –replicas option to create a deployment with 4 replicas.
kubectl create deployment --image=nginx nginx --replicas=4 --dry-run=client -o yaml > nginx-deployment.yaml
기본적인 Yaml 형태
yamlapiVersion: apps/v1 # Kubernetes API 버전 (Deployment는 보통 apps/v1 사용)
kind: Deployment # 생성하려는 리소스의 종류 (여기서는 배포 관리자인 Deployment)
metadata:
name: new-deployment # Deployment의 고유 이름
labels: # Deployment 자체를 식별하기 위한 라벨 (메타데이터)
app: new-deploy
tier: front-end
spec:
replicas: 3 # 상시 유지할 파드(Pod)의 개수
selector: # 어떤 파드를 이 Deployment가 관리할지 찾는 "조건"
matchLabels:
app: nginx-app # 아래 template에 정의된 labels와 반드시 일치해야 함
template: # 실제로 생성될 파드(Pod)의 설계도
metadata:
labels: # 생성될 파드들에 붙여질 라벨
app: nginx-app # 이 라벨을 보고 Deployment가 "내 자식이구나" 하고 인식함
spec:
containers: # 파드 내부에서 실행될 컨테이너 설정
- name: nginx # 컨테이너의 이름
image: nginx # 사용할 도커 이미지 (버전을 명시하지 않으면 최신버전:latest)
💡 작성 시 팁
- 라벨 매칭의 중요성:
spec.selector.matchLabels에 적힌 값과spec.template.metadata.labels에 적힌 값은 반드시 100% 일치해야 합니다. 만약 다르게 적으면 Deployment가 “내가 관리해야 할 파드가 어디 있지?” 하고 찾지 못해 오류가 발생합니다. - 업데이트 트리거: 나중에
image: nginx부분을image: nginx:1.21처럼 수정하고 다시 적용(apply)하면, Deployment가 이를 감지하고 우리가 아까 이야기한 롤링 업데이트를 자동으로 시작합니다. - Deployment 이름 vs 컨테이너 이름:
metadata.name은 ‘배포 관리자’의 이름이고,spec.template.spec.containers[0].name은 그 안에서 돌아가는 ‘실제 프로그램’의 이름입니다.
Practice
기본적으로 pod, replicaset, deployment 확인하기
bashcontrolplane ~ ➜ kubectl get pods
bashNAME READY STATUS RESTARTS AGE frontend-deployment-557f78f544-4sv4w 0/1 ImagePullBackOff 0 54s frontend-deployment-557f78f544-hhfhx 0/1 ImagePullBackOff 0 54s frontend-deployment-557f78f544-ph8cq 0/1 ImagePullBackOff 0 54s frontend-deployment-557f78f544-xrbdl 0/1 ErrImagePull 0 54s controlplane ~ ➜ kubectl get rs NAME DESIRED CURRENT READY AGE frontend-deployment-557f78f544 4 4 0 57s controlplane ~ ➜ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE frontend-deployment 0/4 4 0 62s
전체 확인하기
bashcontrolplane ~ ➜ kubectl get all
bashNAME READY STATUS RESTARTS AGE pod/frontend-deployment-557f78f544-4sv4w 0/1 ImagePullBackOff 0 83s pod/frontend-deployment-557f78f544-hhfhx 0/1 ImagePullBackOff 0 83s pod/frontend-deployment-557f78f544-ph8cq 0/1 ImagePullBackOff 0 83s pod/frontend-deployment-557f78f544-xrbdl 0/1 ImagePullBackOff 0 83s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 15m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/frontend-deployment 0/4 4 0 83s NAME DESIRED CURRENT READY AGE replicaset.apps/frontend-deployment-557f78f544 4 4 0 83s
간단하게 왜 에러가 나는지 확인하고 에러 수정하기
bashcontrolplane ~ ➜ kubectl describe pod frontend-deployment-557f78f544-4sv4w
bash...
Warning Failed 54s (x5 over 4m6s) kubelet Error: ErrImagePull
Normal BackOff 4s (x15 over 4m5s) kubelet Back-off pulling image "busybox888"
Warning Failed 4s (x15 over 4m5s) kubelet Error: ImagePullBackOff
- 이유는 없는 이미지를 pull 하고 있어서 ErrImagePull 에러가 발생한 것으로 확인
- edit 혹은 yaml 수정을 통해서 image 내용 수정하기!
새로운 Deployment 생성하기
yamlName: httpd-frontend;
Replicas: 3;
Image: httpd:2.4-alpine
yaml 생성해서 하기 (Iac 를 위해서)
bashcontrolplane ~ ✖ kubectl create deployment -h
Create a deployment with the specified name.
Aliases:
deployment, deploy
Examples:
# Create a deployment named my-dep that runs the busybox image
kubectl create deployment my-dep --image=busybox
# Create a deployment with a command
kubectl create deployment my-dep --image=busybox -- date
# Create a deployment named my-dep that runs the nginx image with 3 replicas
kubectl create deployment my-dep --image=nginx --replicas=3
# Create a deployment named my-dep that runs the busybox image and expose port
5701
kubectl create deployment my-dep --image=busybox --port=5701
# Create a deployment named my-dep that runs multiple containers
kubectl create deployment my-dep --image=busybox:latest --image=ubuntu:latest
--image=nginx
위에 참고해서 진행
bashcontrolplane ~ ➜ kubectl create deployment httpd-frontend --image=httpd:2.4-alpine --replicas=3 --dry-run=client -o yaml > httpd-frontend-deployment.yaml
bashcontrolplane ~ ➜ cat httpd-frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: httpd-frontend
name: httpd-frontend
spec:
replicas: 3
selector:
matchLabels:
app: httpd-frontend
strategy: {}
template:
metadata:
labels:
app: httpd-frontend
spec:
containers:
- image: httpd:2.4-alpine
name: httpd
resources: {}
status: {}
실행하기
bashcontrolplane ~ ✖ kubectl create -f httpd-frontend-deployment.yaml deployment.apps/httpd-frontend created