K8s集群又双叒叕崩了?你们是不是也在经历这种循环:半夜被告警电话叫醒,一脸懵地打开电脑,SSH连上master节点,看着满屏的报错日志,心跳跟etcd的leader选举一样忽上忽下。
先说一下我们团队的背景:500多人的研发团队,K8s集群支撑着从研发测试环境到生产业务的所有容器化服务,高峰期每天调度上万个Pod。在切换到新的集群管理方案之前,我们的集群故障率高得离谱——平均每个月要出8次左右的重大故障,每次故障平均恢复时间在1到4小时不等。每周五下午三点,整个平台组的同学都会下意识地紧张起来,因为根据墨菲定律,这个时间点线上集群最容易出幺蛾子。
后来我们团队做了一个决定:把集群的底层运维方式彻底换掉,从传统的“裸Kubernetes + 手工维护各种周边组件”切换到Sealos这套云原生基础设施方案。半年多下来,结果比较直接:月均故障次数从8次降到了0。这不是什么魔法,也不是某个工具开了光,而是把之前那些“人肉运维”导致的不确定性全部消灭掉了,顺便把团队从救火队员的角色里解放了出来。
这篇文章我不打算给你讲一堆纯理论,而是把我们从崩溃边缘走到相对稳定的全过程中,选型背后的思考、踩过的坑、实际操作的步骤,以及那些常规文档里不会写清楚的东西,尽量原原本本梳理出来。如果你正在被K8s集群的稳定性问题折磨,或者刚准备上手自建集群,这篇文章应该能帮你少走几个月的弯路。
1. 先把话说明白:K8s集群为什么会“动不动就崩”
在聊怎么解决之前,我们得先搞清楚,K8s集群为什么那么容易出问题。很多人觉得K8s就是“装好Docker、装好Kubelet、再把控制面拉起来”就完事了,但真正跑过生产环境的人都清楚,K8s的复杂程度,跟你自己写过一个高可用服务时体会到的复杂度,完全不是一个量级。
1.1 崩溃点不是K8s本身,而是围绕它的“木桶短板效应”
K8s本身是一个非常健壮的分布式系统,它的设计目标就是“哪怕一个节点挂掉,整个系统照样能跑”。但问题恰恰出在这里:K8s为了保持这种健壮性,引入了大量的外围依赖和组件,比如网络插件(CNI)、存储驱动(CSI)、负载均衡(MetalLB或云厂商LB)、DNS插件、证书管理机制,以及最著名的分布式存储组件etcd。任何一个组件出现异常,都会直接表现为“集群不可用”或者“Pod调度卡住”。
举几个我们真实遇到过的案例:
etcd磁盘满了。这个是最常见也是最致命的。etcd默认数据目录空间使用率超过90%时,它会停止接受写入请求,直接导致整个集群进入“只读”状态,连Pod的调度都没法执行。当时的排查过程极其痛苦,因为K8s的各个组件表面上都在正常运行,但就是创建不了新Pod,修改不了Deployment副本数,最终一层层查下去才发现是etcd空间满了。
证书过期。Kubernetes集群内的组件之间全部通过TLS证书通信,自签证书的有效期一般是1年(有些发行版是3年)。到期前如果没有自动轮换机制,集群会在一瞬间“失联”。
CNI网络插件版本不兼容。有一次升级集群,Kubelet版本和Calico的版本不兼容,集群节点全部变成NotReady状态,Pod创建出来了但网络不通,业务同事报了一堆故障。
Kube-apiserver内存被打爆。当集群规模上来之后,apiserver作为所有请求的门户,如果监控不完善或者存在大量不合理的list/watch请求,内存和CPU都会飙升,最终节点OOM,控制面瘫痪。
这些故障的共性是什么?它们都不是K8s的核心调度逻辑坏了,而是围绕K8s的各种外围能力出现了问题。传统方式部署K8s,意味着你不仅需要一个好用的K8s,还得自己独立运维etcd、Calico、CoreDNS、Ingress Controller、监控组件、日志组件……样样精通,这是极其反人类的。
1.2 “人肉运维”的不确定性是故障率飙升的根源
我们再往深挖一层,为什么同样是K8s,有的团队用得好好的,有的团队天天救火?
以我们团队为例,在切换方案之前,集群的构建方式非常“原始”:基于文档手工部署,先装kubeadm,再初始化控制面,然后手动安装网络插件,再手动配存储、配Ingress、配监控。好处是灵活,坏处是你很难保证生产、测试、预发环境的配置完全一致。我在帮别的团队排查问题的时候经常发现,同一个配置项,在A环境写的是enable-self-signed,在B环境写的是enable-ssl,这种隐蔽的差异带来的是完全不可预期的行为。
更关键的是,K8s刚兴起那两年,网上的教程和各种“最佳实践”鱼龙混杂,很多操作手册拿到生产环境一跑就出问题。版本差异、内核参数、网络环境限制,每一个变量都能让你折腾到深夜。我一度觉得K8s运维的本质,就是用命去填知识的盲区。
所以,降故障率的第一步,不是找一个更牛逼的监控平台,也不是配一个更高级的告警规则,而是把“不可控的环境差异”压缩到最小。
2. 为什么偏偏选了Sealos:从“搭积木”到“开箱即用”的转变
我们当时也考虑过不少方案。Rancher(现在是RKE2)用过一段时间,界面确实漂亮,后期是Corporate版本;Kubesphere的社区很活跃,它的可视化做得很不错;也有人推荐直接用云厂商的托管K8s服务,但我们有相当一部分业务要跑在自建机房物理机上,这个没法直接适用。
当时恰好我在调研过程中接触到了Sealos,它有几个非常戳中我痛点的特性,这是最终促使我们决定在自建机房环境做一次完整升级的关键。
2.1 Sealos不是一个面板,而是一套完整的“集群操作系统”
很多初次接触Sealos的人会问:它是不是又一个K8s可视化面板?还真不是。你可以把它理解为一个“打包好的集群镜像”,类似你用Docker镜像来封装应用环境一样,Sealos封装的是一整个K8s集群运行所需的全部软件栈,包括容器运行时、Kubernetes本体、网络、存储、Ingress、监控,甚至还有数据库、消息队列这类基础云服务组件。
这意味着,过去我们需要花两三天去装的插件、调的参数、配的优化项,现在通过Sealos的方式一次性收敛进集群镜像里。换一个说法,它把底层操作系统和K8s周边设施,像Docker image 一样做成了镜像资产,直接扔给任何一台干净的服务器,就能拉起一个完整可用的集群环境。
这带来一个非常直接的好处:可复现性。不管你是初始化生产集群,还是临时建一套测试环境,拉取同一个镜像,出来的集群环境是一致的,不会再出现“生产环境和测试环境行为不一致然后就崩了”的鬼故事。
2.2 对比传统部署方案,优势是“少”而不是“多”
在选择技术方案之前,最忌讳的就是盲目赶时髦。决定采用Sealos之前,我们团队做了一个比较详细的对比,在这里分享给你,可以作为你们选型的参考。
| 对比维度 | 传统kubeadm手工部署 | Rancher/Kubesphere | Sealos |
|---|---|---|---|
| 集群初始化复杂度 | 高,需要手工执行大量初始化命令 | 中等,界面引导但仍然要理解每项配置含义 | 低,单条命令完成部署 |
| 组件一致性 | 低,各版本混装是家常便饭 | 中,受面板自身版本捆绑 | 高,镜像化统一管理 |
| 升级难度 | 高,涉及证书、组件、参数兼容性 | 中,需要面板进行复杂版本升级 | 低,重新应用新版本镜像即可 |
| 外围组件(存储、网络、监控) | 需要单独部署管理和调优 | 一些厂商配套,部分组件需单独 | 内置并预调优 |
| 对运维人员的要求 | 需要精通底层原理 | 需要掌握面板操作与底层原理 | 需要了解基本原理但不要求精通所有细节 |
注意我这里的结论,不是说Sealos让运维人员不需要懂任何原理了。它减少的是踩坑的随机性,而不是减少你理解系统的必要性。这非常关键。一个完全不懂etcd的人,用Sealos虽然能拉起集群,但遇到故障依然两眼一抹黑。所以它解决的,是把大量“因为经验差异导致的偏差”消灭掉,让问题能够稳定复现、稳定解决。
2.3 一个特别打动我们的细节:单机模式也有一致的体验
很多中大型团队其实都有这样的尴尬需求:开发环境或者临时压测环境,不需要那么大的集群,但线上生产又要按真实规模来。如果部署方式不一致,开发和测试阶段根本复现不了生产环境的问题。
Sealos通过镜像+参数化的方式,可以快速创建一个单节点集群作为开发环境,但它的集群组件、网络方案、运行时,跟生产环境的多节点集群完全一致。这让“开发环境能跑,生产环境一定也能跑”这句以前是口号的东西,第一次变成了比较靠谱的保障。
3. 实操记录:我是怎么用Sealos重建集群并稳定跑上生产的
光说不练假把式。这一部分我会尽量详细地还原我们部署的完整流程,包括命令细节、资源规划、高可用配置、以及日常运维的关键动作。如果你想直接参考落地,这一章应该最有价值。
3.1 部署前的资源规划:按职责划分,别混用
K8s集群部署前,最忌讳的是角色划分混乱。我们之前的旧集群,node节点既跑业务Pod,又跑集群监控和日志组件,导致资源竞争,业务高峰时Pod CPU被监控组件抢掉,直接雪崩。资源规划看起来是件小事,其实解决了大量潜在故障。
我们这套Sealos集群的标准规划如下:
| 节点角色 | 数量 | 配置参考 | 主要承担职责 |
|---|---|---|---|
| Master/Control Plane | 3台 | 16C32G,系统盘200G SSD | 运行etcd、apiserver、scheduler、controller-manager |
| Worker/业务节点 | 8台 | 32C64G起,系统盘与数据盘分离 | 运行业务容器、中间件容器 |
| 存储节点(可选) | 3台起 | 32C64G,大容量高性能盘 | 提供分布式存储能力(如果你需要Sealos内置的存储) |
我们的经验是:Master节点在资源满足要求的前提下,不应部署繁重的业务负载。有人为了省钱,在测试环境让Master兼任Worker角色,这在测试环境还能忍,生产环境这么干,一旦遇到峰值流量,apiserver和业务容器抢CPU,整个集群调度都会变得极其不稳定。
3.2 集群初始化:从裸机到可用集群只用一套命令
在新方案下,集群初始化确实变得非常简单。准备一台干净的Linux服务器(我们在生产环境用的是Rocky Linux 9),内核和系统基础组件配置好之后,直接执行类似以下指令(取决于你选用Sealos版本的命令语法):
# 拉取对应版本的集群镜像 sealos pull labring/kubernetes:v1.29.0 # 针对多节点集群,初始化第一个master节点 sealos run labring/kubernetes:v1.29.0 \ --masters 192.168.10.10,192.168.10.11,192.168.10.12 \ --nodes 192.168.11.10,192.168.11.11,192.168.11.12 \ --passwd 'your-secure-password'这里稍微解释几个细节,因为很多人第一次用的时候容易困惑:
--masters参数是控制面节点的IP列表,写上三个IP,Sealos会自动把这3台机器组成一个高可用控制面,内部的etcd集群和apiserver负载均衡会自动配置好。--nodes参数对应的就是要加入的业务节点IP列表。- 如果你用的是SSH密钥认证,可以指定对应的私钥参数,这样不用在命令行里直接写密码。
执行完成之后,Sealos会自动把环境检查、ssh通信、容器运行时安装、控制面初始化、节点加入、网络插件部署这一整套动作串联起来。整个过程快的话,大概十来分钟就能得到一个多节点高可用集群。这个体验,对我们这些曾经花三天手工部署的人,心情是复杂且激动的。
3.3 高可用细节:证书与负载均衡怎么处理
很多人关心多Master如何保证高可用。传统kubeadm方式下,你需要自己配置外部负载均衡(比如HAProxy/Nginx),把API Server的请求分发到三个Master节点。Sealos内部对高可用的处理方式跟这个思路类似,但自动化程度更高。
需要注意的一个点是:DNS和VIP(虚拟IP)的处理。如果你的自建机房环境有现成的负载均衡设备或者支持VIP,可以配合使用。如果没有,Sealos在初始化过程中也会帮你完成一套内置的负载均衡方案。实际使用中我们发现,它会让kubelet和kubectl自动指向一个本地的LB地址,从而规避单点故障。
之前手工部署时,最噩梦的就是证书管理:初始化生成的CA证书、各组件证书、ServiceAccount密钥,过期时间不同,维护起来非常烦。Sealos在集群镜像中默认处理了证书自动轮换的问题,这也让我们从“怕证书过期”的心理阴影中彻底走出来了。
3.4 日常升级:不再是“拆炸弹”
在旧集群环境里,我们最害怕的就是升级K8s版本,生怕哪个组件升级后配置不兼容。基本上每次升级都要提前一个月做方案评审、预演、回滚计划,结果还是经常出篓子。
Sealos对升级的处理相对平滑。它的做法还是基于镜像机制:拉取一个更高版本的集群镜像,然后执行升级命令,它会自动处理控制面和节点的滚动升级。我们在半年内顺利做过一次大版本升级,整个升级过程中业务没有出现中断,具体操作大致类似:
# 先拉取新版本镜像 sealos pull labring/kubernetes:v1.30.0 # 执行集群升级 sealos upgrade --cluster my-cluster当然,我不是建议你就盲目相信升级一定零风险,任何生产环境的升级都建议先在测试集群做一次完整演练,再把方案搬到生产环境。但至少在操作复杂度上,这个过程已经变成了“标准操作”,不需要投入全部运维人力去搏一把。
4. 稳定运行半年后,我们如何做集群体检与故障预防
故障率降下来,不等于不用干运维的活了。相反,我们的精力从“紧急救火”转向了“日常体检”和“容量规划”。以下这些检查项和方法,是这半年来我们维护集群最核心的几个动作。
4.1 把etcd健康检查排在第一位
etcd是K8s的地基,地基一出问题,整栋楼都摇摇欲坠。我们的巡检脚本里,第一项就是检查etcd集群的健康状态、空间使用率、碎片率和慢请求情况。相关命令并不复杂,重要的是你要定期去看,并设好告警阈值。
我建议至少关注以下几个指标:
| 指标 | 建议阈值 | 为什么不安全 |
|---|---|---|
| etcd db大小(总空间使用率) | 低于70% | 超90%直接拒绝写入,集群只读 |
| etcd leader切换次数 | 一段时间内不频繁切换 | 频繁切换说明网络不稳定或磁盘IO抖动 |
| apiserver请求成功率 | 99.9%以上 | 低于阈值说明控制面压力过大或组件故障 |
| 节点NotReady状态 | 0个 | 出现则排查kubelet、容器运行时、网络 |
4.2 监控告警:让问题暴露在用户发现之前
Sealos这套方案自带了一些监控组件,集群部署完成后,可以快速启动一个Dashboard和监控大盘。为方便快速查看节点的CPU、内存、网络和磁盘状态,我们也保留并配置了Prometheus等监控工具链。这类工具的使用门槛不高,但要记住一个关键点:告警规则不能太多,否则大家会麻木,最终真的故障来临时反而没人响应。
我们定义告警规则的筛选原则是:只告警“影响业务可用性”和“可能导致数据丢失”的场景。比如:
- kube-system命名空间下的Pod重启次数异常上升
- 节点内存使用率持续超过85%,且持续时间超过10分钟
- etcd请求成功率低于99%
- 证书剩余有效期不足30天
其他一些“毛刺”类的问题,宁可让它默默记录到日志里,也不要疯狂打扰值班的同学。
4.3 备份与恢复演练,是安全感真正的来源
一个稳定的集群,备份是底线。K8s的备份和传统数据库备份不太一样,你不仅要考虑etcd里的元数据,还要考虑持久化存储里的业务数据。我们在Sealos集群环境里,最常做的备份动作,就是周期性对etcd做快照,并把快照文件同步到独立的备份存储机器上(注意,别放在同一个节点上)。
几乎每个季度我们都会做一次完整的恢复演练:搭建一套全新的临时集群,用etcd快照进行恢复,验证关键业务能正常拉起。只有当你亲手做过一次恢复流程且成功之后,你面对“集群挂了”这件事时,才能真正心平气和,而不是慌不择路。
4.4 巡检checklist:一套免费的“治未病”方案
这块内容是我们团队每周五例行巡检时实际使用的,分享出来可以直接用:
- 检查所有Master节点的
/var/log/messages或者journalctl日志,有没有持续刷新的异常信息。 - 检查etcd空间使用率,同时执行
etcdctl defrag(如果开启自动压缩和碎片整理周期)。 - 查看Kubernetes事件,筛选
Warning级别且频繁出现的事件,特别是那些“Liveness probe failed”和“Back-off restarting failed container”。 - 检查核心组件Pod副本数是否都符合预期,特别是
kube-proxy、coredns、calico或flannel这类基础组件。 - 抽查业务Pod的调度分布是否均匀,避免因为某个节点被打爆而引发连锁反应。
- 检查证书有效期,确认自动轮换机制正常执行。
坚持半年做下来你会发现,很多潜在故障苗头,确实能在萌芽阶段被掐掉。
5. 故障排查实录:那些依然可能出现的问题与快速定位思路
虽然号称“故障率降到0”,这里我想特别说明一下:0,是指没有因为运维操作失误或者基础设施不确定性导致的重大故障。但这不意味着集群永远不会出任何波浪。以下记录一些我们切换后依然会遇到的典型情况,以及排查思路,供大家参考。
5.1 问题:某业务Pod频繁重启,整个节点负载升高
有一次线上突然出现一批Pod反复重启,现象表现为容器启动后很快被kill,然后重新调度。我们通过监控发现原因是Pod的内存Limit设置过小,而业务流量突增后内存占用超限。这个跟Sealos本身没关系,纯属资源配额不合理。我们用的小技巧是,给业务方一个资源画像工具,让每个团队定期查看自己服务的基础资源消耗,及时调整资源配置。
这个过程中最大的启发是:K8s集群的故障,往往最后都追溯为“人的问题”。要么是应用配置不合理,要么是资源预估不足。平台的职责是给你一个清晰的视图去发现这些东西,而不是替你杜绝它们。
5.2 问题:节点组成“僵死”,kubelet挂着但业务不通
有一次某个业务节点虽然kubelet进程还活着,但已经无法创建新Pod,旧Pod也不断报网络异常。我们排查的路径:
- 查看kubelet日志,没有明显的panic或者报错。
- 再检查容器运行时,发现是containerd的存储驱动出现了磁盘空间不足的状况。
因为K8s的镜像拉取都需要宿主机存储支撑,数据盘满了之后,新Pod的镜像拉取直接失败。快速处理的中间步骤,是找到并清理废弃的镜像和悬空的日志文件,再把监控大盘的磁盘预警收紧了,避免再发生类似默默饿死的场景。
5.3 问题:有人误删了Ingress或Service
K8s集群人一多,权限管理不到位就很容易出事故。比如某团队同学误删了一个全局共享的Ingress配置,导致下游服务瞬间不可访问。Sealos默认是基于Kubernetes标准对象做管理,所以如果你集群内接入了多个团队,建议一定要配置好RBAC权限隔离。权限最小化是集群生产环境的第一安全底线。
当然这类误操作可以通过开启审计日志、或者启用回收站类组件去缓解,但最核心的永远是流程和权限,工具只能辅助。
5.4 常见问题速查表
| 异常表现 | 优先排查方向 | 快速处理建议 |
|---|---|---|
| 新建Pod一直Pending | 节点资源不足 / 存储或网络插件问题 | 查看kubectl describe pod事件,排查调度器日志 |
| 控制面组件频繁重启 | apiserver负载 / etcd性能 | 检查etcd磁盘IO、慢请求、内存占用 |
| Node状态NotReady | 容器运行时异常 / CPU抢占 | 重启containerd/kubelet,检查系统负载 |
| 网络不通或DNS异常 | CNI配置 / CoreDNS副本 | 重启相应组件,检查iptables规则与网络插件 |
| 集群突然只读 | etcd空间不足 | 清理etcd数据目录、执行压缩与碎片整理 |
写在最后:从“人肉抗灾”到“秩序化运维”,这半年我最大的体会
很多朋友看到“故障率从月均8次降到0”这个结果,第一反应都是“Sealos是不是特别牛的神器,能解决所有问题”。其实我更愿意把它看成一种“运维范式”的切换。过去我们把大量的精力花在不停修补“环境差异”和“配置偏差”上,根本没有多少余力去关注真正的系统架构、容量演进和业务稳定;而当底层环境变成了一套可复现的、标准化的镜像之后,我们才终于腾出手来,去把那些真正影响稳定性的问题系统化地解决掉。
从团队的实际变化来说,大家最大的感受是:运维终于不再需要“英雄”了。以前每次出大故障,总需要有一个资深工程师临危不乱,从一堆日志里面找到蛛丝马迹,靠直觉和运气挽救集群。而环境标准化之后,任何一个合格的工程师照着手册和监控就能完成大部分日常维护与快速恢复,团队整体的应对水平被拉齐了。这种“安全感”比任何财务上的指标都更让人踏实。
如果你也想迁移到Sealos,我个人建议不要一上来就动生产,先拿测试集群跑一个月,把该踩的坑踩掉,再逐步扩大范围。另外,不同版本的SealOS命令和配置方式可能会随着时间迭代,建议以官方最新文档为准。这套做法的核心思想,其实是值得参考的:让基础设施向软件资产一样去版本化、可复现、可演进,而不要把它当作永远需要人肉呵护的脆弱装置。
最后再分享一个小细节:我们之前做“周五下午不敢上线新版本”,现在虽然还是会有变更,但心态完全不一样了。因为环境的可预测性变高了,变更的风险变低了,遇到问题我们能够迅速定位和回滚。有时候想想,真正的技术安全感,不是你有多精通底层,而是你知道出了问题之后一定有条路能走出来,Sealos帮我们打通了这条路,剩下的,还是需要我们珍惜这段来之不易的稳定期,把业务打磨得更好。