1. 项目背景与核心价值
在容器化部署成为主流的今天,Kubernetes 集群的稳定性直接关系到业务连续性。去年我们团队在为客户部署生产级 K8s 集群时,曾因遗漏内核参数调优导致节点频繁崩溃。这个惨痛教训让我们意识到:集群预检不是可选项,而是必选项。
预检的本质是系统性风险排查,就像飞行员起飞前的检查清单。通过本文总结的 28 项关键检查项,我们成功将集群部署失败率从 37% 降至 2% 以下。这些经验适用于任何基于 Kubernetes 的部署场景,特别是:
- 生产环境首次部署
- 集群版本升级
- 节点扩容/缩容
- 跨云迁移场景
2. 预检体系设计原理
2.1 分层检查模型
我们将检查项划分为三个层级,形成金字塔式检查体系:
[应用层检查] ▲ [K8s组件层检查] │ ▲ [基础设施层检查]基础设施层是根基,包含:
- 节点资源配额(CPU/内存/磁盘)
- 内核参数(vm.swappiness、fs.file-max)
- 网络插件兼容性(MTU 设置、CNI 版本)
- 存储卷类型支持(是否需要 iscsi-initiator)
K8s组件层关注:
- 控制平面组件版本匹配(kube-apiserver 与 etcd 版本差)
- RBAC 权限配置(避免过度授权)
- Admission Controller 启用状态(PodSecurityPolicy 等)
应用层侧重:
- 资源请求/限制配置(防止内存泄漏导致节点雪崩)
- Pod 反亲和性规则(避免单点故障)
- HPA 指标采集可用性(确保自动扩缩容生效)
2.2 自动化检查工具链
手动检查容易遗漏,我们基于开源工具构建了自动化流水线:
# 检查流程示例 kube-bench → sonobuoy → custom-check-script → report-generator工具选型考量:
kube-bench:CIS 基准检查必备,但需注意:
默认规则过于严格,生产环境应自定义
config.yaml过滤不适用项sonobuoy:官方插件化工具,适合:
- 网络性能测试(通过
netperf插件) - 并发负载测试(模拟 1000+ Pod 创建)
- 网络性能测试(通过
自定义脚本:补足工具链空白,比如:
# 检查节点时间同步偏差 def check_ntp(): for node in kubectl.get_nodes(): offset = ssh(node, "ntpdate -q pool.ntp.org | grep offset") if float(offset.split()[7]) > 0.1: alert(f"{node} 时间偏差超过 100ms")
3. 关键检查项实战解析
3.1 内存计算陷阱
许多团队只关注requests/limits设置,却忽略系统预留。实际可用内存公式:
可用内存 = 节点总内存 - kube-reserved - system-reserved - eviction-threshold - 内核占用我们遇到过典型问题:某节点 16GB 内存,设置requests=14GB却仍被调度,最终因 OOM 崩溃。根源在于未计算:
- 内核占用约 500MB
- kubelet 默认
eviction-hard=100Mi - 系统进程占用 1.2GB
正确做法:
# kubelet 配置示例 --system-reserved=cpu=500m,memory=1Gi --kube-reserved=cpu=200m,memory=500Mi --eviction-hard=memory.available<500Mi3.2 网络插件兼容性检查
不同网络插件对内核要求差异巨大:
| 插件类型 | 内核模块依赖 | 典型问题 |
|---|---|---|
| Calico | ip_set, xt_set | 丢包率高于 5% |
| Cilium | BPF 相关 | 内核版本 <4.9 无法运行 |
| Flannel | vxlan, bridge | MTU 不匹配导致分片 |
检查脚本示例:
# 检查 Calico 依赖模块 lsmod | grep -E "ip_set|xt_set" || echo "需加载内核模块" # 测试 MTU 兼容性 ping -s 1472 -M do ${API_SERVER_IP} # 1472 + 28 = 15004. 典型故障排查手册
4.1 证书过期预警
K8s 集群证书过期是灾难性的。我们开发了定期检查脚本:
# 检查所有证书有效期 certs = ["apiserver", "etcd", "front-proxy"] for cert in certs: expiry = openssl x509 -in /etc/kubernetes/pki/${cert}.crt -noout -enddate if (expiry.date() - datetime.now()) < timedelta(days=30): alert(f"{cert} 证书 30 天内过期")避坑经验:
- 使用
kubeadm certs check-expiration官方工具 - 为不同证书设置不同有效期(CA 可长达 10 年,apiserver 建议 1 年)
4.2 节点 NotReady 根因分析
通过预检可提前发现 80% 的潜在故障。常见原因排查表:
| 现象 | 检查命令 | 解决方案 |
|---|---|---|
| kubelet 无法启动 | journalctl -u kubelet | 检查证书路径或 cgroup 驱动 |
| 容器网络不通 | crictl pods | 确认 CNI 插件已安装 |
| 磁盘压力过高 | df -h /var/lib/docker | 清理镜像或扩容存储 |
5. 预检报告生成技巧
人工阅读原始日志效率低下,我们采用三级报告体系:
执行摘要(1 页 PDF):
- 通过/失败检查项统计
- 关键风险项(如证书 7 天内过期)
- 集群健康评分(0-100)
详细报告(Markdown 格式):
## [节点] worker-01 检查结果 - [通过] 内存压力测试:承受 1000 Pod 创建 - [警告] 磁盘 inode 使用率 92%:建议清理日志 - [失败] conntrack 表满:需调整 `nf_conntrack_max`原始数据包(tar.gz 归档):
- 所有检查命令的 stdout/stderr
- 系统状态快照(
/proc/meminfo等) - 性能指标(Prometheus
node-exporter数据)
报告生成工具推荐:
- Pandoc:将 Markdown 转 PDF/HTML
- GoTemplate:动态生成可视化报告
- Grafana:集成检查指标长期监控
6. 持续改进实践
预检不是一次性动作,我们建立了反馈闭环:
- 问题归档:所有检查失败项录入 Jira,标记根本原因
- 规则迭代:每月更新检查项,例如:
- 新增对 Kubernetes CVE 的检测
- 优化资源计算公式
- 自动化修复:对已知问题实现自愈,如:
# 自动清理 Docker 镜像 if $(df /var | awk '{print $5}' | grep -q '9[0-9]%'); then docker image prune -a --force fi
最后分享一个真实案例:某金融客户集群在预检中发现etcd未启用 TLS,及时修复避免了潜在的数据泄露风险。这再次证明:好的预检机制,是稳定性的第一道防线。