# Kubernetes Best Practices Handbook (2nd Edition) ## 개요 **"Kubernetes Best Practices: Blueprints for Building Successful Applications on Kubernetes (2nd Edition)"**은 Kubernetes 실무에서 검증된 최고의 관행을 다룬 실용 가이드입니다. 4명의 Kubernetes 전문가가 작성했으며, 분산 시스템과 엔터프라이즈 애플리케이션 경험을 담았습니다. ## 핵심 Best Practices ### 1. 리소스 명시적 설정 (Resource Requests & Limits) #### 문제 ```yaml # 나쁜 예: 리소스 제한 없음 apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: myapp:latest # → CPU/메모리 제한 없음 # → Pod 간 리소스 경쟁 (Noisy Neighbor) # → 예상 불가능한 성능 저하 ``` #### 해결책 ```yaml # 좋은 예: 명시적 리소스 설정 apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 template: spec: containers: - name: app image: myapp:latest resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" ``` #### 효과 | 항목 | 설정 전 | 설정 후 | |-----|---------|--------| | 노드 활용률 | ~45% | ~85% | | Pod 안정성 | 낮음 (OOM Killed) | 높음 | | 자동 스케일링 | 부정확 | 정확 | | 비용 최적화 | 낭비 | 효율적 | **Best Practice**: 항상 requests와 limits를 명시적으로 설정하세요. ### 2. 네임스페이스로 논리적 분할 #### 구조 ``` 클러스터 ├── default (기본) ├── production │ ├── payment-service │ ├── user-service │ └── inventory-service ├── staging │ ├── payment-service │ ├── user-service │ └── inventory-service ├── development ├── monitoring └── system (Kubernetes 내부) ``` #### 이점 1. **Blast Radius 제한**: 한 네임스페이스의 오류가 다른 곳에 영향 없음 2. **접근 제어**: RBAC로 팀별 권한 관리 3. **리소스 쿼터**: 네임스페이스별 리소스 제한 4. **환경 분리**: Dev/Staging/Prod 명확한 구분 #### 구현 ```bash # 네임스페이스 생성 kubectl create namespace production # 네임스페이스별 리소스 쿼터 kubectl create quota prod-quota \ --hard=requests.cpu=10,requests.memory=20Gi \ -n production ``` **Best Practice**: 네임스페이스로 환경과 팀을 분리하세요. ### 3. 네트워크 정책 (Network Policies) #### 기본 문제 ``` 기본 설정: 모든 Pod이 모든 Pod과 통신 가능 → 보안 위협: 한 Pod 침해 = 전체 클러스터 침해 ``` #### 해결책: 네트워크 정책 ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all spec: podSelector: {} # 모든 Pod policyTypes: - Ingress - Egress # → 명시적 허용만 가능 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-payment-to-db spec: podSelector: matchLabels: app: database policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: payment-service ports: - protocol: TCP port: 5432 ``` #### 효과 ``` 통신 흐름: payment-service → (허용) → database user-service → (거부) → database payment-service → (거부) → user-service ``` **Best Practice**: 기본으로 deny-all 설정, 필요한 것만 명시적 허용. ### 4. 보안 강화 (Security Hardening) #### 4.1 최소 권한 원칙 (Least Privilege) ```yaml apiVersion: v1 kind: Pod metadata: name: secure-app spec: containers: - name: app image: myapp:latest securityContext: runAsNonRoot: true runAsUser: 1000 readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL ``` **설정 항목**: - `runAsNonRoot: true` — root 실행 금지 - `readOnlyRootFilesystem: true` — 읽기 전용 파일시스템 - `allowPrivilegeEscalation: false` — 권한 상승 금지 - `capabilities.drop: ALL` — 모든 Linux 권한 제거 #### 4.2 Pod Security Standards (PSS) ```yaml # v1.25 이상에서 권장 apiVersion: v1 kind: Namespace metadata: name: production labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/warn: restricted ``` **3가지 레벨**: 1. **Privileged** — 권한 제약 없음 (권장하지 않음) 2. **Baseline** — 알려진 취약점 방지 3. **Restricted** — 최고 강화 (권장) #### 4.3 이미지 스캔 ```bash # 이미지 취약점 스캔 trivy image myapp:latest # 정책: 모든 이미지는 스캔되고 승인된 레지스트리에서만 사용 kubectl apply -f - <<EOF apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: image-policy spec: rules: - operations: ["CREATE"] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] EOF ``` ### 5. 헬스 체크 (Liveness & Readiness Probes) #### 문제 ``` Pod이 실행 중이지만 응답하지 않음 → 트래픽이 계속 이 Pod으로 라우팅됨 → 사용자 경험 저하 ``` #### 해결책 ```yaml apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: myapp:latest # 1. Readiness Probe (서비스 준비 상태) readinessProbe: httpGet: path: /health/ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 # 2. Liveness Probe (Pod 생사 확인) livenessProbe: httpGet: path: /health/live port: 8080 initialDelaySeconds: 15 periodSeconds: 20 timeoutSeconds: 3 failureThreshold: 3 ``` #### 워크플로우 ``` Pod 시작 ↓ (initialDelaySeconds: 5) Readiness Check → PASS → Service에 트래픽 유입 ↓ (계속 체크) 건강 유지 → 트래픽 유지 ↓ (readiness fail) Service에서 제거 (트래픽 중단) ↓ (liveness fail × 3번) Pod 재시작 ``` ### 6. 무중단 배포 (Rolling Updates) #### 전략 ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 5 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 추가로 1개 Pod 허용 maxUnavailable: 1 # 동시에 1개 Pod만 종료 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: myapp:v2 ``` #### 배포 순서 ``` 이전 상태: [Pod v1 v1 v1 v1 v1] ↓ 단계 1: [Pod v1 v1 v1 v1 v1 Pod v2] (maxSurge=1) ↓ 단계 2: [Pod v1 v1 v1 v1 Pod v2] (maxUnavailable=1로 1개 종료) ↓ 반복... 최종 상태: [Pod v2 v2 v2 v2 v2] ``` ## 도메인별 Best Practices ### 데이터베이스 관련 - StatefulSet 사용 (순서, 식별 가능한 네트워크 ID) - 영구 저장소(PersistentVolume) 필수 - 백업 정책 수립 ### 로깅 & 모니터링 - 중앙화된 로깅 (ELK, Loki) - 메트릭 수집 (Prometheus) - 알림 정책 (Alertmanager) ### CI/CD 통합 - 이미지 스캔 및 승인 - 테스트 자동화 - GitOps 원칙 (ArgoCD, Flux) ## 2nd Edition의 신규 내용 - **Kubernetes 1.30+ 최신 기능** - **AI/ML 워크로드** 관리 - **비용 최적화** 전략 - **멀티 클러스터** 관리 - **서비스 메시 (Istio)** 통합 ## 실무 체크리스트 ``` 배포 전 점검: □ 리소스 요청/제한 설정 □ 네임스페이스 분리 □ RBAC 설정 □ 네트워크 정책 적용 □ 헬스 체크 구성 □ 보안 컨텍스트 설정 □ 이미지 스캔 완료 □ 로깅/모니터링 준비 □ 백업 정책 수립 □ 무중단 배포 테스트 ``` ## 참고 더 자세한 보안 관련 내용은 DoD/NSA Kubernetes Hardening Guidance 참고.