컨테이너화 & 오케스트레이션 심화 가이드
멀티 스테이지 빌드, 이미지 보안, 고급 스케줄링, 서비스 매쉬
2025년 2월 6일·5 min read·
infra
docker
kubernetes
containerization
orchestration
service-mesh
image-security
1. 고급 컨테이너 빌드 전략
멀티 스테이지 빌드
빌드 환경과 런타임 환경을 분리하여 이미지 크기 최소화
# 빌드 스테이지
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o main .
# 런타임 스테이지
FROM alpine:3.18
COPY --from=builder /app/main /main
CMD ["/main"]
이미지 레이어 최적화
# Bad: 캐시 효율 낮음
COPY . .
RUN npm install
# Good: 캐시 효율 높음
COPY package*.json ./
RUN npm install
COPY . .
이미지 보안
| 도구 | 용도 |
|---|---|
| Trivy | 취약점 스캔 |
| Notary | 이미지 서명 |
| distroless | 경량 베이스 이미지 |
# Trivy로 취약점 스캔
trivy image my-app:latest
2. 리소스 격리와 튜닝
cgroups & Namespaces
Linux 커널 레벨에서 CPU, 메모리, I/O, 네트워크 격리
# Kubernetes 리소스 제한
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
컨테이너 런타임
| 런타임 | 특징 |
|---|---|
| containerd | 경량, K8s 기본 |
| CRI-O | K8s 전용 |
| gVisor | 보안 샌드박스 |
Rootless 컨테이너
호스트 루트 권한 없이 컨테이너 실행
# Podman rootless 모드
podman run --user 1000:1000 nginx
3. 고급 스케줄링
Node Affinity
특정 노드에 Pod 배치
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
Pod Anti-Affinity
같은 종류의 Pod를 다른 노드에 분산
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
Taint & Toleration
노드에 Taint 설정하여 특정 Pod만 허용
# 노드에 Taint 추가
kubectl taint nodes gpu-node gpu=true:NoSchedule
# Pod에 Toleration 추가
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
4. 서비스 메쉬
서비스 메쉬란?
마이크로서비스 간 통신을 관리하는 인프라 레이어
| 기능 | 설명 |
|---|---|
| 트래픽 제어 | 라우팅, 로드밸런싱 |
| 보안 | mTLS 자동 적용 |
| 관찰성 | 분산 트레이싱 |
주요 솔루션
| 솔루션 | 특징 |
|---|---|
| Istio | 가장 많은 기능, 복잡도 높음 |
| Linkerd | 경량, 사용 쉬움 |
| Consul Connect | HashiCorp 생태계 |
Sidecar 패턴
┌─────────────────────────┐
│ Pod │
├───────────┬─────────────┤
│ App │ Envoy │
│ Container │ (Sidecar) │
└───────────┴─────────────┘
애플리케이션 코드 수정 없이 네트워크 기능 추가
5. 스토리지 오케스트레이션
CSI (Container Storage Interface)
다양한 스토리지를 일관되게 사용
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
동적 프로비저닝
PVC 생성 시 자동으로 PV 할당
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
storageClassName: fast
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
6. 오토 스케일링
HPA (Horizontal Pod Autoscaler)
CPU/메모리 기반 자동 스케일링
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
KEDA (Kubernetes Event-Driven Autoscaling)
이벤트 기반 정밀 스케일링
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-scaler
spec:
scaleTargetRef:
name: consumer
triggers:
- type: kafka
metadata:
topic: orders
lagThreshold: "100"
7. Observability
모니터링 스택
Prometheus → Grafana (메트릭)
Fluentd → Elasticsearch → Kibana (로그)
Jaeger/Zipkin (트레이싱)
GitOps
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Git │───▶│ Argo CD │───▶│ K8s │
│ Repo │ │ /Flux │ │ Cluster │
└─────────┘ └─────────┘ └─────────┘
Git 저장소가 Single Source of Truth
정리
| 영역 | 핵심 기술 |
|---|---|
| 빌드 | 멀티 스테이지, 이미지 스캔 |
| 스케줄링 | Affinity, Taint/Toleration |
| 네트워킹 | 서비스 메쉬, CNI |
| 스토리지 | CSI, 동적 프로비저닝 |
| 스케일링 | HPA, VPA, KEDA |
| 운영 | GitOps, Observability |
컨테이너 오케스트레이션의 핵심은 선언적 구성, 자동화, 관찰성입니다. 적절한 도구와 패턴을 선택하여 안정적인 운영 환경을 구축하세요.