CFN Cloud
Cloud Future New Life
en zh
2025-10-07 · 0 次浏览

创建 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 nodeskubectl get pods -Akubectl get events -A
  • 对比“期望状态”和“实际状态”,kubectl describe 往往能解释漂移或失败原因。
  • 名称、Label、Selector 要一致,避免 Service 或控制器找不到 Pod。

快速检查清单

  • 资源定义与业务意图一致。
  • Namespace、权限、镜像与环境匹配。
  • 上线前具备健康探针与可观测日志。
  • 备份与恢复流程有记录。
  • 凭据存放在 Secret 而非明文。

参考链接