컨테이너화 & 오케스트레이션 심화 가이드
멀티 스테이지 빌드, 이미지 보안, 고급 스케줄링, 서비스 메시 등 컨테이너 심화 운영
2025년 2월 6일5 min read
문서 목차
컨테이너는 애플리케이션과 실행 환경을 하나의 패키지로 묶어 어디서든 동일하게 동작하도록 보장한다. 컨테이너 수가 늘어나면 배포, 네트워킹, 스토리지, 장애 복구를 자동화하는 오케스트레이션이 필요해진다.
고급 컨테이너 빌드 전략
멀티 스테이지 빌드
빌드 환경과 런타임 환경을 분리하여 이미지 크기 최소화
dockerfile
# 빌드 스테이지
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"]이미지 레이어 최적화
dockerfile
# Bad: 캐시 효율 낮음
COPY . .
RUN npm install
# Good: 캐시 효율 높음
COPY package*.json ./
RUN npm install
COPY . .이미지 보안
| 도구 | 용도 |
|---|---|
| Trivy | 취약점 스캔 |
| Notary | 이미지 서명 |
| distroless | 경량 베이스 이미지 |
bash
# Trivy로 취약점 스캔
trivy image my-app:latest리소스 격리와 튜닝
cgroups & Namespaces
Linux 커널 레벨에서 CPU, 메모리, I/O, 네트워크 격리
yaml
# Kubernetes 리소스 제한
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"컨테이너 런타임
| 런타임 | 특징 |
|---|---|
| containerd | 경량, K8s 기본 |
| CRI-O | K8s 전용 |
| gVisor | 보안 샌드박스 |
Rootless 컨테이너
호스트 루트 권한 없이 컨테이너 실행
bash
# Podman rootless 모드
podman run --user 1000:1000 nginx고급 스케줄링
Node Affinity
특정 노드에 Pod 배치
yaml
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"Pod Anti-Affinity
같은 종류의 Pod를 다른 노드에 분산
yaml
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostnameTaint & Toleration
노드에 Taint 설정하여 특정 Pod만 허용
bash
# 노드에 Taint 추가
kubectl taint nodes gpu-node gpu=true:NoScheduleyaml
# Pod에 Toleration 추가
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"서비스 메쉬
서비스 메쉬란?
마이크로서비스 간 통신을 관리하는 인프라 레이어
| 기능 | 설명 |
|---|---|
| 트래픽 제어 | 라우팅, 로드밸런싱 |
| 보안 | mTLS 자동 적용 |
| 관찰성 | 분산 트레이싱 |
주요 솔루션
| 솔루션 | 특징 |
|---|---|
| Istio | 가장 많은 기능, 복잡도 높음 |
| Linkerd | 경량, 사용 쉬움 |
| Consul Connect | HashiCorp 생태계 |
Sidecar 패턴
애플리케이션 코드 수정 없이 네트워크 기능 추가
스토리지 오케스트레이션
CSI (Container Storage Interface)
다양한 스토리지를 일관되게 사용
yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer동적 프로비저닝
PVC 생성 시 자동으로 PV 할당
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
storageClassName: fast
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi오토 스케일링
HPA (Horizontal Pod Autoscaler)
CPU/메모리 기반 자동 스케일링
yaml
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: 70KEDA (Kubernetes Event-Driven Autoscaling)
이벤트 기반 정밀 스케일링
yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-scaler
spec:
scaleTargetRef:
name: consumer
triggers:
- type: kafka
metadata:
topic: orders
lagThreshold: "100"Observability
모니터링 스택
- 메트릭:
Prometheus -> Grafana - 로그:
Fluentd -> Elasticsearch -> Kibana - 트레이싱:
Jaeger또는Zipkin
GitOps
Git 저장소가 Single Source of Truth
정리
| 영역 | 핵심 기술 |
|---|---|
| 빌드 | 멀티 스테이지, 이미지 스캔 |
| 스케줄링 | Affinity, Taint/Toleration |
| 네트워킹 | 서비스 메쉬, CNI |
| 스토리지 | CSI, 동적 프로비저닝 |
| 스케일링 | HPA, VPA, KEDA |
| 운영 | GitOps, Observability |
컨테이너 오케스트레이션의 핵심은 선언적 구성, 자동화, 관찰성이다. 적절한 도구와 패턴을 선택하여 안정적인 운영 환경을 구축하는 것이 핵심이다.