Kubernetes 编译失败:但情况还在持续恶化
我从来都不是一个大赌徒。过去我可能为了给超级碗赛事添点料而小赌一把,虽然我当时并没有那么投入,但这种赌注也不算太疯狂。真正把钱押上去需要一定的确定性,而我很少在任何体育赛事、选举结果或未来预测中拥有这种确定性。科技行业几乎没有确定性。工作保障并非天定之事,行业趋势也时好时坏,你每天使用的工具和技术栈也很可能随着时间的推移而演变。尽管充满不确定性,但总有一样东西你可以放心地押注:总有一天,你会遭遇网络中断。
Kubernetes 资深工程师都能证明这一点。在这种情况下,害怕失败或为了确保100% 可用性而费尽心思是没有意义的。错误和中断应该被视为学习的机会,对于任何渴望成熟并以可靠的方式提供高质量服务的环境来说,这都是必要之恶。
有效处理和消化故障的最佳方法是系统地进行事后分析。事实证明,这是我们发现故障模式并总结故障经验教训的最有力工具。关于 Kubernetes 集群故障中常见的模式,我们总结了一些。
DNS、网络和默认资源分配是一些主要原因。
在本文中,我们将分析其中的一些事后分析,并尽力吸收其他人从惨痛经历中吸取的经验教训。
故障严重程度量表
并非每次中断都会产生相同的影响,因此我创建了一个非常科学的分类系统来了解每次 Kubernetes 中断的影响:
🤷 - Oopsie Daisy:琐碎的 Kubernetes 故障
😅 - 非生产,但仍然令人讨厌:我们没有影响任何客户,但从中吸取了教训
🤬 - 休斯顿,我们在生产中遇到了一个问题:客户受到了影响,职业选择受到了质疑。
在我忘记之前,请允许我感谢Glasskube允许我花时间创作这样的内容。如果您是第一次听说我们,我们正在努力打造下一代Package Manager for Kubernetes
。
如果您愿意支持我们完成这项任务,我们将不胜感激
⭐️在 GitHub 上为 Glasskube 点赞🙏
哎呀黛西🤷
如果你不能嘲笑自己,你还能嘲笑谁呢?
集群和节点组
第一个故事来自一位谦虚的记者,他最近使用 AWS 控制台启动了一个测试版 Kubernetes 集群,用于快速验证概念。我已经很久没有不使用 EKSCTL 或某种形式的基础设施即代码定义文件创建集群了。
因此,我登录,访问了 EKS 控制台,命名了我的 Kubernetes 集群,然后点击“创建”。然后,我按照 CLI 说明配置 kubeconfig 文件,并通过终端连接到我新创建的集群。
为了测试最新版本的 Glasskube,我把它安装在了集群中。然而,Pod 的调度时间之长让我大吃一惊。现在回想起来,我都不好意思承认,我花了很长时间才意识到自己没有配置节点组,难怪 Pod 没有被调度。
打电话给消防队,我忘了添加资源限制。
另一个真实的故事来自另一位 Glasskube 成员,由于在本地 Minikube 集群中安装太多组件(GitLab),导致本地笔记本电脑超载,笔记本电脑几乎烧穿了他的桌子,这很好地提醒了我们使用资源限制和请求
虽然不是产品,但还是很烦人😅
谈到一些真实事件,幸运的是,这些事件只局限于一些不会影响付费客户的群体。
事件 #1:Venafi 的 Webhook 无响应
Venafi是一个机器身份控制平面 (OPA),最近被Cyberark收购,后者在 OPA 方面遇到了一些问题。完整的事后分析请点击此处。
影响: API 服务器间歇性超时,导致节点健康度下降。
涉及:开放策略代理、节点就绪
详细分析:
在一次计划的集群升级过程中,尽管之前出现过警告且升级成功,但主服务器升级仍然失败,导致 API 服务器超时和节点不稳定。根本原因是 ConfigMap 更新过程中发生超时,而该超时是由一个无响应的OPA webhook 触发的。删除该 webhook 后,服务恢复正常,之后他们将其限制在特定的命名空间内,为 OPA 添加了活跃度探测,并更新了文档。
他们强调了 API 响应时间警报、工作负载探测以及可能使用 Helm chart 进行部署的必要性,以避免将来出现类似问题。他们持续监控功能的改进,并通过 Flightdeck 服务提供深入的见解。
经验教训:
- 需要对 API 服务器响应时间发出警报。
- 所有工作负载都需要增加
livenessProbes
。 - 使用包管理进行更精细的配置。
💡 此次事件凸显了Glasskube旨在解决的用例之一。虽然 Glasskube 尚不支持 OPA 操作符,但我们相信,如果使用强大的 Kubernetes 包管理器,这个问题是可以避免的。Glasskube 可以轻松配置关键功能,协助升级,并采用 GitOps 方法进行包操作符管理,包括回滚和特定命名空间的分配。点击此处试用。
事件 #2:当加密货币矿工潜入时
JW Player成为比特币挖矿恶意软件的攻击目标,请点击此处查看完整的事后分析。
影响:非生产集群被比特币矿工渗透
涉及:根访问权限利用
详细分析:
在 Datadog 向 JW Player 的 DevOps 团队发出预警,称其 staging 和开发环境中的平均负载过高后,他们在 Kubernetes 集群中发现了一个加密货币挖矿程序。初步调查显示,一个 gcc 进程占用了 100% 的 CPU 资源,该进程是由监控工具 Weave Scope 启动的挖矿程序。该挖矿程序利用了面向公众的 Weave Scope 负载均衡器,该均衡器允许在容器中执行命令。
立即采取的措施包括停止 Weave Scope、隔离受影响的节点并将其轮换出去。该事件导致 CPU 使用率过高,但并未造成服务中断或数据泄露。团队认为 Kubernetes 覆盖了手动安全组编辑操作是一个关键问题,并强调需要采取适当的配置措施来防止此类漏洞。
经验教训:
- 监控负载并不是检测集群问题的最佳方法。
falcon
可能sysdig
需要的工具- 需要更强大的 Docker 镜像和容器扫描。
- 建筑的一些区域需要重新审视。
- 需要更多跨团队数据共享和沟通。
事件 #3:GKE 耗尽 IP 地址
影响:一个高节点数集群耗尽了 IP 地址,无法调度新的 Pod。
涉及:子网、每个节点的默认 IP 分配
事件详情:一位团队成员报告其应用程序的部署时间异常长,引发了一次事件pending
。他们很快发现,虽然一些新部署的 Pod 正在处理流量,但其余 Pod 仍处于某种状态。分析显示一条FailedScheduling
警告,指示资源不足。尽管部署了集群自动扩缩器,但问题仍然存在,因为他们看到了一条令人担忧的“0/256 个可用节点”消息。进一步检查发现,GKE 为每个节点预分配了 110 个 IP,导致 IP 消耗量意外升高。发现这个问题后,他们调整了每个节点的 Pod 分配,将 IP 总体使用率降低了 30%。此外,他们还探索了扩展子网和增加节点大小等方案,以缓解 IP 耗尽问题,最终优化了节点池实例大小,从而更好地利用资源。
经验教训:
- 了解 GKE 设置的默认值的重要性。
- 子网扩展是一个非常有用的工具(不过关于次要范围的文档并不多)。
- 增加节点池实例大小也可以完成这项工作(每个节点运行更多 pod,然后需要更少的节点)。
休斯顿,我们的生产出了问题🤬
这些类型的中断会让 SRE 彻夜难眠,当客户受到影响并且业务价值受到威胁时,这些就是最重要的经验教训出现的地方,也是英雄诞生的地方。
事件 #1 Skyscanner 只需要几个字符就能让他们的网站瘫痪
由此可见,即使针对弹性进行了优化的架构,也仍然可能因为一行代码而导致故障。完整的事后分析请点击此处。
影响:全球 Skyscanner 网站和移动应用程序无法访问
涉及: IaC 舱单
事件详情
2021 年 8 月,Skyscanner 遭遇了一场持续超过四小时的全球宕机,原因是其基础设施配置系统中的根文件被意外更改。由于缺少{{ }}
,这一更改意外触发了全球范围内关键微服务的删除,导致其网站和移动应用程序无法访问。
他们迅速解决了这个问题,利用 GitOps 恢复配置并优先处理关键服务。
经验教训:
- 不要进行全局配置部署。
- 需要更彻底的“最坏情况”规划。
- 验证备份/恢复过程。
- 保持运行手册为最新。
- 自动化潜力巨大。
事件#2 Monzo Bank 的 Linkerd 惨败
英国数字银行艰难地发现了一个严重的 Kubernetes 漏洞。完整分析请点击此处。
影响:预付卡和新活期账户暂停服务约 1.5 小时
涉及: Linkerd、kube-apiserver、etcd
事件详情:
事件起因于一次例行部署导致支付处理失败。尝试回滚更改失败,导致内部宣布中断。工程师识别并重启了运行状况不佳的linkerd
实例,但配置问题导致kube-apiserver
新linkerd
实例无法启动,最终导致中断升级为整个平台故障。根本原因追溯到 Kubernetes 和 etcd 中的一个 bug,该 bug 由最近的集群重新配置触发。这导致linkerd
无法接收网络更新,再加上 Kubernetes 和 linkerd 之间的兼容性问题。最终通过更新 linkerd 并移除空的 Kubernetes 服务解决了该事件。
经验教训:
- 需要新版本的 Linkerd。
- k8s 错误需要修复(现已修复)。
- 改进健康检查、仪表板和警报。
- 程序改进以改善停机期间的内部沟通。
事件 #3 Redis 操作员抛出了一个难题
Palark 是一家 DevOps 服务提供商,它曾试图保护自己的 Redis 集群,但最终却后悔莫及。以下是完整的分析报告
影响:添加副本后的生产 Redis 数据
涉及: Redis 操作员
详细分析:
他们遇到了一起涉及著名内存键值存储 Redis 的事故。他们通过Redis Operator安装 Redis来运行 Redis 故障转移。最初部署 Redis 时只使用一个副本,后来扩展到两个副本以增强数据库可靠性。然而,这个看似微小的改动在部署过程中却带来了灾难性的后果,导致数据丢失。该事故暴露了 Redis Operator 的缺陷,主要是其readiness probe
,导致主节点意外提升,进而导致数据损坏。进一步分析后,他们使用类似工具,Redis-memory-analyzer
深入了解了数据库的大小和元素,从而帮助开发人员优化数据库和应用程序代码,防止未来再次发生事故。
经验教训:
- 使用 Kubernetes 操作员时要非常小心(确保它们成熟且经过充分测试)。
- 发现了与 Redis Operators 就绪探测相关的一个关键错误,该错误导致副本扩展容易发生数据丢失(现已修复)。
Redis-memory-analyzer
是解决 Redis 数据库故障的最佳工具。
事件#4 Datadog 的多区域噩梦
多个Datadog区域瘫痪,systemd-networkd
强制删除了容器网络接口 (CNI) 插件管理的路由。完整事后分析请点击此处。
影响:多个地区的用户无法访问 API 和平台。
涉及: systemd 更新、Cilium
详细回顾:
自2023年3月8日开始,Datadog经历了一次影响多个区域的重大中断,导致用户无法访问平台、API和监控器,并影响了数据提取。此次问题由众多虚拟机上的systemd自动安全更新触发,导致网络中断,数万个节点离线。恢复工作包括恢复计算能力、解决特定服务问题以及向客户提供持续更新。最终确定的根本原因是配置错误导致自动更新功能被启用,该功能现已被禁用。
经验教训:
- 更强大的混沌测试。
- 需要在停电期间改善与客户的沟通
- 停机期间状态页面不够完善。
- 自动更新本身存在风险,应谨慎使用。
事件#5 Reddit 的 Pi-Day 中断
Reddit 遭受了快速有机增长的后果,他们面临的严峻现实是,他们的许多关键 Kubernetes 集群都是不标准化的,容易发生中断,完整的 Pi-Day 中断事后分析在这里。
影响:持续 314 分钟的严重跨平台中断
涉及: Calico、Kubernetes 版本更新
2023 年 3 月,Reddit 经历了一次
长达 314 分钟的严重宕机,恰逢圆周率日。尝试访问该网站的用户要么遇到了 Snoo 吉祥物卡顿、出现错误信息,要么主页空白。此次宕机是由 Kubernetes 1.23 升级到 1.24 引发的,升级过程中引入了一个此前未曾发现的细微问题。工程团队近年来一直致力于提高可用性,但现在他们发现自己正面临一个严峻的挑战:回滚虽然风险很大,但却成了最佳选择。
在恢复过程中,由于 TLS 证书和 AWS 容量限制不匹配而出现了一些复杂情况,但团队设法克服了这些挑战并重新建立了高可用性控制平面。
进一步调查显示,根本原因与 Calico 的过时路由反射器配置有关,由于删除了“主”节点标签,该配置与 Kubernetes 1.24 不兼容。
经验教训:
- 改进预生产集群以用于测试的重要性。
- 需要改进 Kubernetes 组件生命周期管理工具。
- 需要更加同质的环境。
- 此外,还需要增加他们的 IaC 和内部技术文档。
结论
如您所见,熵定律很容易适用于 Kubernetes 集群——破坏它们比保持它们正常运行容易得多。升级、推出、扩展和部署等更改通常会引发中断,因此您可能倾向于将其最小化。但对于那些努力引领其细分市场并满足不断变化的客户需求的组织来说,这不是一个选择。我们所能期望的最好结果是边做边学,从失败中学习。从好的方面来看,科技行业通常对学习持开放态度,并且在大多数情况下都坦诚面对失败。许多大型企业公开分享事后分析摘要以供广大社区借鉴,这是一种最佳实践,它基于这样的假设:故障和中断是“何时”而不是“是否”的问题。保护我们自己的最好方法是在它们过去后从中吸取教训。
🫵 那你呢?你经历过什么特别棘手的宕机事件,并且最终成功了,还能分享你的故事吗?如果有的话,请在下方评论区分享你的经历。我相信很多人都很想听听你的故事。
帮助我们制作更多类似的内容!
在Glasskube,我们投入了大量精力来制作这样的内容,并构建next generation package manager for Kubernetes
。
如果您从我们的工作中获得了价值,我们将非常感激,如果您能
在 GitHub 上为 Glasskube 点赞⭐️🙏