当然可以!下面是一个 使用 MySQL 官方镜像 的 Kubernetes Pod 健康检查(Health Check)动手实验。我们将配置 Liveness Probe (存活探针)和 Readiness Probe(就绪探针),并通过模拟故障观察 Kubernetes 如何自动处理异常。
✅ 本实验完全基于 MySQL 镜像,无需额外依赖,适合你的离线或内网环境。
🎯 实验目标
- 为 MySQL Pod 配置 Readiness Probe:确保 MySQL 完全启动后才接收流量
- 为 MySQL Pod 配置 Liveness Probe:当 MySQL 进程卡死时自动重启容器
- 观察探针失败时的行为差异
🔧 前提条件
- 已在节点上加载
mysql:latest镜像(通过ctr import或提前拉取) - 使用
imagePullPolicy: Never避免拉取 - 单副本(
replicas: 1),因为多副本 MySQL 无主从会冲突
📄 实验 YAML:带健康检查的 MySQL Deployment
yaml
# mysql-health-check.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-health-check
spec:
replicas: 1
selector:
matchLabels:
app: mysql-health-check
template:
metadata:
labels:
app: mysql-health-check
spec:
containers:
- name: mysql
image: docker.io/library/mysql:latest
imagePullPolicy: Never
ports:
- containerPort: 3306
# 必需的环境变量
env:
- name: MYSQL_ROOT_PASSWORD
value: "MyPass123!"
# 挂载数据目录(避免重启丢数据)
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
# =============== Readiness Probe(就绪探针)===============
# 使用 mysqladmin ping 检查是否可响应
readinessProbe:
exec:
command: ["mysqladmin", "ping", "-uroot", "-pMyPass123!"]
initialDelaySeconds: 15 # MySQL 启动较慢
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# =============== Liveness Probe(存活探针)===============
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-uroot", "-pMyPass123!"]
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3
volumes:
- name: mysql-data
emptyDir: {} # 测试用;生产请用 PVC
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
---
# 创建 Service 供外部连接(可选)
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
selector:
app: mysql-health-check
ports:
- protocol: TCP
port: 3306
targetPort: 3306
type: ClusterIP
💡 说明:
- 使用
mysqladmin ping是官方推荐的健康检查方式-pMyPass123!中不能有空格(否则命令解析失败)initialDelaySeconds要足够长(MySQL 冷启动可能需 20+ 秒)
🧪 实验步骤
第一步:部署 MySQL
kubectl apply -f mysql-health-check.yaml
第二步:观察启动过程
ini
# 查看 Pod 状态(READY 列会从 0/1 → 1/1)
kubectl get pods -w -l app=mysql-health-check
等待约 30 秒,直到:
sql
NAME READY STATUS RESTARTS AGE
mysql-health-check-7d8b9c4b5d-abc12 1/1 Running 0 45s
✅
READY=1/1表示 Readiness Probe 成功
第三步:验证健康检查正常工作
ini
# 查看详细事件
kubectl describe pod -l app=mysql-health-check
在 Events 部分应看到:
erlang
Successfully assigned ...
Created container mysql
Started container mysql
没有 Readiness probe failed 或 Liveness probe failed 错误。
🔥 实验 Part A:模拟"未就绪"状态(测试 Readiness Probe)
我们无法直接修改 MySQL 密码来破坏探针(会永久锁死),但可以通过 临时删除 readinessProbe 来观察反向效果------更安全的方式是 观察启动阶段。
不过,我们可以手动触发一次"慢启动"场景:
-
删除当前 Pod(Deployment 会重建)
inikubectl delete pod -l app=mysql-health-check -
立即 watch 状态:
arduinokubectl get pods -w你会看到:
sqlmysql-... 0/1 Pending 0 0s mysql-... 0/1 ContainerCreating 0 2s mysql-... 0/1 Running 0 10s ← 已 Running,但 READY=0/1! mysql-... 1/1 Running 0 25s ← Readiness 成功,变为 1/1
✅ 结论 :在 initialDelaySeconds 期间和探针成功前,Pod 不会被 Service 加入 Endpoints,即使容器已运行!
💥 实验 Part B:模拟"进程卡死"(测试 Liveness Probe)
我们将进入容器,手动杀死 MySQL 进程,观察 Liveness 是否触发重启。
步骤:
-
进入 MySQL 容器
sqlPOD_NAME=$(kubectl get pod -l app=mysql-health-check -o jsonpath='{.items[0].metadata.name}') kubectl exec -it $POD_NAME -- sh -
在容器内杀死 mysqld 进程
perl# 查找 mysqld PID ps aux | grep mysqld # 假设 PID 是 1(通常主进程是 1) kill -9 1 -
退出容器,观察 Pod 状态
arduinokubectl get pods -w你会看到:
sqlmysql-... 1/1 Running 0 2m mysql-... 0/1 Running 1 2m30s ← RESTARTS 变成 1! mysql-... 1/1 Running 1 3m ← 重启完成 -
查看事件确认是 Liveness 导致重启
bashkubectl describe pod $POD_NAME在 Events 中应有:
bashLiveness probe failed: OCI runtime exec failed: ... (or) Liveness probe failed: mysqladmin: connect to server at 'localhost' failed Killing container with id containerd://mysql: Need to kill Pod
✅ 结论 :Liveness Probe 失败后,Kubernetes 自动重启了容器,实现自愈!
📊 关键知识点总结
| 探针类型 | 检查命令 | 作用 | 失败后果 |
|---|---|---|---|
| Readiness | mysqladmin ping |
判断 MySQL 是否可服务 | 从 Service Endpoints 剔除(不接收新流量) |
| Liveness | mysqladmin ping |
判断 MySQL 是否存活 | 重启整个容器 |
⚠️ 注意:
mysqladmin ping依赖正确密码,必须与MYSQL_ROOT_PASSWORD一致
🛡️ 生产建议
-
密码不要明文写 YAML → 改用 Secret
yamlenv: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password readinessProbe: exec: command: ["sh", "-c", "mysqladmin ping -uroot -p$(MYSQL_ROOT_PASSWORD)"] -
数据持久化 → 将
emptyDir替换为 PVC -
调整超时参数 → 根据实际性能调整
initialDelaySeconds
✅ 清理实验
arduino
kubectl delete -f mysql-health-check.yaml
现在你就掌握了 如何为有状态数据库(如 MySQL)配置 Kubernetes 健康检查!这不仅能提升系统稳定性,还能避免流量打到"假死"实例。
需要我帮你生成 带 Secret + PVC 的生产级版本 吗?或者想试试 PostgreSQL / Redis 的健康检查?欢迎继续提问!