2일차에서 nginx Pod를 직접 생성해봤지만, 실제 운영에서는 다음과 같은 문제가 있습니다:
| 워크로드 타입 | 용도 | 특징 |
|---|---|---|
| Deployment | 일반적인 애플리케이션 | 무중단 배포, 롤백, 스케일링 |
| ReplicaSet | Pod 복제본 관리 | Deployment가 내부적으로 사용 |
| DaemonSet | 모든 노드에서 실행 | 로깅, 모니터링 에이전트 |
| StatefulSet | 상태가 있는 애플리케이션 | 데이터베이스, 순서가 중요한 앱 |
| Job | 일회성 작업 | 배치 처리, 백업 |
| CronJob | 스케줄 작업 | 정기적인 배치 작업 |
# nginx-deployment.yaml
# Kubernetes API 버전을 지정합니다. Deployment는 apps/v1 API 그룹을 사용합니다.
# 이는 Kubernetes가 이 YAML을 올바른 API로 처리하도록 합니다.
apiVersion: apps/v1
# 리소스 유형을 정의합니다. 여기서는 Deployment로, 스테이트리스 애플리케이션을 관리합니다.
kind: Deployment
# Deployment의 메타데이터를 정의합니다. 이름, 네임스페이스, 라벨 등을 포함합니다.
metadata:
# Deployment의 고유 이름입니다. 클러스터 내에서 고유해야 합니다.
name: nginx-deployment
# Deployment가 배포될 네임스페이스입니다. 지정하지 않으면 'default'가 기본값입니다.
namespace: default
# Deployment 자체를 식별하기 위한 라벨입니다. 관리 및 쿼리에 사용됩니다.
labels:
app: nginx
# Deployment의 원하는 상태(desired state)를 정의합니다.
spec:
# 실행할 Pod의 개수를 지정합니다. 여기서는 3개의 Pod를 유지합니다.
replicas: 3
# Deployment가 관리할 Pod를 선택하기 위한 라벨 셀렉터입니다.
selector:
# Pod의 라벨과 일치해야 합니다. 여기서는 app=nginx인 Pod를 관리합니다.
matchLabels:
app: nginx
# Pod의 템플릿을 정의합니다. Deployment가 생성할 Pod의 모양을 지정합니다.
template:
# Pod의 메타데이터입니다. 주로 라벨을 정의합니다.
metadata:
# Pod에 붙일 라벨입니다. selector.matchLabels와 일치해야 합니다.
labels:
app: nginx
# Pod의 세부 설정(PodSpec)을 정의합니다. 컨테이너, 볼륨, 리소스 등을 포함합니다.
spec:
# Pod 내에서 실행할 컨테이너 목록입니다.
containers:
# 컨테이너의 이름입니다. Pod 내에서 고유해야 합니다.
- name: nginx
# 사용할 컨테이너 이미지입니다. 'nginx:latest'는 최신 nginx 이미지를 사용합니다.
image: nginx:latest
# 컨테이너가 노출할 포트를 정의합니다.
ports:
# 컨테이너 내부에서 열 포트입니다. 여기서는 HTTP 포트 80을 엽니다.
- containerPort: 80
# 컨테이너의 리소스 요청(requests)과 제한(limits)을 정의합니다.
resources:
# 최소 필요한 리소스를 지정합니다. 스케줄링 시 노드 선택에 사용됩니다.
requests:
# 최소 0.1 CPU 코어(100 milliCPU)를 요청합니다.
cpu: "100m"
# 최소 128MB 메모리를 요청합니다.
memory: "128Mi"
# 최대 사용 가능한 리소스를 제한합니다. 이를 초과하면 컨테이너가 종료될 수 있습니다.
limits:
# 최대 0.2 CPU 코어(200 milliCPU)를 사용할 수 있습니다.
cpu: "200m"
# 최대 256MB 메모리를 사용할 수 있습니다.
memory: "256Mi"
# 1. Deployment 생성
kubectl apply -f nginx-deployment.yaml
# 2. 상태 확인
kubectl get deployments
kubectl get pods
kubectl get replicasets
# 3. 세부 정보 확인
kubectl describe deployment nginx-deployment
🔍 관찰 포인트:
# 1. 수동 스케일링
kubectl scale deployment nginx-deployment --replicas=5
# 2. 상태 확인
kubectl get pods -w
# 3. 스케일 다운
kubectl scale deployment nginx-deployment --replicas=2
# 1. 현재 이미지 확인
kubectl describe deployment nginx-deployment | grep Image
# 2. 이미지 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
# 3. 롤아웃 과정 관찰
kubectl rollout status deployment/nginx-deployment
kubectl get pods -w
# 4. 롤아웃 히스토리 확인
kubectl rollout history deployment/nginx-deployment
# 1. 문제가 있는 이미지로 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:invalid-tag
# 2. 상태 확인 (실패 확인)
kubectl get pods
kubectl describe pod [pod-name]
# 3. 롤백 실행
kubectl rollout undo deployment/nginx-deployment
# 4. 롤백 확인
kubectl rollout status deployment/nginx-deployment
# 1. ReplicaSet 상세 정보
kubectl get replicasets -o wide
kubectl describe replicaset [replicaset-name]
# 2. ReplicaSet과 Pod 관계 확인
kubectl get pods --show-labels
# 1. Pod 하나 삭제
kubectl delete pod [pod-name]
# 2. 자동 복구 관찰
kubectl get pods -w
# 3. ReplicaSet 이벤트 확인
kubectl describe replicaset [replicaset-name]
DaemonSet은 클러스터의 모든 노드(또는 특정 노드)에서 Pod를 실행합니다.
# fluentd-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemonset
labels:
app: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluent/fluentd:v1.12
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
# 1. DaemonSet 생성
kubectl apply -f fluentd-daemonset.yaml
# 2. 상태 확인
kubectl get daemonsets
kubectl get pods -o wide
# 3. 노드별 Pod 분포 확인
kubectl get pods --all-namespaces -o wide | grep fluentd
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-statefulset
spec:
serviceName: mysql-service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "true"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
clusterIP: None
selector:
app: mysql
ports:
- port: 3306
# 1. StatefulSet 및 Service 생성
kubectl apply -f mysql-statefulset.yaml
# 2. 순차 배포 관찰
kubectl get pods -w
# 3. Pod 이름 패턴 확인
kubectl get pods
# mysql-statefulset-0, mysql-statefulset-1, mysql-statefulset-2
# 4. 스케일링 테스트
kubectl scale statefulset mysql-statefulset --replicas=5
kubectl get pods -w
# batch-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: batch-job
spec:
template:
spec:
containers:
- name: batch-worker
image: busybox
command: ["sh", "-c", "echo 'Batch job started'; sleep 30; echo 'Batch job completed'"]
restartPolicy: Never
backoffLimit: 4
# 1. Job 생성
kubectl apply -f batch-job.yaml
# 2. Job 상태 확인
kubectl get jobs
kubectl get pods
# 3. Job 로그 확인
kubectl logs [job-pod-name]
# 4. Job 완료 후 상태
kubectl get jobs
kubectl describe job batch-job
# backup-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-cronjob
spec:
schedule: "*/2 * * * *" # 2분마다 실행
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: busybox
command: ["sh", "-c", "echo 'Backup started at $(date)'; sleep 10; echo 'Backup completed'"]
restartPolicy: OnFailure
# 1. CronJob 생성
kubectl apply -f backup-cronjob.yaml
# 2. CronJob 상태 확인
kubectl get cronjobs
# 3. 실행되는 Job들 관찰
kubectl get jobs -w
# 4. 특정 실행 로그 확인
kubectl logs [cronjob-pod-name]
# 1. 현재 실행 중인 모든 워크로드 확인
kubectl get all
# 2. 각 워크로드의 특징 관찰
echo "=== Deployments ==="
kubectl get deployments -o wide
echo "=== DaemonSets ==="
kubectl get daemonsets -o wide
echo "=== StatefulSets ==="
kubectl get statefulsets -o wide
echo "=== Jobs ==="
kubectl get jobs
echo "=== CronJobs ==="
kubectl get cronjobs
# 1. 각 워크로드의 Pod 하나씩 강제 삭제
kubectl delete pod [deployment-pod-name]
kubectl delete pod [daemonset-pod-name]
kubectl delete pod [statefulset-pod-name]
# 2. 복구 동작 관찰
kubectl get pods -w
# 3. 복구 시간과 방식 비교 분석
| 시나리오 | 권장 워크로드 | 이유 |
|---|---|---|
| 웹 애플리케이션 | Deployment | 무중단 배포, 쉬운 스케일링 |
| 로그 수집기 | DaemonSet | 모든 노드에서 실행 필요 |
| 데이터베이스 | StatefulSet | 상태 보존, 순서 있는 배포 |
| 이미지 처리 | Job | 일회성 배치 작업 |
| 백업 작업 | CronJob | 정기적 실행 |
# 1. 생성한 모든 리소스 확인
kubectl get all
# 2. Deployment 삭제
kubectl delete deployment nginx-deployment
# 3. DaemonSet 삭제
kubectl delete daemonset fluentd-daemonset
# 4. StatefulSet 삭제 (Service 포함)
kubectl delete statefulset mysql-statefulset
kubectl delete service mysql-service
# 5. Job 삭제
kubectl delete job batch-job
# 6. CronJob 삭제
kubectl delete cronjob backup-cronjob
# 7. 최종 확인
kubectl get all
# 배포 관련
kubectl apply -f [file]
kubectl scale deployment [name] --replicas=[number]
kubectl set image deployment/[name] [container]=[image]
kubectl rollout status deployment/[name]
kubectl rollout undo deployment/[name]
# 상태 확인
kubectl get [resource-type]
kubectl describe [resource-type] [name]
kubectl logs [pod-name]
# 정리
kubectl delete [resource-type] [name]
이제 Pod 단위가 아닌 실제 운영에 적합한 다양한 배포 전략을 이해하고 실습해보셨습니다!