一、为什么要这么玩?
在 Kubernetes 这个「容器游乐场」里,传统数据库就像被宠坏的孩子:
- 动不动就「我要固定名字!」(稳定标识)
- 哭喊着「数据不能丢!」(持久存储)
- 还要求「兄弟要整齐!」(有序扩缩容)
StatefulSet 就像贴心保姆,帮我们把这些熊孩子(MySQL)调教得服服帖帖!
二、架构图:兄弟连的「秘密基地」
+----------------+ +----------------+
| MySQL 大哥 | | MySQL 二哥 |
| (主节点) | | (从节点) |
+----------------+ +----------------+
▲ ▲
│ │
+-----+-----+ +-----+-----+
| DNS 路标 | | 读请求分流器 |
| (mysql-0.mysql) | | (mysql-read) |
+------------------+ +----------------+
▲ ▲
│ │
+-----+-----+ +-----+-----+
| 本地硬盘仓库 | | 本地硬盘仓库 |
| (/data/mysql) | | (/data/mysql2)|
+------------------+ +----------------+
三、完整配置:给熊孩子们的「家规」
1. 本地存储:秘密基地的选址
# 01-persistentVolume-1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-data-1
spec:
capacity:
storage: 15Gi
accessModes:
- ReadWriteOnce # 独门独户,禁止合租
local:
path: /data/svr/mysql # 仓库地址
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: ["worker-node"] # 固定在某个工人节点
2. 存储规则:仓库使用说明书
# 02-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner # 手动管理仓库
volumeBindingMode: WaitForFirstConsumer # 等人来了再开门
3. 命名空间:熊孩子们的专属小区
# 03-mysql-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: mysql-world # 小区名字
labels:
app: mysql-family # 住户标签
4. 配置文件:兄弟俩的个性设定
# 04-mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-settings
namespace: mysql-world
data:
master.cnf: |
[mysqld]
server-id=1 # 大哥身份证号
log-bin=big-brother-bin # 大哥的日记本
slave.cnf: |
[mysqld]
server-id=2 # 二哥身份证号
super-read-only # 二哥只读模式
5. 密码保险箱:防止熊孩子乱改密码
# 05-mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
namespace: mysql-world
type: Opaque
data:
password: MTIzNDU2 # 123456 的加密版
6. 服务配置:兄弟俩的联系方式
# 06-mysql-services.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mysql-world
spec:
ports:
- name: mysql-port
port: 3306
clusterIP: None # 大哥专线,不接电话
selector:
app: mysql-family
---
apiVersion: v1
kind: Service
metadata:
name: mysql-read
namespace: mysql-world
spec:
ports:
- name: mysql-port
port: 3306
selector:
app: mysql-family # 二哥接电话
7. 兄弟连组建:StatefulSet 点兵
# 07-mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-brothers
namespace: mysql-world
spec:
serviceName: mysql # 大哥的专线
replicas: 2 # 1 大哥 + 1 二哥
template:
metadata:
labels:
app: mysql-family
spec:
containers:
- name: mysql
image: mysql:5.7 # 使用 MySQL 5.7 版本
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- name: mysql-port
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql # 仓库挂载点
- name: config
mountPath: /etc/mysql/conf.d # 配置文件位置
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- "ReadWriteOnce"
storageClassName: local-storage
resources:
requests:
storage: 3Gi # 每人 3G 仓库
四、部署流程:兄弟连的诞生
- 创建仓库:
kubectl apply -f 01-persistentVolume-{1..3}.yaml
- 划小区:
kubectl apply -f 03-mysql-namespace.yaml
- 发装备:
kubectl apply -f 04-mysql-configmap.yaml
kubectl apply -f 05-mysql-secret.yaml
- 接电话:
kubectl apply -f 06-mysql-services.yaml
- 召唤兄弟:
kubectl apply -f 07-mysql-statefulset.yaml
- 检查状态:
kubectl get pods -n mysql-world
NAME READY STATUS RESTARTS AGE
mysql-brothers-0 2/2 Running 0 3m
mysql-brothers-1 2/2 Running 0 2m
五、主从同步:兄弟间的悄悄话
1. 大哥授权:
kubectl exec -it mysql-brothers-0 -n mysql-world -- bash
mysql -uroot -p123456 -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'replpass';"
2. 二哥拜师:
kubectl exec -it mysql-brothers-1 -n mysql-world -- bash
mysql -uroot -p123456 -e "CHANGE MASTER TO
MASTER_HOST='mysql-brothers-0.mysql-world',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='big-brother-bin.000001',
MASTER_LOG_POS=0;"
mysql -uroot -p123456 -e "START SLAVE;"
3. 验证同步:
# 大哥写数据
kubectl exec mysql-brothers-0 -n mysql-world -- \
mysql -uroot -p123456 -e "CREATE DATABASE test; INSERT INTO test.people VALUES ('豆包', 25);"
# 二哥查数据
kubectl exec mysql-brothers-1 -n mysql-world -- \
mysql -uroot -p123456 -e "SELECT * FROM test.people;"
六、扩军:召唤三弟
kubectl scale statefulset mysql-brothers -n mysql-world --replicas=3
⚠️ 三弟需要手动拜师(同二哥步骤)
七、生产环境秘籍
- 云存储:
# 使用 NFS 动态存储
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Gi
- 负载均衡:
# 安装 MetalLB 分配外部 IP
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
- 监控报警:
# 安装 Prometheus Operator
kubectl apply -f https://github.com/prometheus-operator/prometheus-operator/releases/latest/download/bundle.yaml
八、总结
通过 StatefulSet,我们实现了:
- 名字不变:
mysql-brothers-0
永远是大哥 - 数据不丢:仓库跟着 Pod 跑
- 兄弟齐心:主从同步自动完成
现在你可以傲娇地说:「在我的 Kubernetes 动物园里,MySQL 是最听话的动物!」
🐳 提示:部署前记得在节点创建
/data/svr/mysql
目录哦!