절약왕국 프로젝트에서 기존에 Docker Compose로 돌아가던 bb-server 애플리케이션을 MSA 환경으로 구축하기 위해 Kubernetes로 이전하는 과정을 정리해보겠습니다.
현재 프로젝트 상황
bb-server가 실행 중 주제: Docker Compose 환경을 Kubernetes를 활용한 Cluster 환경으로 마이그레이션 하기
이제 Docker Compose로 운영되던 bb-server를 Kubernetes 리소스(Secret, ConfigMap, PersistentVolume, PersistentVolumeClaim, Deployment, Service, HPA)로 마이그레이션 해보겠습니다.
bb-server가 어떤 환경 변수를 쓰고 있고, 어떤 포트가 노출되어 있는지 확인합니다. volumes 설정을 사용하고 있다면, Kubernetes에서는 PersistentVolume, PersistentVolumeClaim으로 매핑해야 합니다.이 과정을 통해 이전에 쓰였던 환경 변수, 포트, 볼륨 등을 모두 파악해두면, K8s 마이그레이션 시 놓치지 않고 반영할 수 있습니다.
apiVersion: v1
kind: Secret
metadata:
name: bb-mariadb-secret
type: Opaque
data:
mysql-root-password: cm9vdA==
mysql-database: Ym9hcmQ=
apiVersion: v1
kind: ConfigMap
metadata:
name: bb-mariadb-config
data:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: board
문제 발생 & 해결
문제: 모든 설정값을 ConfigMap에 넣었다가, 실제로는 민감정보(비밀번호 등)도 섞여있어서 보안 이슈 제기.
해결: 민감정보만 Secret으로 분리하여 관리함.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-bb-mariadb
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data/bb-mariadb"
문제 발생 & 해결
문제: 실제 Worker Node의 /mnt/data/bb-mariadb 디렉토리가 없어서 마운트 실패 발생.
해결: 노드에 들어가 sudo mkdir -p /mnt/data/bb-mariadb && sudo chmod 777 /mnt/data/bb-mariadb 로 디렉토리 생성 후 권한 설정.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bb-mariadb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: bb-mariadb
spec:
replicas: 1
selector:
matchLabels:
app: bb-mariadb
template:
metadata:
labels:
app: bb-mariadb
spec:
containers:
- name: bb-mariadb
image: mariadb:latest
envFrom:
- configMapRef:
name: bb-mariadb-config
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: bb-mariadb-storage
volumes:
- name: bb-mariadb-storage
persistentVolumeClaim:
claimName: pvc-bb-mariadb
apiVersion: v1
kind: Service
metadata:
name: bb-mariadb
spec:
ports:
- port: 3306
selector:
app: bb-mariadb
Compose에서 container_name: mariadb 로 연결하던 것을, K8s에서는 Service 이름(bb-mariadb)으로 접근합니다: bb-mariadb:3306.
apiVersion: apps/v1
kind: Deployment
metadata:
name: bb-server
spec:
replicas: 1
selector:
matchLabels:
app: bb-server
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: bb-server
spec:
containers:
- name: bb-server
image: 99koo/bb-server:1617
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:mariadb://bb-mariadb:3306/board?useUnicode=true&characterEncoding=UTF-8
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: bb-mariadb-secret
key: mysql-root-password
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: bb-mariadb-secret
key: mysql-root-password
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
문제 발생 & 해결
문제: Docker Compose에서는 depends_on: mariadb로 DB를 먼저 띄웠는데, K8s에선 DB 준비가 늦어 bb-server가 DB 연결 실패.
해결: livenessProbe와 readinessProbe를 설정해, DB 연결 전까지는 Pod을 준비 중(Ready=false) 상태로 두도록 조정.
apiVersion: v1
kind: Service
metadata:
name: bb-server
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: bb-server
문제 발생 & 해결
문제: On-premise 환경에서 LoadBalancer 타입이 동작하지 않아 접속이 불가.
해결: Service를 NodePort 타입으로 변경해 :로 직접 접근하도록 설정함.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: bb-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: bb-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
이렇게 Docker Compose로 운영되던 bb-server를 Kubernetes 환경으로 이전해보았습니다.
Docker Compose에서 정의했던 볼륨, 환경 변수, 포트 노출을 Kubernetes의 PV/PVC, Secret/ConfigMap, Service로 대체 오토스케일링(HPA) 기능 추가로 부하에 대응할 수 있는 구조로 업그레이드하였습니다.
절약왕국 프로젝트에는 총 5개의 서버(front-server, auth-server, bb-server, sb-server, cm-server)가 있습니다. 서버별로 필요한 Kubernetes 오브젝트를 각각 따로 관리하면 너무 복잡해질 수 있어, 각 서버별로 필요한 오브젝트를 하나의 YAML 파일에 모아 서버 5개에 대한 파일 5개로 구성하였습니다.
apiVersion: v1
kind: Secret
metadata:
name: bb-mariadb-secret
type: Opaque
data:
mysql-root-password: cm9vdA==
mysql-database: Ym9hcmQ=
---
apiVersion: v1
kind: ConfigMap
metadata:
name: bb-mariadb-config
data:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: board
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-bb-mariadb
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data/bb-mariadb"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-bb-mariadb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bb-mariadb
spec:
replicas: 1
selector:
matchLabels:
app: bb-mariadb
template:
metadata:
labels:
app: bb-mariadb
spec:
containers:
- name: bb-mariadb
image: mariadb:latest
envFrom:
- configMapRef:
name: bb-mariadb-config
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: bb-mariadb-storage
volumes:
- name: bb-mariadb-storage
persistentVolumeClaim:
claimName: pvc-bb-mariadb
---
apiVersion: v1
kind: Service
metadata:
name: bb-mariadb
spec:
ports:
- port: 3306
selector:
app: bb-mariadb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bb-server
spec:
replicas: 1
selector:
matchLabels:
app: bb-server
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: bb-server
spec:
containers:
- name: bb-server
image: 99koo/bb-server:1617
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:mariadb://bb-mariadb:3306/board?useUnicode=true&characterEncoding=UTF-8
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: bb-mariadb-secret
key: mysql-root-password
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: bb-mariadb-secret
key: mysql-root-password
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: bb-server
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: bb-server
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: bb-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: bb-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50