创建 MySQL 数据库
用 PVC + Deployment + Service 起一个单实例 MySQL。
下面示例展示如何在集群里启动一个单实例 MySQL,并挂载持久化存储。这种方式适合开发或测试环境,生产环境建议使用 StatefulSet。
本文在原有示例基础上增加了 Secret、连通性验证、探针与资源配置等步骤,帮助你形成完整的实践流程。
将要创建的资源
- PVC 用于持久化数据。
- 单实例 MySQL Pod(用 Deployment 简化)。
- ClusterIP Service 提供集群内访问。
创建命名空间
将数据库与业务隔离:
kubectl create namespace db
创建 Secret
避免明文密码:
kubectl -n db create secret generic mysql-auth \
--from-literal=MYSQL_ROOT_PASSWORD='ChangeMe123!'
基础资源清单
包含 PVC、Deployment、Service:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: db
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: db
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-auth
key: MYSQL_ROOT_PASSWORD
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: db
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
应用:
kubectl apply -f mysql.yaml
验证 Pod 与 PVC
kubectl get pods -n db
kubectl get pvc -n db
kubectl get svc -n db
Pod 若长时间 Pending,优先检查 PVC 是否绑定。
使用临时客户端验证
启动一个临时 MySQL 客户端 Pod:
kubectl run -it --rm mysql-client \
--namespace db \
--image=mysql:8.0 \
--command -- bash
连接数据库:
mysql -h mysql.db.svc.cluster.local -u root -p
创建表并写入数据:
CREATE DATABASE IF NOT EXISTS demo;
USE demo;
CREATE TABLE items (id INT PRIMARY KEY, name VARCHAR(64));
INSERT INTO items VALUES (1, 'hello');
健康探针
建议加入 liveness/readiness,避免 MySQL 未就绪就接流量:
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-h", "127.0.0.1"]
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command: ["mysqladmin", "ping", "-h", "127.0.0.1"]
initialDelaySeconds: 10
periodSeconds: 5
资源请求与限制
数据库对 CPU/IO 很敏感,建议设置 requests/limits:
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
StorageClass 选择
如果集群里有多个 StorageClass,数据库优先选择 SSD 或低延迟类型。可以在 PVC 中指定:
spec:
storageClassName: fast-ssd
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
查看可用类型:
kubectl get storageclass
安全与最小权限
应用不要使用 root 账号,建议创建专用用户并限制权限,定期轮换密码。数据库 Service 尽量只在集群内使用,并配合 NetworkPolicy 限制访问来源。
如果出现数据目录权限问题,可以设置 fsGroup,保证 MySQL 进程有写入权限。
配置覆盖与初始化
默认参数不一定适合业务,建议通过 ConfigMap 挂载自定义配置,例如 max_connections 或慢查询日志:
volumes:
- name: mysql-config
configMap:
name: mysql-config
volumeMounts:
- name: mysql-config
mountPath: /etc/mysql/conf.d
readOnly: true
需要初始化库表时,可在首次启动后执行 SQL,或使用 init 容器生成脚本。
连接池与并发
应用侧务必使用连接池,避免连接数暴涨。必要时调整 max_connections,但要结合资源评估,避免过多连接导致内存压力。
PVC 扩容与回收策略
如果 StorageClass 支持扩容,可以修改 PVC 的 requests.storage 来扩容。注意不同存储后端是否需要文件系统扩容步骤。
PVC 删除是否释放数据取决于 reclaim policy。重要数据建议使用 Retain,避免误删。
备份建议
即便是单实例,也要有备份方式。最简单的逻辑备份:
kubectl exec -n db deploy/mysql -- \
mysqldump -u root -p demo > backup.sql
备份文件建议放到集群外部。
恢复演练
备份要定期验证恢复。可以在测试命名空间中导入备份文件:
kubectl exec -n db deploy/mysql -- \
mysql -u root -p demo < backup.sql
确认表结构与数据一致,避免“有备份无法恢复”的情况。
监控与日志
至少关注 Pod 重启、磁盘使用率和查询延迟。可以先用 kubectl top 和 MySQL 状态指标做基础监控,逐步引入 exporter。
日志增长过快会占用磁盘,建议配置日志轮转或集中采集。
何时切换到 StatefulSet
- 需要稳定网络标识或多副本。
- 希望每个副本自动创建 PVC。
- 对可用性有更高要求。
Deployment 适合快速实验,StatefulSet 更适合生产。
常见问题
- Pod Pending:PVC 未绑定或缺少 StorageClass。
- CrashLoopBackOff:密码错误或内存不足。
- 连接失败:MySQL 未就绪或 Service 选择器不匹配。
- 磁盘满:扩容 PVC 或清理无用数据。
快速排查:
kubectl describe pod -n db <pod-name>
kubectl logs -n db <pod-name>
实操要点
- 先做快速盘点:
kubectl get nodes、kubectl get pods -A、kubectl get events -A。 - 对比“期望状态”和“实际状态”,
kubectl describe往往能解释漂移或失败原因。 - 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。
快速检查清单
- 资源定义与业务意图一致。
- Namespace、权限、镜像与环境匹配。
- 上线前具备健康探针与可观测日志。
- 备份与恢复流程有记录。
- 凭据存放在 Secret 而非明文。