🗄️ K8S MySQL 部署(Helm · 1主1备)
M1 动手前摸底:查集群里现有 MySQL 的版本 | M2 1主1备方案选型(Bitnami 复制架构) | M3 Helm 一键安装(values 逐行讲) | M4 主从复制验证 | M5 主写从读连接 | M6 升级/扩容/备份/卸载 | M7 报错速查
📑 目录 · MySQL on K8S(Helm 1主1备)
⭐摸底:查看集群里 MySQL 的版本
1主1备方案怎么选
安装:Helm 一键部署 1主1备
验证:主从复制是否正常
连接使用:主写从读
日常运维:升级/扩容/备份/卸载
高频报错速查
M1 ⭐ 摸底:查看集群里 MySQL 的版本 —— 动手前先跑这组命令
装新库/对齐版本前,先看看线上现在跑的是什么。按下面顺序敲,前两条不需要密码 ,最快:
# 0. 先确认 kubectl 连的是目标集群(别在 docker-desktop 上白查)
kubectl config current-context
kubectl config get-contexts
# 1. 全命名空间找 MySQL 的 Pod
kubectl get pods -A | grep -i mysql
# 2. ★ 最快:直接看容器镜像 tag(不用密码、不用进容器)
kubectl get pods -A -o custom-columns='NS:.metadata.namespace,POD:.metadata.name,IMAGE:.spec.containers[*].image' | grep -i mysql
# NS POD IMAGE
# fke-db fke-mysql-hmsserver-prod-0 docker.ergesanbaishou.com/kube-publicmysql/community-operator:8.4.7-2.1.9,docker.ergesanbaishou.com/kube-public/mysql/community-server:8.4.7
# fke-db fke-mysql-hmsserver-prod-1 ...(同上,每套库 3 个实例 -0/-1/-2)
# fke-db fke-mysql-hmsserver-prod-router-… docker.ergesanbaishou.com/kube-public/mysql/community-router:8.4.7
# fke-db mysql-operator-5b99fcbbc7-qxzjb docker.ergesanbaishou.com/kube-publicmysql/community-operator:8.4.7-2.1.9
# ↑↑↑↑ ★ 本环境线上 MySQL 版本 = 8.4.7(8.4 LTS);tag 里的 -2.1.9 是 operator 版本号
# mysql mysql-primary-0 docker.io/bitnami/mysql:8.4.7-debian-12-rX ← 本文目标(=线上 8.4.7,装法见 M3)
# 3. 看控制器(Deployment/StatefulSet)镜像 —— 比 Pod 更代表"当初装的版本"
kubectl get deploy,sts -A | grep -i mysql
kubectl get sts mysql-primary -n mysql -o jsonpath='{.spec.template.spec.containers[0].image}'
# 4. 问 MySQL 本体(要 root 密码;Bitnami chart 的密码存在 Secret 里)
PW=$(kubectl get secret mysql -n mysql -o jsonpath='{.data.mysql-root-password}' | base64 -d)
kubectl exec -n mysql mysql-primary-0 -- env MYSQL_PWD=$PW mysql -uroot -e "SELECT VERSION();"
kubectl exec -n mysql mysql-primary-0 -- mysql --version
# 5. Helm 装的,连 chart 版本一起看(APP VERSION = MySQL 版本)
helm list -A | grep -i mysql
helm get metadata mysql -n mysql # 看 chart_version / app_version
镜像 tag 法(第 2 条)最通用: 不管 Helm/Yaml 怎么装的,只要 MySQL 跑在 K8s 里就能看出来。
不是 Helm 装的 就跳过第 5 条;helm: command not found 说明那台机器没装 Helm(装法见 M3 第 0 步 )。
Pod 名不一定叫 primary/secondary: 用第 1 条找到实际名字,后面命令替换即可。
💡 查到的版本怎么用: 本环境线上已实测为
MySQL 8.4.7(8.4 LTS) ;新装时把
image.tag 固定成
8.4.7-debian-12-rX(见
M3 values ),与线上对齐,避免版本差异带来的 SQL 行为/排序规则变化。
M2 1主1备方案怎么选 —— 本文用 Bitnami chart 复制架构
"1主1备"在 K8s 里有三种落地姿势,先对号入座:
方案 架构 自动故障切换 适用
Bitnami chart · standalone 单实例 — 测试/无关紧要的数据
★ Bitnami chart · replication(本文) 1 主 + N 备,异步复制 无 (备可读,主挂需人工介入)读写分离 + 数据热备,大多数内网场景
★ mysql-operator(InnoDB Cluster)—— 本环境线上采用 3 实例组复制 + Router 读写分离 有(自动选主) 要求 RPO≈0、DBA 运维能力
本文部署出来的样子(replication 架构,secondary.replicaCount=1):
应用(写) ──▶ mysql-primary:3306 ──── binlog 异步复制 ────▶ mysql-secondary:3306 ◀── 应用(读,可选)
StatefulSet ×1(读写) StatefulSet ×1(只读热备)
PVC: data-mysql-primary-0 PVC: data-mysql-secondary-0
Svc: mysql-primary / mysql-primary-h(头less) Svc: mysql-secondary / mysql-secondary-h
# "备"的两层含义都占了:① 数据实时同步(热备,主盘炸了数据还在备上);
# ② 备库可对外提供只读服务(读写分离),不是躺着睡觉的冷备
💡 本环境线上实况(2026-10 实测): fke-db / fke-db-dev 里的 MySQL 全部是 mysql-operator(InnoDB Cluster) 方案 —— 每套库 = 3 个 community-server:8.4.7 实例(-0/-1/-2) + 2~4 个 community-router:8.4.7 + 全局一个 mysql-operator(8.4.7-2.1.9),镜像走私仓 docker.ergesanbaishou.com。本文仍用 Bitnami chart 装自己的 1主1备,版本对齐线上 8.4.7 ;要与线上完全同构(自动切换)请走 mysql-operator 路线 —— 注意 InnoDB Cluster 最少 3 实例 起步,没有"1主1备"形态。
⚠️ 两个必须知道的真相: ① 该 chart 不做自动故障切换 —— primary Pod 挂了 K8s 会把它原样拉起(数据在 PVC 里不丢),但 secondary 不会自动升主;要"主挂备自动顶上"请上 mysql-operator,复杂度高一个量级。② 异步复制有秒级延迟 :刚在主上写完立刻查备库可能读不到,强一致读写都走 primary。
M3 安装:Helm 一键部署 1主1备 —— values 逐行讲
第 0 步:准备 Helm 客户端(能连集群的机器上装即可)
# Linux(master 或跳板机)
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Windows(开发机)
choco install kubernetes-helm # 或官网下 zip 解压进 PATH
# 通用前提:kubectl 能连通目标集群(helm 全靠 ~/.kube/config)
helm version # version.BuildInfo{Version:"v3.x.x"...} 即 OK
第 1 步:加仓库,看清楚版本 —— ★ 最新 chart ≠ 线上版本,必须锁
helm repo add bitnami https://charts.bitnami.com/bitnami && helm repo update
helm search repo bitnami/mysql
# NAME CHART VERSION APP VERSION DESCRIPTION
# bitnami/mysql 14.0.3 9.4.0 ... ← 默认只显示最新:跟踪 MySQL 9.x 创新版,不是我们要的!
# ★ 要 8.4.x(LTS):加 --versions 列历史版本,找 APP VERSION = 8.4.x 的行(实测输出)
helm search repo bitnami/mysql --versions | grep -E 'CHART|8\.4\.' | head -5
# NAME CHART VERSION APP VERSION
# bitnami/mysql 12.3.5 8.4.5 ← ★ 8.4 系最高 chart 到此为止(APP 8.4.5),没有 8.4.7 的 chart
# bitnami/mysql 12.3.4 8.4.5
# bitnami/mysql 12.3.3 8.4.4
# bitnami/mysql 12.3.2 8.4.4
# ★ 结论:chart 锁 12.3.5;精确到 8.4.7 靠 image.tag(同 8.4 系小版本,安全)
# 先确认 Docker Hub 有没有 8.4.7 的 tag(有输出即存在,照抄最精确那个):
curl -s 'https://hub.docker.com/v2/repositories/bitnami/mysql/tags/?name=8.4.7&page_size=10' \
| grep -o '"name":"[^"]*"' | head -3
# ★ 2026-10 实测结论:docker.io/bitnami/mysql 已被清空(上面 curl 无任何输出)!
# Bitnami 2025-08 起免费镜像迁移,旧 tag 全部归档到 bitnamilegacy:
curl -s 'https://hub.docker.com/v2/repositories/bitnamilegacy/mysql/tags/?name=8.4&page_size=10' \
| grep -o '"name":"[^"]*"' | head -5
# 有 8.4.5-debian-12-r0 等 → ★ 第 2 步 values 里加 image.repository: bitnamilegacy/mysql
# (可选)看该 chart 默认镜像 tag 的格式
helm show values bitnami/mysql --version 12.3.5 | grep -A3 '^image:'
⚠️ 为什么不"最新 chart + 强改 image.tag": chart 的启动脚本/模板与 APP VERSION 配套,用 14.x(9.4) 的 chart 回退 8.4 镜像属于跨大版本混搭,容易起不来;chart 和镜像一起锁在 8.4 系 才是稳的。MySQL 8.4 是 LTS,9.x 是创新版 —— 对齐线上选 8.4。
第 2 步:创建 values-mysql.yaml(★ 2026-10 服务器实测终版,整段可直接粘贴)
mkdir -p /data/git/mysql && cd /data/git/mysql # 集中放 mysql 部署文件,以后好找
cat > values-mysql.yaml <<'EOF'
global:
security:
allowInsecureImages: true # ★ 用 bitnamilegacy 归档镜像必须放行(Bitnami 校验,2025-08 新增,否则 upgrade 拒装)
architecture: replication # ★ 复制模式(默认 standalone 单机,别漏!)
auth:
rootPassword: "Root@123456" # ★ root 密码,改成你的
database: "appdb" # 自动创建的业务库
username: "app" # 业务账号(仅对 appdb 授权)
password: "App@123456" # ★ 改成你的
replicationUser: replicator # 主从复制专用账号(chart 自动建并授复制权限)
replicationPassword: "Repl@123456"
image:
repository: bitnamilegacy/mysql # ★ 2026-10 实测:docker.io/bitnami 已清空,8.4 系全在 bitnamilegacy 归档
# 注:不写 tag = 用 chart 12.3.5 默认的 8.4.5-debian-12-r0(与线上 8.4.7 同系 8.4 LTS,tag 名不变)
primary:
persistence:
size: 8Gi # 主库数据卷;线上建议按数据量给足(可在线扩容,见 k8s-issues)
# storageClass: "xxx" # Pod 卡 Pending(绑不上默认 SC)时取消注释,填 kubectl get sc 查到的名字
resources:
requests: {cpu: 250m, memory: 512Mi}
limits: {cpu: "1", memory: 1Gi}
secondary:
replicaCount: 1 # ★★★ 1 主 1 备的灵魂行:备库数量 = 1
persistence:
size: 8Gi # 建议与主库同尺寸
resources:
requests: {cpu: 250m, memory: 512Mi}
limits: {cpu: "1", memory: 1Gi}
metrics:
enabled: false # 先关(少拉一个镜像,提高首次安装成功率);要 Prometheus 指标再改 true
EOF
第 3 步:一键安装 + 盯 Pod
helm install mysql bitnami/mysql -n mysql --create-namespace \
--version 12.3.5 -f /data/git/mysql/values-mysql.yaml
# ★ --version 锁 8.4 系 chart,别省!(13/14.x 已是 9.x 系)
# ★ -f 用绝对路径最稳:换了目录再跑相对路径会报
# Error: INSTALLATION FAILED: open values-mysql.yaml: no such file or directory
# NAME: mysql LAST DEPLOYED: ... STATUS: deployed REVISION: 1
kubectl get pods -n mysql -w # 首次要拉镜像,耐心等两个都 Running(Ctrl+C 退出)
# NAME READY STATUS RESTARTS AGE
# mysql-secondary-0 1/1 Running 0 3m
# mysql-primary-0 1/1 Running 0 3m
# 装出来的全家桶一览
kubectl get all,pvc,secret,cm -n mysql | head -30
release 名叫 mysql ,所以 Pod/Svc/Secret 前缀都是 mysql-;改名则相应变化。
root 密码同时也存在 Secret 里 (装完忘了密码从这里捞):kubectl get secret mysql -n mysql -o jsonpath='{.data.mysql-root-password}' | base64 -d
Pod 起不来先看两处: kubectl describe pod -n mysql mysql-primary-0(Events 排查)与镜像拉取问题(见 M7 )。
卡 Init:ImagePullBackOff(2026-10 实测全记录): 报 unexpected media type text/html = tag/仓库在源上不存在(不是网络! )—— 根因是 docker.io/bitnami 已清空 ,解法见第 2 步 image.repository: bitnamilegacy/mysql,改后 helm upgrade 滚动重建;若是纯超时(i/o timeout)才走 containerd 国内加速(问题总汇 · 05 )。
⚠️ 重装陷阱: 卸载后 PVC
默认保留 !旧数据卷里存着旧 root 密码,新密码不生效、Pod 起不来 —— 重装前要么删 PVC(
kubectl delete pvc -n mysql data-mysql-primary-0 data-mysql-secondary-0),要么沿用旧密码。磁盘/PVC 扩容实战见
问题总汇 。
M4 验证:主从复制是否正常 —— 写一条数据全程跑一遍
# 取 root 密码(后面反复用)
PW=$(kubectl get secret mysql -n mysql -o jsonpath='{.data.mysql-root-password}' | base64 -d)
# 1. 主库写入测试数据
kubectl exec -n mysql mysql-primary-0 -- env MYSQL_PWD=$PW mysql -uroot -e \
"CREATE DATABASE IF NOT EXISTS repl_test; USE repl_test; \
CREATE TABLE t1(id INT, name VARCHAR(32)); INSERT INTO t1 VALUES (1,'qingfeng');"
# 2. 备库读到了 = 复制链路通
kubectl exec -n mysql mysql-secondary-0 -- env MYSQL_PWD=$PW mysql -uroot -e "SELECT * FROM repl_test.t1;"
# +------+-----------+
# | id | name |
# | 1 | qingfeng | ← 备库能查到,主→备复制正常
# 3. 复制线程体检(两个 Running 都要 Yes)
kubectl exec -n mysql mysql-secondary-0 -- env MYSQL_PWD=$PW mysql -uroot -e "SHOW REPLICA STATUS\G" \
| grep -E 'Replica_IO_Running|Replica_SQL_Running|Seconds_Behind'
# Replica_IO_Running: Yes ← 从主库拉 binlog 的线程
# Replica_SQL_Running: Yes ← 回放 binlog 的线程
# Seconds_Behind_Source: 0 ← 延迟秒数(旧版字段名 Seconds_Behind_Master)
💡 健康标准: IO/SQL 双 Yes + Seconds_Behind 稳定在个位数。任一为 No 去
M7 查对应报错。
env MYSQL_PWD=$PW 是为了避免密码出现在 ps/历史记录里,比
-p密码 规范。
M5 连接使用:主写从读 —— 谁该连哪个地址
┌─ NodePort 30306 ──→ mysql-primary-0 (10.244.0.94) 读写
集群外(Navicat等) ───┤
└─ NodePort 30307 ──→ mysql-secondary-0 (10.244.0.93) 只读热备
集群内应用 ──→ mysql-primary.mysql.svc.cluster.local:3306 (写)
──→ mysql-secondary.mysql.svc.cluster.local:3306 (读)
场景 连谁 地址
写入 / 事务 / 强一致读 主库(必) mysql-primary.mysql.svc.cluster.local:3306
报表/大查询等可容忍延迟的读 备库(可选) mysql-secondary.mysql.svc.cluster.local:3306
同 namespace 内的 Pod 均可 短名 mysql-primary / mysql-secondary
集群外临时调试 port-forward kubectl port-forward svc/mysql-primary -n mysql 3306:3306 后连 127.0.0.1:3306
# 应用连接串示例(JDBC;app 账号即 values 里 auth.username/password)
# 写库: jdbc:mysql://mysql-primary.mysql.svc.cluster.local:3306/appdb
# 读库: jdbc:mysql://mysql-secondary.mysql.svc.cluster.local:3306/appdb
# 集群外长期访问:Service 改 NodePort(本环境惯用套路,和 ingress 同思路)
# (默认 ClusterIP:只在集群内可达,所以 get svc 看不到 nodePort、EXTERNAL-IP 是 —— 正常设计,不是漏配)
# ★ 正规做法:写进 values(★ 手 kubectl patch 会被下次 helm upgrade 打回原形!)
# 即在已有 primary:/secondary: 段下各加 service 块(type + nodePorts 端口取 30000-32767):
sed -i '/^primary:/a\ service:\n type: NodePort\n nodePorts:\n mysql: 30306' values-mysql.yaml
sed -i '/^secondary:/a\ service:\n type: NodePort\n nodePorts:\n mysql: 30307' values-mysql.yaml
helm upgrade mysql bitnami/mysql -n mysql --version 12.3.5 -f values-mysql.yaml
kubectl get svc -n mysql
# service/mysql-primary NodePort 10.x.x.x 3306:30306/TCP ← 节点IP:30306 = 主库(读写)
# service/mysql-secondary NodePort 10.x.x.x 3306:30307/TCP ← 节点IP:30307 = 备库(只读)
# 之后任意节点 IP:30306 即主库;生产内网可用,公网别裸开 3306
# 只读语义自测:往备库写会被拒
kubectl exec -n mysql mysql-secondary-0 -- env MYSQL_PWD=$PW mysql -uroot -e \
"USE repl_test; INSERT INTO t1 VALUES (2,'x');"
# ERROR 1290 (HY000): The MySQL server is running with the --read-only option
# ↑ 这不是故障,是备库的正确姿态!写必须走 primary
应用侧最省事: 没做读写分离中间件就全部连 primary ,备库纯当热备,不必强读写分离。
-h 后缀的 headless Service (mysql-primary-h)是给 StatefulSet 稳定 DNS 用的,应用别连它。
两个 3306 为何不冲突: Pod 各有独立 IP(独立网络空间);3306:30306 冒号前的 3306 只是"转发到 Pod 的目标端口",节点上真正监听的是 nodePort(30306/30307,ss -lnt 可查),kube-proxy 从不在节点上直接监听 3306。
DNS 为什么这么拼: mysql-primary.mysql.svc.cluster.local = <Service名>.<namespace>.svc.cluster.local —— svc 是 k8s 内置的"服务"类标记,cluster.local 是集群默认域名(CoreDNS 定的);同 namespace 连短名 mysql-primary 即可(Pod 里 resolv.conf 的 search 域自动补全),跨 namespace 才用全名。★ 注意两个 mysql 含义不同:前缀里的 mysql 是 release 名,中间的 mysql 是 namespace 名,纯属撞名。
宿主机 ping 不通集群域名是正常的: CoreDNS(10.96.0.10)只服务 Pod —— Pod 的 resolv.conf 才指向它,宿主机用自己的 DNS 不认识 mysql-primary。宿主机想查:nslookup mysql-primary.mysql.svc.cluster.local 10.96.0.10;测端口:timeout 3 bash -c '</dev/tcp/10.107.128.199/3306' && echo OPEN(ClusterIP 节点可达,kube-proxy 规则在节点上也生效)。
Navicat/DBeaver 连不上? 先用 port-forward 法验证账号密码,再查 NodePort/防火墙 —— 分层排查。
M6 日常运维:升级 / 扩容 / 备份 / 卸载
① 升级 MySQL 版本(如 8.4.6 → 8.4.7,只改 image.tag)
helm upgrade mysql bitnami/mysql -n mysql -f values-mysql.yaml \
--version 12.3.5 --set image.tag=8.4.7-debian-12-rX # chart 版本同样要带,与安装时保持一致
kubectl rollout status sts/mysql-primary -n mysql # 等滚动完成
kubectl rollout status sts/mysql-secondary -n mysql
# 复查:回到 M1 第 4 条 SELECT VERSION();复制状态回 M4 体检
② 读扩容:备库 1 → 2(1主2备;缩容同理改回 1)
helm upgrade mysql bitnami/mysql -n mysql -f values-mysql.yaml --set secondary.replicaCount=2
kubectl get pods -n mysql # 新增 mysql-secondary-1,自动从主库同步全量数据
③ 备份(逻辑备份,在主库跑;二进制大库可对备库跑减少主库压力)
PW=$(kubectl get secret mysql -n mysql -o jsonpath='{.data.mysql-root-password}' | base64 -d)
kubectl exec -n mysql mysql-primary-0 -- env MYSQL_PWD=$PW sh -c \
'mysqldump -uroot --all-databases --single-transaction --routines --triggers --events' \
> mysql-all-$(date +%F).sql
ls -lh mysql-all-*.sql # 恢复:mysql -uroot -p < mysql-all-2026-10-22.sql
# 参考:线上 fke-db 的 hms-mysql-backup / apifox-mysql-backup(CronJob 定时备份)用的就是 mysqlsh dump/restore
④ 卸载(PVC 默认保留;连数据一起删才执行第二步)
helm uninstall mysql -n mysql
kubectl delete pvc -n mysql data-mysql-primary-0 data-mysql-secondary-0 # ★ 数据将清空,确认再敲
kubectl delete ns mysql
⑤ values 文件丢了 / 要部署到另一套集群:导出与迁移
# 从已有 release 导回 values(接手别人装的环境同样适用!)
helm get values mysql -n mysql # 只看你 -f 传的自定义项 = values-mysql.yaml 的等效物
helm get values mysql -n mysql --all # 自定义 + chart 默认全量(排错看全貌用)
helm get manifest mysql -n mysql # 渲染后的最终 YAML(所有资源对象实际长这样)
helm history mysql -n mysql # 升级历史,每次 REVISION 都可回滚
# 把这套部署搬去另一套集群(如公司线上 fke)的 checklist:
# 1) 传文件:scp values-mysql.yaml 用户@线上操作机:/data/git/mysql/
# 2) 切集群:kubectl config get-contexts 看有哪些 → kubectl config use-context <目标>
# 3) values 按目标集群改:密码(换正式的!)/storageClass(kubectl get sc 查目标集群的)/size/NodePort 端口(避开占用)
# 4) 镜像源:公司线上走私仓 docker.ergesanbaishou.com —— image.repository 改私仓路径(bitnami 镜像需私仓已有或可代理;
# 若线上直连 docker.io 受限,bitnamilegacy 同样要提前验证可拉)
# 5) 安装命令原样照搬:helm install ... --version 12.3.5 -f /data/git/mysql/values-mysql.yaml
💡 变更三板斧: 改 values →
helm upgrade(Helm 只 apply 差异)→
kubectl rollout status 盯滚动。永远别
kubectl edit Helm 管理的资源 —— 下次 upgrade 会被打回原形。Helm 常用命令速查另见
命令速查 。
M7 高频报错速查表
现象/报错 根因 解决
Pod 一直 Pending 没有默认 StorageClass / PVC 绑不上 kubectl get sc;values 里显式 storageClass;排障详见 问题总汇 · 挂载失败
ImagePullBackOff / unexpected media type text/html★ 2026-10 实测:docker.io/bitnami 已清空,8.4 镜像在 bitnamilegacy 归档(纯 i/o timeout 才是网络问题) values 改 image.repository: bitnamilegacy/mysql 后 helm upgrade(见 M3 第 2 步 );其他排查见 问题总汇 · 拉不下镜像
root 登录 Access denied 重装时旧 PVC 带着旧密码,新密码没写进去 用旧密码;或删 PVC 重装(见 M3 重装陷阱 )
备库查不到最新数据 复制延迟 / 复制线程断了 SHOW REPLICA STATUS\G 看 Seconds_Behind 与 Last_Error;双 No → 检查 replicationUser 密码与 primary 可达
ERROR 1290 ... --read-only option往备库写 设计如此,写走 mysql-primary(见 M5 )
Pod CrashLoopBackOff 反复重启 Secret 密码与 PVC 旧数据不一致 / 内存 limit 太小 kubectl logs 看启动报错;对齐密码或删 PVC;调大 resources
secondary 起不来,日志报连不上 primary primary 未就绪时 secondary 先起 等 primary Running 后 kubectl delete pod mysql-secondary-0 -n mysql 让它重连
helm upgrade 后配置没变资源被手动 kubectl edit 过,upgrade 跳过漂移项 所有变更走 helm upgrade,别手改(见 M6 三板斧 )
helm install 报 open values-mysql.yaml: no such file or directory当前目录没有该文件(创建后换了目录跑) -f 用绝对路径,如 -f /data/git/mysql/values-mysql.yaml(见 M3 第 3 步 )
upgrade 报 Original containers have been substituted for unrecognized onesBitnami chart 校验到非官方仓库镜像(如 bitnamilegacy) values 加 global.security.allowInsecureImages: true(见 M3 第 2 步 )
🗄️ K8S MySQL 部署(Helm · 1主1备) · Bitnami chart 复制架构:摸底查版本 → 选型 → 安装 → 复制验证 → 主写从读 → 运维 → 排障 (2026-10-22)
K8S Web · 部署清单见 k8s/deploy.yaml · kubectl apply -f k8s/ 一键部署