들어가며: 컨테이너가 기본값이 된 세상
2026년, 컨테이너는 더 이상 "혁신적인 기술"이 아닙니다. 신규 서비스를 컨테이너 없이 배포하는 것이 오히려 이상한 시대가 되었습니다. Kubernetes는 기업의 표준 인프라가 되었고, Docker는 개발 환경의 필수 도구로 자리잡았습니다.
하지만 컨테이너 생태계는 여전히 빠르게 변화하고 있습니다. Docker에서 Podman으로의 전환, containerd의 부상, GPU 워크로드를 위한 K8s 확장, 경량 K8s 배포판의 엣지 컴퓨팅 활용 등 2026년에 반드시 알아야 할 변화들이 있습니다. 이 글에서 전체 생태계를 정리합니다.
2026년 컨테이너 생태계는 containerd가 K8s 기본 런타임으로 자리잡고, Kubernetes가 82% 점유율로 사실상 오케스트레이션 표준이 되었습니다. Docker는 개발 환경에서 여전히 강세를 보이지만 Podman이 보안 중심 환경에서 빠르게 부상하고 있으며, AI/ML 워크로드를 위한 GPU 스케줄링과 경량 K8s(k3s/k0s)의 엣지 활용이 핵심 트렌드로 떠올랐습니다. 멀티스테이지 빌드, HPA, Spot 인스턴스, ArgoCD GitOps를 조합하면 안정성과 비용 효율을 동시에 잡을 수 있습니다.
1. 2026년 컨테이너 생태계 현황
컨테이너 런타임 시장 점유율
| 런타임 | 사용 비율 | 주요 사용처 |
|---|---|---|
| containerd | 58% | K8s 기본, 대부분의 퍼블릭 클라우드 |
| Docker Engine | 32% | 개발 환경, 레거시 프로덕션 |
| CRI-O | 7% | Red Hat OpenShift |
| Podman | 3% (빠르게 성장) | RHEL 환경, 보안 중시 |
오케스트레이션 플랫폼 현황
| 플랫폼 | 2024 점유율 | 2026 점유율 | 트렌드 |
|---|---|---|---|
| Kubernetes | 78% | 82% | ↑ |
| Docker Swarm | 12% | 6% | ↓↓ (지원 종료 수순) |
| Nomad | 5% | 6% | → |
| k3s/k0s (경량) | 3% | 5% | ↑ |
| Managed K8s (EKS/GKE/AKS) | 퍼블릭 클라우드 표준 | 표준 | ↑ |
2. Docker vs Podman vs containerd 심층 비교
각 도구의 핵심 차이
| 항목 | Docker | Podman | containerd |
|---|---|---|---|
| 데몬 | 있음 (root) | 없음 (daemonless) | 있음 |
| 루트리스 | 제한적 | 완전 지원 | 제한적 |
| K8s 호환 | (Docker shim 제거됨) | CRI-O 통해 | 직접 지원 |
| 컴포즈 지원 | Docker Compose v2 | podman-compose | 없음 |
| 이미지 빌드 | Dockerfile | Containerfile (동일 문법) | 별도 도구 필요 |
| OCI 준수 | 완전 | 완전 | 완전 |
| 라이선스 | Apache 2.0 | Apache 2.0 | Apache 2.0 |
| 기업 지원 | Docker Inc. | Red Hat | CNCF |
Docker: 여전한 개발 환경의 왕
# Docker 2026 주요 기능
# 1. Docker Scout - 취약점 분석 (무료 기본 제공)
docker scout quickview nginx:latest
docker scout cves nginx:latest --only-severity critical,high
# 2. docker init - 프로젝트 자동 설정
cd my-nodejs-project
docker init # 인터랙티브 Dockerfile + compose.yaml 생성
# 3. Build Secrets (보안 강화)
# 비밀값을 이미지 레이어에 남기지 않고 빌드 시 사용
docker build \
--secret id=mysecret,src=./secret.txt \
--tag myapp:latest .
# 대응 Dockerfile
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=secret,id=mysecret \
NPM_TOKEN=$(cat /run/secrets/mysecret) \
npm ci
COPY . .
CMD ["node", "server.js"]
# 4. Docker Desktop 없이 Colima 사용 (macOS, 무료)
brew install colima
colima start --cpu 4 --memory 8 --disk 60
docker ps # 바로 사용 가능
Dockerfile 모범 사례 2026
# syntax=docker/dockerfile:1
# ==========================================
# 2026 모범 사례 Dockerfile (Node.js 예시)
# ==========================================
# 1. 특정 버전 고정 (floating tag 사용 금지)
FROM node:20.11.0-alpine3.19 AS base
# 2. 최소 권한 원칙
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodeuser -u 1001
WORKDIR /app
# 3. 의존성 레이어 캐시 최적화 (소스 코드보다 먼저)
FROM base AS deps
COPY package.json package-lock.json ./
RUN npm ci --only=production && \
npm cache clean --force
# 4. 빌드 단계 분리 (멀티스테이지)
FROM base AS builder
COPY package.json package-lock.json ./
RUN npm ci # 개발 의존성 포함
COPY . .
RUN npm run build
# 5. 최종 이미지 (프로덕션용, 최소화)
FROM base AS runner
# 비루트 사용자로 실행
USER nodeuser
# 빌드 아티팩트만 복사
COPY --from=deps --chown=nodeuser:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodeuser:nodejs /app/dist ./dist
COPY --from=builder --chown=nodeuser:nodejs /app/package.json ./
# 포트 문서화
EXPOSE 3000
# 헬스체크
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
# 시그널 처리를 위해 exec 형태 사용
CMD ["node", "dist/server.js"]
멀티스테이지 빌드를 사용하면 최종 이미지에 빌드 도구와 개발 의존성이 포함되지 않아 이미지 크기를 최대 80%까지 줄일 수 있습니다. 반드시 특정 버전 태그(예: node:20.11.0-alpine3.19)를 고정하고, 루트가 아닌 사용자로 실행하도록 설정하세요. HEALTHCHECK와 시그널 처리(exec 형태 CMD)를 추가하면 프로덕션 안정성이 크게 향상됩니다.
Podman: 보안이 중요한 환경의 선택
# Podman 설치 및 기본 사용 (Docker와 완벽 호환 명령어)
# macOS
brew install podman
podman machine init --cpus 4 --memory 8192
podman machine start
# Docker 명령어와 완벽 호환
alias docker=podman # .bashrc/.zshrc에 추가
# Rootless 컨테이너 (보안 강점)
podman run --rm -it nginx:latest # root 권한 없이 실행
# Pod 기능 (K8s Pod 개념 로컬 구현)
podman pod create --name myapp-pod -p 8080:80
podman run -d --pod myapp-pod --name webapp nginx:latest
podman run -d --pod myapp-pod --name sidecar busybox sleep infinity
podman pod ps
# Kubernetes YAML 생성 (podman → K8s 배포 가능)
podman generate kube myapp-pod > myapp-pod.yaml
kubectl apply -f myapp-pod.yaml # K8s에 바로 배포!
# Podman Compose (Docker Compose 호환)
podman compose up -d
podman compose logs -f
3. Kubernetes 최신 버전 핵심 기능
K8s 1.30+ 주요 변경사항
# 1. Sidecar Container 공식 지원 (K8s 1.29+)
# 이전: init container 패턴으로 우회
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-with-sidecar
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
initContainers:
# Sidecar: 앱 컨테이너와 함께 라이프사이클 유지
- name: log-collector
image: fluent/fluent-bit:latest
restartPolicy: Always # ← 이것이 sidecar를 의미
volumeMounts:
- name: varlog
mountPath: /var/log
containers:
- name: webapp
image: myapp:latest
ports:
- containerPort: 8080
volumeMounts:
- name: varlog
mountPath: /app/logs
volumes:
- name: varlog
emptyDir: {}
# 2. In-Place Pod Vertical Scaling (K8s 1.27+, 안정화 진행 중)
# 재시작 없이 CPU/메모리 리소스 조정
apiVersion: v1
kind: Pod
metadata:
name: dynamic-resources
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # CPU는 재시작 없이 변경
- resourceName: memory
restartPolicy: RestartContainer # 메모리는 재시작 필요
완전한 K8s 배포 예시: 실전 프로덕션 패턴
# production-deployment.yaml
# 한국 스타트업이 많이 사용하는 패턴
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: production
labels:
app: api-server
version: "1.5.2"
team: backend
spec:
replicas: 3
# 롤링 업데이트 설정
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 최대 추가 생성 pod 수
maxUnavailable: 0 # 항상 replicas 수 유지
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
version: "1.5.2"
spec:
# 서비스 어카운트 (최소 권한)
serviceAccountName: api-server-sa
# 보안 컨텍스트 (Pod 레벨)
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
# 노드 분산 (토폴로지 스프레드)
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: api-server
containers:
- name: api-server
image: myregistry.io/api-server:1.5.2
# 포트
ports:
- containerPort: 8080
protocol: TCP
# 환경변수 (ConfigMap/Secret 참조)
env:
- name: APP_ENV
value: production
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
- name: REDIS_URL
valueFrom:
configMapKeyRef:
name: app-config
key: redis-url
# 리소스 제한 (필수!)
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
# 헬스체크
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30
periodSeconds: 10
# 컨테이너 보안
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
# 임시 쓰기 가능 디렉토리
volumeMounts:
- name: tmp
mountPath: /tmp
- name: logs
mountPath: /app/logs
volumes:
- name: tmp
emptyDir: {}
- name: logs
emptyDir: {}
# Graceful Shutdown
terminationGracePeriodSeconds: 60
---
# HPA (Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 2
periodSeconds: 60
---
# Service
apiVersion: v1
kind: Service
metadata:
name: api-server
namespace: production
spec:
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
# PodDisruptionBudget (가용성 보장)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
namespace: production
spec:
minAvailable: 2 # 항상 최소 2개 Pod 유지
selector:
matchLabels:
app: api-server
4. k3s vs k0s: 경량 K8s 비교
언제 경량 K8s가 필요한가?
| 사용 사례 | 일반 K8s | 경량 K8s |
|---|---|---|
| 엔터프라이즈 대규모 클러스터 | 권장 | 비권장 |
| 소규모 팀 자체 운영 클러스터 | 과도한 복잡성 | 권장 |
| 엣지/IoT 디바이스 | 불가 | 권장 |
| 개발/스테이징 환경 | 과도한 리소스 | 권장 |
| CI/CD 임시 클러스터 | 느림 | 권장 |
k3s vs k0s 비교표
| 항목 | k3s | k0s |
|---|---|---|
| 개발사 | Rancher (SUSE) | Mirantis |
| 바이너리 크기 | ~50MB | ~200MB |
| 최소 RAM | 512MB | 1GB |
| 기본 저장소 | SQLite (단일 노드) | etcd |
| 설치 방법 | 쉘 스크립트 | 바이너리 실행 |
| 고가용성 | 임베디드 etcd 지원 | 기본 지원 |
| K8s 호환성 | 완전 | 완전 |
| ARM 지원 | 완전 | 완전 |
| 엣지 지원 | 매우 강함 | 강함 |
k3s 실전 설치 및 설정
# k3s 마스터 노드 설치 (단일 명령)
curl -sfL https://get.k3s.io | sh -
# 또는 옵션 포함
curl -sfL https://get.k3s.io | \
INSTALL_K3S_VERSION="v1.29.3+k3s1" \
K3S_TOKEN="my-secret-token" \
sh -s - server \
--disable traefik \ # 기본 ingress 비활성화 (Nginx Ingress 사용 시)
--disable servicelb \ # MetalLB 사용 시
--node-name master-1 \
--tls-san "my-domain.com"
# 워커 노드 추가
K3S_URL="https://master-ip:6443" \
K3S_TOKEN="my-secret-token" \
curl -sfL https://get.k3s.io | sh -
# kubeconfig 설정
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get nodes
# k3s 상태 확인
systemctl status k3s
k3s kubectl get all -A
k0s 설치
# k0s 설치
curl -sSLf https://get.k0s.sh | sudo sh
# 컨트롤러 초기화
sudo k0s install controller --single # 단일 노드 모드
sudo k0s start
# kubeconfig 추출
sudo k0s kubeconfig admin > ~/.kube/config
kubectl get nodes
5. AI 워크로드를 위한 GPU 스케줄링
NVIDIA GPU Operator 설치
AI/ML 워크로드를 K8s에서 실행하려면 GPU 지원 설정이 필요합니다.
# Helm을 통한 NVIDIA GPU Operator 설치
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--create-namespace \
--set driver.enabled=true \
--set mig.strategy=single
# GPU 노드 확인
kubectl get nodes -l "nvidia.com/gpu=true"
kubectl describe node gpu-node-1 | grep -A10 "Allocatable"
GPU를 사용하는 AI 워크로드 배포
# gpu-inference-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-inference
namespace: ai-workloads
spec:
replicas: 1 # GPU 공유가 아니면 1로 시작
selector:
matchLabels:
app: llm-inference
template:
metadata:
labels:
app: llm-inference
spec:
# GPU 노드에만 배포
nodeSelector:
nvidia.com/gpu: "true"
nvidia.com/gpu.product: "NVIDIA-A100-SXM4-80GB" # 특정 GPU 모델
# GPU 독점 사용 보장
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: inference-server
image: myregistry.io/llm-server:latest
resources:
limits:
nvidia.com/gpu: "1" # GPU 1개 요청
memory: "32Gi"
cpu: "8"
requests:
nvidia.com/gpu: "1"
memory: "16Gi"
cpu: "4"
env:
- name: CUDA_VISIBLE_DEVICES
value: "0"
- name: MODEL_PATH
value: "/models/llama-3-8b"
ports:
- containerPort: 8000
volumeMounts:
- name: model-storage
mountPath: /models
readOnly: true
livenessProbe:
httpGet:
path: /v1/models
port: 8000
initialDelaySeconds: 120 # 모델 로딩 시간 고려
periodSeconds: 30
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-storage-pvc
---
# MIG (Multi-Instance GPU) 설정 - A100/H100 등
# 하나의 GPU를 여러 워크로드가 공유
apiVersion: v1
kind: Pod
metadata:
name: small-inference-job
spec:
containers:
- name: inference
image: myapp:latest
resources:
limits:
nvidia.com/mig-1g.10gb: "1" # A100을 7등분한 1 MIG 인스턴스
6. 서버리스 vs 컨테이너 선택 기준
2026년 선택 가이드
| 요소 | 컨테이너 (K8s) | 서버리스 |
|---|---|---|
| 콜드 스타트 | 없음 (항상 실행) | 있음 (수백ms ~ 수초) |
| 비용 (트래픽 낮음) | 높음 (항상 비용 발생) | 낮음 (실행 시만 과금) |
| 비용 (트래픽 높음) | 낮음 (최적화 가능) | 높음 |
| 상태 유지 | 가능 (Persistent Volume) | 어려움 |
| 실행 시간 제한 | 없음 | 있음 (보통 15분 ~ 1시간) |
| GPU 지원 | 완전 지원 | 제한적 |
| 배포 복잡도 | 높음 | 낮음 |
| 운영 부담 | 높음 | 낮음 |
| 디버깅 | 쉬움 | 어려움 |
| 벤더 종속 | 낮음 | 높음 |
컨테이너(K8s) 선택 시나리오:
- 항시 실행되는 API 서버, 웹 애플리케이션
- GPU 필요한 AI/ML 워크로드
- 복잡한 마이크로서비스 아키텍처
- 데이터 처리 파이프라인 (긴 실행 시간)
서버리스 선택 시나리오:
- 이벤트 기반 처리 (이미지 리사이징, 알림 전송)
- 낮은 트래픽 API
- 스케줄 기반 배치 작업
- MVP/초기 단계 프로젝트
LLM 추론, 모델 학습, 배치 임베딩 처리 등 AI/ML 워크로드는 GPU 지원, 긴 실행 시간, 대용량 모델 스토리지가 필요하기 때문에 서버리스로는 한계가 뚜렷합니다. NVIDIA GPU Operator와 MIG(Multi-Instance GPU) 기능을 활용하면 K8s 클러스터에서 GPU를 효율적으로 분할하여 여러 워크로드가 공유할 수 있어 GPU 활용률과 비용 효율을 동시에 높일 수 있습니다.
7. 비용 최적화 전략
K8s 비용 절감 실전 팁
# 1. Vertical Pod Autoscaler (VPA) - 적정 리소스 자동 설정
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Auto" # 또는 "Off" (추천만), "Initial" (최초 생성만)
resourcePolicy:
containerPolicies:
- containerName: api-server
minAllowed:
cpu: "100m"
memory: "128Mi"
maxAllowed:
cpu: "2000m"
memory: "2Gi"
---
# 2. Spot/Preemptible 노드 활용 (비용 60~80% 절감)
# AWS EKS 예시: Spot 인스턴스 노드그룹
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: ap-northeast-2
managedNodeGroups:
# 온디맨드 (중요 워크로드)
- name: on-demand
instanceType: m5.xlarge
desiredCapacity: 2
labels:
node-type: on-demand
# Spot (비용 최적화)
- name: spot
instanceTypes: ["m5.xlarge", "m5.2xlarge", "m4.xlarge", "m4.2xlarge"]
spot: true
desiredCapacity: 3
labels:
node-type: spot
taints:
- key: spot
value: "true"
effect: NoSchedule
# Spot 노드 허용 워크로드 (중단 허용)
spec:
tolerations:
- key: "spot"
operator: "Equal"
value: "true"
effect: "NoSchedule"
nodeSelector:
node-type: spot
# Spot 중단 처리 (2분 전 경고 활용)
terminationGracePeriodSeconds: 120
# kubecost 대안: 비용 분석 스크립트
import subprocess
import json
def get_pod_cost_estimate():
"""kubectl을 통한 리소스 사용량 기반 비용 추정"""
# 노드별 리소스 가격 (AWS ap-northeast-2 기준, m5.xlarge)
node_hourly_cost = {
"on-demand": 0.192, # USD/시간
"spot": 0.058, # USD/시간 (평균)
}
# 현재 실행 중인 Pod 리소스 조회
result = subprocess.run(
["kubectl", "top", "pods", "--all-namespaces", "--no-headers"],
capture_output=True, text=True
)
pods = []
for line in result.stdout.strip().split('\n'):
if line:
parts = line.split()
pods.append({
"namespace": parts[0],
"pod": parts[1],
"cpu_m": int(parts[2].rstrip('m')),
"memory_mi": int(parts[3].rstrip('Mi')),
})
# 월간 비용 추정 (m5.xlarge: 4 vCPU, 16GB RAM 기준)
vcpu_cost_per_hour = node_hourly_cost["on-demand"] / 4
memory_cost_per_hour = node_hourly_cost["on-demand"] / 16
total_monthly = 0
for pod in pods:
cpu_cost = (pod["cpu_m"] / 1000) * vcpu_cost_per_hour * 24 * 30
mem_cost = (pod["memory_mi"] / 1024) * memory_cost_per_hour * 24 * 30
pod_cost = cpu_cost + mem_cost
total_monthly += pod_cost
print(f"{pod['namespace']}/{pod['pod']}: ${pod_cost:.2f}/월")
print(f"\n전체 추정 비용: ${total_monthly:.2f}/월")
get_pod_cost_estimate()
AWS Spot 인스턴스는 비용을 60~80% 절감할 수 있지만, 2분 전 통보 후 강제 종료될 수 있습니다. 상태를 유지하는 데이터베이스, 캐시 서버, 결제 처리 등 중요 워크로드에는 절대 Spot을 사용하지 마세요. terminationGracePeriodSeconds를 120초로 설정하고, PodDisruptionBudget으로 최소 가용 Pod 수를 보장하며, 중단 허용 워크로드(배치, 비동기 처리)에만 Spot을 적용하는 것이 안전합니다.
8. 한국 스타트업이 많이 사용하는 패턴
2026년 한국 스타트업 K8s 스택
국내 스타트업들의 인프라 패턴을 분석한 결과:
클라우드 제공자 선택:
| 규모 | 선택 클라우드 | 이유 |
|---|---|---|
| 초기 스타트업 | AWS (EKS) | 생태계, 레퍼런스 풍부 |
| 네이버/카카오 협력사 | NCP (NKS) | 파트너십, 국내 지원 |
| 글로벌 지향 | GCP (GKE) + AWS | GKE 관리 편의성 |
| 비용 절감 중시 | AWS + Spot | Spot 적극 활용 |
인기 스택 조합 (한국 스타트업 기준):
인프라: AWS EKS (서울 리전)
├── 컨테이너 레지스트리: ECR 또는 GitHub Container Registry
├── CI/CD: GitHub Actions + ArgoCD
├── 모니터링: Grafana + Prometheus + Loki
├── 서비스 메시: Istio 또는 없음 (소규모)
├── Ingress: Nginx Ingress Controller + AWS ALB
├── 인증서: cert-manager + Let's Encrypt
├── 시크릿 관리: AWS Secrets Manager + External Secrets
└── 비용 최적화: Karpenter (노드 자동 프로비저닝)
ArgoCD를 통한 GitOps 패턴
# argocd-app.yaml - GitOps 배포 설정
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-server
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/mycompany/k8s-manifests
targetRevision: main
path: apps/api-server/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # Git에서 삭제된 리소스 자동 제거
selfHeal: true # 수동 변경 자동 복구
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Karpenter로 비용 최적화 (AWS EKS)
# karpenter-nodepool.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
metadata:
labels:
managed-by: karpenter
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"] # Spot 우선, 불가 시 On-Demand
- key: karpenter.k8s.aws/instance-family
operator: In
values: ["m5", "m5d", "m6i", "c5", "c6i"]
- key: kubernetes.io/arch
operator: In
values: ["amd64", "arm64"] # ARM도 지원
disruption:
consolidationPolicy: WhenUnderutilized # 비용 최적화 통합
consolidateAfter: 30s
limits:
cpu: 1000
memory: 1000Gi
9. 2026년 컨테이너 트렌드 전망
WebAssembly (WASM) + 컨테이너
# WASM 워크로드를 K8s에서 실행 (실험적)
# containerd + runwasi shim 설치 필요
# WASM 컨테이너 배포 예시
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: wasm-app
spec:
replicas: 1
selector:
matchLabels:
app: wasm-app
template:
metadata:
labels:
app: wasm-app
annotations:
module.wasm.image/variant: compat-smart
spec:
runtimeClassName: wasmtime # WASM 런타임
containers:
- name: wasm-app
image: myregistry.io/my-wasm-app:latest
command: ["/app.wasm"]
EOF
컨테이너 보안 강화 트렌드
# 2026년 K8s 보안 모범 사례
apiVersion: v1
kind: Namespace
metadata:
name: secure-workloads
labels:
pod-security.kubernetes.io/enforce: restricted # Pod Security Standards
---
# Network Policy (기본 deny-all)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 필요한 통신만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-server-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
role: ingress-controller
ports:
- port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- port: 5432
결론
2026년 컨테이너/K8s 생태계에서 핵심은 다음과 같습니다.
즉시 적용해야 할 것들:
- Dockerfile 멀티스테이지 빌드 + 보안 모범 사례 적용
- HPA + PDB로 가용성과 자동확장 설정
- Spot 인스턴스로 비용 30~60% 절감
- ArgoCD 기반 GitOps로 배포 자동화
2026~2027년 주목할 것들:
- WASM 컨테이너의 실용화
- AI 워크로드를 위한 GPU 스케줄링 고도화
- eBPF 기반 네트워킹(Cilium)의 표준화
- Kubernetes SIG별 기능 안정화 (VPA, sidecar 등)
컨테이너와 K8s는 이미 성숙한 기술이지만, 생태계는 여전히 발전 중입니다. 기본기를 탄탄히 하고, 새로운 기능은 파일럿 프로젝트로 검증하면서 점진적으로 도입하는 전략이 가장 현명합니다.
- 2026년 컨테이너 런타임은 containerd(58%)가 주도하고, Kubernetes(82%)가 오케스트레이션 표준으로 완전히 자리잡았다. Docker Swarm은 사실상 레거시로 전환 중이다.
- Dockerfile은 멀티스테이지 빌드·버전 고정·비루트 사용자·HEALTHCHECK를 모두 적용해야 2026년 프로덕션 기준을 충족한다. Podman은 rootless 실행이 필요한 보안 환경에서 Docker의 강력한 대안이다.
- AI/ML 워크로드는 NVIDIA GPU Operator와 MIG를 활용해 K8s에서 GPU를 효율적으로 스케줄링하고, 서버리스 대신 컨테이너(K8s)를 선택해야 GPU 지원과 긴 실행 시간을 보장받을 수 있다.
- 비용 최적화의 핵심은 Spot 인스턴스(60~80% 절감) + Karpenter 자동 프로비저닝 + VPA 적정 리소스 설정이며, ArgoCD GitOps로 배포를 자동화하면 운영 부담도 함께 줄일 수 있다.
TechPulse 테크펄스에서 DevOps/클라우드 네이티브 관련 심층 콘텐츠를 계속 발행합니다.