news 2026/6/3 15:52:46

K8s 生产集群炸了才知道的 4 件事:证书、etcd、节点、发布【系列三】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
K8s 生产集群炸了才知道的 4 件事:证书、etcd、节点、发布【系列三】

系列说明:本文是「K8s 避坑指南」系列第 3 篇。前两篇解决了环境搭建和开发阶段的问题,这篇进入生产阶段,专门对付那些能让整个集群直接挂掉的高危坑。


生产环境的坑和开发不一样——开发踩坑顶多一个服务挂掉,生产踩坑可能是整个集群不可用、数据丢失、凌晨三点电话打过来。这篇的 4 个坑,每一个都是真实事故的来源。建议仔细读,最好提前把预防措施做掉,而不是等踩了再来看怎么恢复。


坑 11:节点变成 NotReady,上面的 Pod 全被驱逐

报错现象

NAME STATUS ROLES AGE node-2 NotReady worker 15d

某个节点突然变成 NotReady,上面运行的 Pod 陆续出现Evicted或被调度到其他节点,业务出现抖动。

根本原因

kubelet 无法在规定时间内(默认 40s)向 API Server 上报心跳,节点被标记为 NotReady。实际根因排序如下:

根因占比特征
节点磁盘满最常见/var/lib/containerd/var/log撑满
kubelet OOM 被杀常见dmesg 里有 OOM 记录
网络中断偶发节点和 API Server 网络不通
kubelet 进程崩溃较少systemctl status kubelet 显示 failed

解决方案

登录到问题节点上按顺序排查:

# 第一步:检查 kubelet 状态和最近日志 systemctl status kubelet journalctl -u kubelet --since "1 hour ago" | tail -200 # 第二步:检查磁盘(最常见!) df -h # 重点关注以下路径所在分区的使用率 du -sh /var/lib/containerd # 镜像和容器层 du -sh /var/lib/kubelet # Pod 数据 du -sh /var/log # 系统日志 # 磁盘满了:清理 containerd 悬空资源 crictl rmi --prune # 清理无用镜像 crictl rm $(crictl ps -a -q --state exited) 2>/dev/null # 清理已退出容器 # 第三步:检查内存和 OOM 记录 free -h dmesg | grep -i "oom" | tail -20 # 第四步:检查网络连通性 curl -k https://<apiserver-ip>:6443/healthz # 处理完根因后重启 kubelet systemctl restart kubelet

预防配置(提前配好,避免磁盘满了才发现):

# /var/lib/kubelet/config.yaml # kubelet 主动驱逐 Pod,避免节点完全崩掉 evictionHard: memory.available: "200Mi" # 内存剩余不足 200Mi 开始驱逐 nodefs.available: "10%" # 磁盘剩余不足 10% 开始驱逐 nodefs.inodesFree: "5%" imagefs.available: "15%" # 镜像存储剩余不足 15% 开始驱逐

坑 12:etcd 磁盘写满,集群进入只读模式

报错现象

所有写操作(create、delete、apply、patch)全部报错:

Error from server: etcdserver: mvcc: database space exceeded

集群进入只读状态,kubectl get还能用,但任何变更操作全部失败,相当于集群瘫痪。

根本原因

etcd 使用 boltdb 存储,默认数据库文件上限是2GB,写满后拒绝写入。常见导致写满的原因:

  • K8s Event 对象堆积(默认每个 namespace 无限制)
  • 频繁 apply 导致大量历史版本(revision)积累
  • etcd 长期未做碎片整理,已删数据占用的空间没有释放

解决方案

紧急恢复(先让集群能写入):

# 设置 etcdctl 环境变量(避免每次都写一长串参数) export ETCDCTL_API=3 export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/server.crt export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379 # 查看当前数据库大小 etcdctl endpoint status --write-out=table # 消除告警(让集群先恢复可写) etcdctl alarm disarm # 碎片整理(释放已删数据占用的空间) etcdctl defrag --cluster # 再次确认大小已减小 etcdctl endpoint status --write-out=table

清理 K8s Event(最大的空间消耗源之一):

# 清理所有 namespace 的 Event kubectl delete events --all -A # 查看 etcd 里 events 占用情况 etcdctl get /registry/events --prefix --keys-only | wc -l

