Kubernetes을 사용해 MySQL서버 구축 & 배포하기
2024년 07월 08일부터 Weasel 이라는 프로젝트를 시작했습니다. RDS를 띄우기 전, 개발 및 테스트 용도로 사용될 MySQL 서버가 필요했습니다. 해당 포스트에서는 Kubernetes 클러스터에 MySQL 서버를 구축하고 배포하는 과정에 대해 다뤄보겠습니다.
2024/08/28 - Mysql 같은 경우 클러스터링을 할 경우 여러 개의 Pods를 띄울 상황이 생깁니다. 해당 경우 Deployment가 아닌 StatefulSet을 사용해야 합니다.
사전 준비물
쿠버네티스
PV, PVC 생성
기본적으로 Pod가 실행되면서 생긴 데이터는 Pod가 삭제되거나 재시작될 때 유지되지 않습니다. 따라서 데이터를 영구적으로 저장할 PV, PVC를 생성해주었습니다. 해당 방법과 더불어 Storage Class를 사용하는 방법도 추천드립니다.
mysql-pv.yaml
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
mysql-pvc.yaml
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
ConfigMap 생성
팀원들이 사용할 사용자 계정을 생성해야했고, ConfigMap의 데이터를 컨테이너의
/docker-entrypoint-initdb.d
디렉토리에 마운트하면 MySQL 컨테이너가 초기화 되면서 해당 파일이 같이 실행되는 것을 알게 되었습니다.
mysql-configmap.yaml
1
2
3
4
5
6
7
8
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-initdb-config
data:
init.sql: |
GRANT ALL PRIVILEGES ON *.* TO 's5t1'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
secrets 생성
MySQL 초기화에 필요한 환경변수들을 Secret으로 생성해주었습니다. 여기서 주의할 점은 시크릿을 암호화하지 않게되면 base64로 인코딩 한 값을 kubectl 명령어를 통해 확인할 수 있으므로, 쿠버네티스 클러스터 설정에서
EncryptionConfigure
를 사용해주어야 합니다. 추가로 HashiCorp Vault, AWS Secret Manager를 사용하는 방법도 추천드립니다.
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
mysql-root-password: {mysql-root-password}
mysql-user-id: {mysql-user-id}
mysql-user-password: {mysql-user-password}
mysql-database-name: {mysql-database-name}
Deployment 생성
앞에서 만든 ConfigMap, Secret을 사용해 MySQL Deployment를 생성해주었습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: mysql-root-password
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-secret
key: mysql-user-id
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: mysql-user-password
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: mysql-secret
key: mysql-database-name
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
- name: initdb
mountPath: /docker-entrypoint-initdb.d # 초기화 스크립트를 저장하는 특별한 위치 디렉토리에 있는 모든 .sh, .sql, .sql.gz 파일이 자동으로 실행
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
- name: initdb
configMap:
name: mysql-initdb-config
Service 생성
간단한 배포를 위해 NodePort를 사용했고, 30006번 포트로 배포했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: NodePort
ports:
- name: mysql-port
port: 3306
targetPort: 3306
nodePort: 30006
selector:
app: mysql
궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKam._.Ji