Kubernetes 배포 가이드
Caffeine Framework를 Kubernetes 클러스터에 배포하는 가이드입니다.
📋 개요
프로덕션 환경을 위한 Kubernetes 배포 전략과 구성을 다룹니다.
학습 시간: 90분
난이도: ⭐⭐⭐ 고급
🏗️ 아키텍처
📁 디렉토리 구조
k8s/
├── namespace.yaml
├── configmap.yaml
├── secrets.yaml
├── postgresql/
│ ├── statefulset.yaml
│ ├── service.yaml
│ └── pvc.yaml
├── redis/
│ ├── deployment.yaml
│ └── service.yaml
├── influxdb/
│ ├── statefulset.yaml
│ ├── service.yaml
│ └── pvc.yaml
├── caffeine-server/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── hpa.yaml
├── drivers/
│ └── modbus-driver.yaml
└── ingress.yaml
🚀 배포 매니페스트
Namespace
apiVersion: v1
kind: Namespace
metadata:
name: caffeine
labels:
name: caffeine
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: caffeine-config
namespace: caffeine
data:
aspnetcore-environment: "Production"
server-url: "http://caffeine-server:5001"
redis-host: "redis:6379"
influxdb-url: "http://influxdb:8086"
Secrets
apiVersion: v1
kind: Secret
metadata:
name: caffeine-secrets
namespace: caffeine
type: Opaque
stringData:
postgres-password: "change-me-in-production"
influxdb-admin-password: "change-me-in-production"
api-key: "your-api-key-here"
PostgreSQL StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: caffeine
spec:
serviceName: postgresql
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
containers:
- name: postgresql
image: postgres:16-alpine
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_DB
value: "caffeine"
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: caffeine-secrets
key: postgres-password
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
exec:
command:
- sh
- -c
- pg_isready -U postgres
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- sh
- -c
- pg_isready -U postgres
initialDelaySeconds: 5
periodSeconds: 5
volumeClaimTemplates:
- metadata:
name: postgres-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: postgresql
namespace: caffeine
spec:
clusterIP: None
selector:
app: postgresql
ports:
- port: 5432
targetPort: 5432
Redis Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: caffeine
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
ports:
- containerPort: 6379
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumeMounts:
- name: redis-storage
mountPath: /data
volumes:
- name: redis-storage
persistentVolumeClaim:
claimName: redis-pvc
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: caffeine
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: caffeine
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Caffeine Server Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: caffeine-server
namespace: caffeine
spec:
replicas: 3
selector:
matchLabels:
app: caffeine-server
template:
metadata:
labels:
app: caffeine-server
spec:
containers:
- name: caffeine-server
image: nexcode/caffeine-server:2.0
ports:
- containerPort: 5001
name: http
- containerPort: 5002
name: grpc
env:
- name: ASPNETCORE_ENVIRONMENT
valueFrom:
configMapKeyRef:
name: caffeine-config
key: aspnetcore-environment
- name: ConnectionStrings__PostgreSQL
value: "Host=postgresql;Database=caffeine;Username=postgres;Password=$(POSTGRES_PASSWORD)"
- name: ConnectionStrings__Redis
valueFrom:
configMapKeyRef:
name: caffeine-config
key: redis-host
- name: ConnectionStrings__InfluxDB
valueFrom:
configMapKeyRef:
name: caffeine-config
key: influxdb-url
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: caffeine-secrets
key: postgres-password
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /health
port: 5001
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 5001
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: caffeine-server
namespace: caffeine
spec:
type: ClusterIP
selector:
app: caffeine-server
ports:
- name: http
port: 5001
targetPort: 5001
- name: grpc
port: 5002
targetPort: 5002
HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: caffeine-server-hpa
namespace: caffeine
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: caffeine-server
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: caffeine-ingress
namespace: caffeine
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- caffeine.example.com
secretName: caffeine-tls
rules:
- host: caffeine.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: caffeine-server
port:
number: 5001
Driver Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: modbus-driver
namespace: caffeine
spec:
replicas: 2
selector:
matchLabels:
app: modbus-driver
template:
metadata:
labels:
app: modbus-driver
spec:
containers:
- name: modbus-driver
image: mycompany/modbus-driver:latest
env:
- name: Caffeine__ServerUrl
valueFrom:
configMapKeyRef:
name: caffeine-config
key: server-url
- name: Driver__Host
value: "192.168.1.100"
- name: Driver__Port
value: "502"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
🚀 배포 실행
kubectl 사용
# Namespace 생성
kubectl apply -f namespace.yaml
# ConfigMap과 Secrets
kubectl apply -f configmap.yaml
kubectl apply -f secrets.yaml
# Database 배포
kubectl apply -f postgresql/
kubectl apply -f redis/
kubectl apply -f influxdb/
# 데이터베이스가 Ready 상태인지 확인
kubectl wait --for=condition=ready pod -l app=postgresql -n caffeine --timeout=300s
kubectl wait --for=condition=ready pod -l app=redis -n caffeine --timeout=300s
# Caffeine Server 배포
kubectl apply -f caffeine-server/
# Driver 배포
kubectl apply -f drivers/
# Ingress 배포
kubectl apply -f ingress.yaml
Helm 차트 (권장)
# Helm 차트 설치
helm install caffeine ./charts/caffeine \
--namespace caffeine \
--create-namespace \
--values values-production.yaml
# 업그레이드
helm upgrade caffeine ./charts/caffeine \
--namespace caffeine \
--values values-production.yaml
# 삭제
helm uninstall caffeine --namespace caffeine
📊 모니터링
Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: caffeine-server
namespace: caffeine
spec:
selector:
matchLabels:
app: caffeine-server
endpoints:
- port: http
path: /metrics
interval: 30s
📚 참고 자료
작성일: 2026-01-28
버전: 2.0