以下是一個基于Kubernetes部署MySQL主從集群的詳細YAML示例,包含StatefulSet、Service、ConfigMap和Secret等關鍵配置。MySQL主從集群需要至少1個主節點和多個從節點,這里使用 StatefulSet + 初始化腳本 實現主從自動配置。
1. 創建 Namespace (可選)
apiVersion: v1
kind: Namespace
metadata:name: mysql-cluster
2. 創建 Secret (存儲MySQL密碼)
apiVersion: v1
kind: Secret
metadata:name: mysql-secretsnamespace: mysql-cluster
type: Opaque
data:root-password: eHg= # echo -n "xx" | base64 (示例密碼)replication-password: eHg= # 主從同步專用密碼
3. 創建 ConfigMap (主從配置文件)
apiVersion: v1
kind: ConfigMap
metadata:name: mysql-confignamespace: mysql-cluster
data:master.cnf: |[mysqld]log-bin=mysql-binserver-id=1slave.cnf: |[mysqld]log-bin=mysql-binserver-id=2init.sql: | # 初始化主從復制的SQL腳本CREATE USER 'repl'@'%' IDENTIFIED BY 'xx'; # 密碼需與Secret中一致GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';FLUSH PRIVILEGES;
4. 創建 Service (主從分離訪問)
# 主節點服務
apiVersion: v1
kind: Service
metadata:name: mysql-masternamespace: mysql-cluster
spec:ports:- name: mysqlport: 3306selector:app: mysqlrole: masterclusterIP: None# 從節點服務
apiVersion: v1
kind: Service
metadata:name: mysql-slavenamespace: mysql-cluster
spec:ports:- name: mysqlport: 3306selector:app: mysqlrole: slaveclusterIP: None
5. 創建 StatefulSet (1主2從)
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysqlnamespace: mysql-cluster
spec:serviceName: mysqlreplicas: 3selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlrole: slave # 默認標記為slave,init容器中將修改第一個Pod為masterspec:initContainers:- name: init-mysqlimage: mysql:8.0command:- bash- "-c"- |# 根據Pod序號分配server-id和角色[[ `hostname` =~ -([0-9]+)$ ]] || exit 1ordinal=${BASH_REMATCH[1]}if [[ $ordinal -eq 0 ]]; then# 主節點配置cp /mnt/config/master.cnf /mnt/conf.d/echo "role=master" > /mnt/conf.d/roleelse# 從節點配置cp /mnt/config/slave.cnf /mnt/conf.d/echo "role=slave" > /mnt/conf.d/rolefivolumeMounts:- name: confmountPath: /mnt/conf.d- name: config-mapmountPath: /mnt/config- name: clone-mysqlimage: alpine:3.18command:- bash- "-c"- |# 只有從節點需要等待主節點初始化完成if [ -f /mnt/conf.d/role ] && grep -q "slave" /mnt/conf.d/role; thenuntil nslookup mysql-0.mysql; dosleep 2donefivolumeMounts:- name: confmountPath: /mnt/conf.dcontainers:- name: mysqlimage: mysql:8.0env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretskey: root-password- name: MYSQL_REPL_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretskey: replication-passwordports:- name: mysqlcontainerPort: 3306volumeMounts:- name: datamountPath: /var/lib/mysql- name: confmountPath: /etc/mysql/conf.d- name: init-sqlmountPath: /docker-entrypoint-initdb.dlivenessProbe:exec:command: ["mysqladmin", "ping", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]initialDelaySeconds: 30periodSeconds: 10readinessProbe:exec:command: ["mysql", "-uroot", "-p${MYSQL_ROOT_PASSWORD}", "-e", "SELECT 1"]initialDelaySeconds: 5periodSeconds: 5volumes:- name: confemptyDir: {}- name: config-mapconfigMap:name: mysql-configitems:- key: master.cnfpath: master.cnf- key: slave.cnfpath: slave.cnf- name: init-sqlconfigMap:name: mysql-configitems:- key: init.sqlpath: init.sqlvolumeClaimTemplates:- metadata:name: dataspec:accessModes: ["ReadWriteOnce"]storageClassName: "standard" # 根據環境調整resources:requests:storage: 10Gi
6. 主從初始化自動化腳本 (StatefulSet啟動后執行)
主節點啟動后自動創建復制用戶,從節點自動連接主節點:
# 在StatefulSet的Pod模板中添加以下生命周期鉤子
lifecycle:postStart:exec:command:- "/bin/bash"- "-c"- |if [ -f /etc/mysql/conf.d/role ] && grep -q "master" /etc/mysql/conf.d/role; then# 主節點執行初始化SQLmysql -uroot -p${MYSQL_ROOT_PASSWORD} < /docker-entrypoint-initdb.d/init.sqlelse# 從節點配置主從復制until mysql -h mysql-0.mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"; dosleep 1donemysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "CHANGE MASTER TOMASTER_HOST='mysql-0.mysql',MASTER_USER='repl',MASTER_PASSWORD='${MYSQL_REPL_PASSWORD}',MASTER_AUTO_POSITION=1;START SLAVE;"fi
驗證主從同步
# 檢查主節點狀態
kubectl exec -it mysql-0 -n mysql-cluster -- mysql -uroot -p -e "SHOW MASTER STATUS\G"# 檢查從節點同步狀態
kubectl exec -it mysql-1 -n mysql-cluster -- mysql -uroot -p -e "SHOW SLAVE STATUS\G"
關鍵注意事項:
- 主節點高可用:此方案主節點單點,若需高可用,需結合 Orchestrator 或 ProxySQL 實現故障轉移。
- 數據持久化:確保
storageClassName
與實際存儲系統匹配(如rook-cephfs
、nfs
)。 - 密碼安全:通過Secret管理敏感信息,禁止明文存儲。
- 網絡通信:確保StatefulSet的Pod之間可通過DNS名稱互相訪問(如
mysql-0.mysql.mysql-cluster.svc.cluster.local
)。 - 擴展性:通過增加
replicas
數量擴展從節點。
完整架構示意圖:
Client -> Service(mysql-master) -> Pod(mysql-0) [Master]
Client -> Service(mysql-slave) -> Pod(mysql-1, mysql-2) [Slave]
可根據需求調整副本數量或增加讀寫分離中間件(如ProxySQL)。