Kubernetes中对Pod 进行 健康检查的动手实验,使用mysql镜像

当然可以!下面是一个 使用 MySQL 官方镜像 的 Kubernetes Pod 健康检查(Health Check)动手实验。我们将配置 Liveness Probe (存活探针)和 Readiness Probe(就绪探针),并通过模拟故障观察 Kubernetes 如何自动处理异常。

✅ 本实验完全基于 MySQL 镜像,无需额外依赖,适合你的离线或内网环境。


🎯 实验目标

  1. 为 MySQL Pod 配置 Readiness Probe:确保 MySQL 完全启动后才接收流量
  2. 为 MySQL Pod 配置 Liveness Probe:当 MySQL 进程卡死时自动重启容器
  3. 观察探针失败时的行为差异

🔧 前提条件

  • 已在节点上加载 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 failedLiveness probe failed 错误。


🔥 实验 Part A:模拟"未就绪"状态(测试 Readiness Probe)

我们无法直接修改 MySQL 密码来破坏探针(会永久锁死),但可以通过 临时删除 readinessProbe 来观察反向效果------更安全的方式是 观察启动阶段

不过,我们可以手动触发一次"慢启动"场景

  1. 删除当前 Pod(Deployment 会重建)

    ini 复制代码
    kubectl delete pod -l app=mysql-health-check
  2. 立即 watch 状态:

    arduino 复制代码
    kubectl get pods -w

    你会看到:

    sql 复制代码
    mysql-...   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 是否触发重启。

步骤:

  1. 进入 MySQL 容器

    sql 复制代码
    POD_NAME=$(kubectl get pod -l app=mysql-health-check -o jsonpath='{.items[0].metadata.name}')
    kubectl exec -it $POD_NAME -- sh
  2. 在容器内杀死 mysqld 进程

    perl 复制代码
    # 查找 mysqld PID
    ps aux | grep mysqld
    
    # 假设 PID 是 1(通常主进程是 1)
    kill -9 1
  3. 退出容器,观察 Pod 状态

    arduino 复制代码
    kubectl get pods -w

    你会看到:

    sql 复制代码
    mysql-...   1/1   Running   0   2m
    mysql-...   0/1   Running   1   2m30s   ← RESTARTS 变成 1!
    mysql-...   1/1   Running   1   3m      ← 重启完成
  4. 查看事件确认是 Liveness 导致重启

    bash 复制代码
    kubectl describe pod $POD_NAME

    在 Events 中应有:

    bash 复制代码
    Liveness 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 一致


🛡️ 生产建议

  1. 密码不要明文写 YAML → 改用 Secret

    yaml 复制代码
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-secret
          key: password
    readinessProbe:
      exec:
        command: ["sh", "-c", "mysqladmin ping -uroot -p$(MYSQL_ROOT_PASSWORD)"]
  2. 数据持久化 → 将 emptyDir 替换为 PVC

  3. 调整超时参数 → 根据实际性能调整 initialDelaySeconds


✅ 清理实验

arduino 复制代码
kubectl delete -f mysql-health-check.yaml

现在你就掌握了 如何为有状态数据库(如 MySQL)配置 Kubernetes 健康检查!这不仅能提升系统稳定性,还能避免流量打到"假死"实例。

需要我帮你生成 带 Secret + PVC 的生产级版本 吗?或者想试试 PostgreSQL / Redis 的健康检查?欢迎继续提问!

相关推荐
小毅&Nora1 小时前
【云计算】【Kubernetes】 ③ 深入 containerd - CRI 插件如何驱动 OCI 容器?
容器·kubernetes·云计算
a***11351 小时前
使用Kubernetes部署Spring Boot项目
spring boot·容器·kubernetes
退役小学生呀1 小时前
二十五、基于ArgoCD的K8s多集群管理方案及落地
运维·云原生·容器·kubernetes·devops
leo__5202 小时前
在Kubernetes环境中引用变量的方法
云原生·容器·kubernetes
catoop2 小时前
K8s 通过 Traefik Ingress 配置白名单IP访问限制
kubernetes
catoop4 小时前
K8s 通过 Nginx Ingress 配置白名单IP访问限制
kubernetes
哈里谢顿11 小时前
Kubernetes Service动手实验
kubernetes
哈里谢顿12 小时前
k8s实用脚本
kubernetes
❥ღ Komo·12 小时前
K8s集群搭建全流程详解
云原生·容器·kubernetes