쿠버네티스에 MySQL을 올릴 때는 컨테이너만 실행해서는 부족합니다. 비밀번호는 Secret으로 분리하고, 데이터는 PVC에 보존하며, 고정된 이름과 종료 순서가 필요한 워크로드는 StatefulSet으로 관리하는 편이 좋습니다.
이 예시는 실습과 소규모 내부 환경을 위한 단일 인스턴스입니다. 복제·자동 장애 전환·백업까지 필요한 운영 데이터베이스라면 관리형 서비스나 검증된 MySQL Operator를 먼저 검토하세요.
네임스페이스와 비밀번호
kubectl create namespace database
kubectl -n database create secret generic mysql-auth \
--from-literal=root-password='[강한 비밀번호]'
명령 기록에 비밀번호를 남기고 싶지 않다면 별도 파일이나 비밀 관리 도구를 사용합니다. Secret은 기본 상태에서 암호화가 아닌 Base64 인코딩이므로 etcd 암호화와 RBAC도 함께 설정해야 합니다.
설정과 PVC
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: database
data:
custom.cnf: |
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
slow_query_log=ON
long_query_time=1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-data
namespace: database
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-client
resources:
requests:
storage: 10Gi
storageClassName은 클러스터 환경에 맞게 바꿉니다. NFS 프로비저너 구성은 쿠버네티스 NFS 프로비저닝을 참고하세요.
Service와 StatefulSet
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: database
spec:
clusterIP: None
selector:
app: mysql
ports:
- name: mysql
port: 3306
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: database
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 60
containers:
- name: mysql
image: mysql:8.4
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-auth
key: root-password
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d/custom.cnf
subPath: custom.cnf
readinessProbe:
exec:
command: ["sh", "-c", "mysqladmin ping -uroot -p$MYSQL_ROOT_PASSWORD"]
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 2Gi
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-data
- name: config
configMap:
name: mysql-config
kubectl apply -f mysql.yaml
kubectl -n database rollout status statefulset/mysql
kubectl -n database get pod,pvc,svc
접속과 점검
클러스터 내부에서는 mysql.database.svc.cluster.local:3306으로 접근합니다. 외부에 3306을 바로 공개하지 말고, 점검 시에는 포트포워딩을 사용합니다.
kubectl -n database port-forward service/mysql 3306:3306
kubectl -n database logs statefulset/mysql
마지막으로 PVC를 붙였다는 사실만으로 백업이 되는 것은 아닙니다. mysqldump, 물리 백업 또는 스토리지 스냅샷을 별도 위치에 보관하고 복원 테스트까지 해야 합니다.