이종관
Back to Posts

컨테이너화 & 오케스트레이션 심화 가이드

멀티 스테이지 빌드, 이미지 보안, 고급 스케줄링, 서비스 매쉬

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-OK8s 전용
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 ConnectHashiCorp 생태계

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

컨테이너 오케스트레이션의 핵심은 선언적 구성, 자동화, 관찰성입니다. 적절한 도구와 패턴을 선택하여 안정적인 운영 환경을 구축하세요.