# 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 참고.