长期预防配置:

# kube-apiserver 参数:限制 Event 保留时间 --event-ttl=2h # 默认 1h,按需调整 # etcd 参数:扩大数据库上限 --quota-backend-bytes=8589934592 # 8GB # 生产建议:每周执行一次碎片整理 # 写入 crontab 0 3 * * 0 etcdctl defrag --cluster >> /var/log/etcd-defrag.log 2>&1

坑 13:证书过期,集群突然完全不可用

报错现象

集群运行了大约一年,某天所有 kubectl 命令突然报:

Unable to connect to the server: x509: certificate has expired or is not yet valid

API Server、etcd、控制器、调度器之间互相无法认证,整个集群瘫痪。

根本原因

kubeadm 生成的 k8s 组件证书默认有效期是1 年。大多数团队安装完集群后就不管了,直到一年后证书过期才发现集群挂了。这个坑非常"阴"——平时什么症状都没有,过期那天直接宕。

解决方案

查看证书状态:

# 查看所有证书的过期时间(kubeadm 1.15+) kubeadm certs check-expiration # 输出示例: # CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY # admin.conf Nov 01, 2025 08:00 UTC <invalid> ca ← 已过期 # apiserver Nov 01, 2025 08:00 UTC <invalid> ca # apiserver-etcd-... Nov 01, 2025 08:00 UTC <invalid> etcd-ca

续期证书:

# 一键续期所有证书(kubeadm 1.15+) kubeadm certs renew all # 续期后重启控制面组件(static pod 会自动重启,等待即可) # 手动确认重启完成 kubectl -n kube-system get pods | grep -E "apiserver|controller|scheduler|etcd" # 更新 kubeconfig(续期后证书变了,旧 config 失效) cp /etc/kubernetes/admin.conf ~/.kube/config

预防(提前告警,不要等过期了才处理):

# 加入 crontab:每月 1 日检查,剩余不足 30 天则发告警 cat <<'EOF' >> /etc/cron.d/k8s-cert-check 0 9 1 * * root \ EXPIRE=$(kubeadm certs check-expiration 2>&1 | grep apiserver | grep -oP '\d+d'); \ [ "${EXPIRE%d}" -lt 30 ] && \ echo "K8s 证书将在 ${EXPIRE} 后过期,请尽快续期!" | \ mail -s "[告警] K8s 证书即将过期" ops@example.com EOF

重要:kubeadm 1.21+ 的集群,每次执行kubeadm upgrade时会自动续期证书。如果集群长期不升级,就一定要手动续期或加自动续期脚本。


坑 14:滚动更新期间出现 502/503,发布必然有抖动

报错现象

执行kubectl rollout restart deployment或部署新版本时,监控上出现持续约 5~30s 的 502/503 报错尖刺,客户端偶发请求失败。

根本原因

默认滚动更新配置下,有两个导致请求失败的时间窗口:

  1. 旧 Pod 被删时仍在接流量:kube-proxy 更新 iptables 规则有延迟(约几秒),旧 Pod 已收到 SIGTERM 开始关闭,但 Service 还在把流量打过来。
  2. 新 Pod 未就绪就接流量:没配readinessProbe,Pod 刚启动就被 Service 纳入,但应用还没 ready。

解决方案

一个完整的「零抖动」Deployment 配置:

spec: strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 # 不允许任何 Pod 不可用,先起新的再删旧的 maxSurge: 1 # 允许多出 1 个 Pod(保证容量不下降) template: spec: # 给 Pod 关闭留足时间排干存量请求 terminationGracePeriodSeconds: 60 containers: - name: app # readinessProbe 通过后才接流量,这是零抖动的核心 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 3 failureThreshold: 3 lifecycle: preStop: exec: # 在进程收到 SIGTERM 之前,先 sleep 等 kube-proxy 完成 iptables 更新 # 这 10s 是让 Service 把这个 Pod 摘掉所需的时间 command: ["sleep", "10"]

为什么preStop: sleep 10有效?

Pod 删除流程是并行的:kubelet 发 SIGTERM 和 Endpoint Controller 摘掉 Pod 是同时进行的,但 Endpoint → kube-proxy → iptables 这条链路有延迟。preStop让进程在真正收到 SIGTERM 之前先等 10s,这段时间 kube-proxy 的 iptables 更新已经完成,新流量不再打进来,再关闭进程处理存量请求就不会有 502 了。


快速检查清单(生产运维篇)

节点健康检查: □ df -h → 磁盘使用率 < 80% □ free -h → 内存有余量 □ systemctl status kubelet → 状态 active (running) □ kubectl get nodes → 所有节点 Ready etcd 健康检查: □ etcdctl endpoint health → 所有节点 healthy □ etcdctl endpoint status → db size < quota 的 80% □ 是否有定期 defrag 计划 证书检查: □ kubeadm certs check-expiration → 所有证书剩余时间 > 30 天 □ 是否有证书到期告警机制 发布配置检查: □ maxUnavailable = 0 □ readinessProbe 已配置 □ preStop sleep 已配置 □ terminationGracePeriodSeconds > preStop sleep 时间

小结

这 4 个坑有一个共同特点:平时没有任何征兆,出事的时候影响面极大。证书过期、etcd 写满、节点磁盘满,都是能让整个集群挂掉的级别。建议现在就去检查一下你的集群证书剩余时间和 etcd 数据库大小。

下一篇预告(系列收官):最后一篇收录剩余 4 个坑——PVC 卡在 Terminating 删不掉、HPA 不生效、RBAC 权限踩坑、NetworkPolicy 配错服务不通。同时附上全系列的快速检查清单和高频 Q&A,建议收藏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/3 15:52:09

UVa 372 WhatFix Notation

题目描述 编译器和计算器中常用的三种遍历方法&#xff1a; 中缀&#xff08;infix\texttt{infix}infix&#xff09;&#xff1a;如 a b c前缀&#xff08;prefix\texttt{prefix}prefix&#xff09;&#xff1a;如 a b c后缀&#xff08;postfix\texttt{postfix}postfix&am…

作者头像 李华
网站建设 2026/6/3 15:49:17

2026年AI编程工具全方位推荐:五大主流工具深度评测

在2026年Q2的开发者社区投票中&#xff0c;TRAE凭借98%的代码生成准确率&#xff08;CSDN评测数据&#xff09;和极高的性价比&#xff0c;成为增长最快的AI编程工具之一。截至2025年底&#xff0c;TRAE累计注册用户已突破600万&#xff0c;其中中文用户占比超过70%&#xff0c…

作者头像 李华
网站建设 2026/6/3 15:48:05

Alphabet计划募资800亿美元,全力押注AI基础设施建设

谷歌母公司Alphabet宣布&#xff0c;计划通过股权融资方式筹集最高800亿美元&#xff08;约合590亿英镑&#xff09;&#xff0c;用于支撑其大规模人工智能基础设施投资。此举规模之大&#xff0c;引发市场对AI经济效益的广泛质疑。此次融资是全球有史以来规模最大的股权募资之…

作者头像 李华
网站建设 2026/6/3 15:45:41

深度解析nCov2019_data_crawler开源数据工程:从Python爬虫源码剖析到公共卫生数据挖掘实战的自动化采集系统

深度解析nCov2019_data_crawler开源数据工程&#xff1a;从Python爬虫源码剖析到公共卫生数据挖掘实战的自动化采集系统 在2020年新冠疫情爆发初期&#xff0c;数据的时效性直接决定了防控决策的效率与科学模型的准确性。然而&#xff0c;面对海量的互联网信息&#xff0c;如何…

作者头像 李华
网站建设 2026/6/3 15:41:54

生命周期与不安全指针的零拷贝艺术:穿透 Tokio 运行时内核

生命周期与不安全指针的零拷贝艺术&#xff1a;穿透 Tokio 运行时内核 前言 大伙好&#xff0c;我是刘洋&#xff0c;网名第一程序员。虽然名头有点唬人&#xff0c;但我其实是个每天都在跟 Tokio 运行时和 Rust 生命周期标注斗智斗勇的系统编程萌新。最近在优化公司的 AI 推理…

作者头像 李华