网易数帆云原生故障诊断系统实践与思考

Kubernetes 是一个生产级的容器编排引擎,但是 Kubernetes 仍然存在系统复杂、故障诊断成本高等问题。网易数帆旗下轻舟云原生团队在近几年的稳定性保障工作中累计了不少生产实践的经验,我们沉淀并落地了轻舟云原生故障诊断系统来帮助产品评估集群的稳定性并为用户提供优化建议。本文分享了我们在业务落地不同时期稳定性保障的实践,以及我们在集群稳定性保障层面产品化的思考,希望能够给读者朋友带来一些启发。

容器化落地早期(2018 下半年至 2019 上半年)

在 2018 年下半年,网易内部的部分业务开始逐步对应用进行容器化改造并在生产中落地。这个时期业务的使用还远谈不上云原生,很多用户是把容器当作虚拟机在用。我们团队在这个时期的主要职责包括以下几个方面:

  • 保障内部 Kubernetes 集群的稳定性。

  • 解决业务用户在容器化落地过程中遇到的一系列问题。

  • 解决轻舟产品化初期的一系列问题。

早期面临的问题

这个时期我们面临的问题主要集中在两个方面:Kubernetes、Docker、操作系统层面的问题以及用户使用方式不合理导致的问题。

Kubernetes、Docker、操作系统层面的问题是容器化落地早期难以避免的。我们当时内部主要使用的 Kubernetes 版本是 1.11,Docker 版本是 18.06,现在社区中仍然能找到很多那个时期 Kubernetes 和 Docker 相关问题的 Issue。我们内部当时维护的操作系统是 Debian 9 和 Debian 10,而一些较强势的业务对操作系统有硬性要求,集群中的节点使用 CentOS 7 的操作系统。CentOS 7 使用的 3.10 版本内核的 Cgroups 和 Systemd 实现在容器场景下埋了非常多的坑。针对这方面的问题,我们通过内核调参以及为 Kubernetes 和 Docker 打补丁以维护内部版本的方式来避免问题。以 Kernel Memory Accounting 泄漏这个经典问题为例,我们关闭了 Kubelet 和 Docker 中相关的逻辑,并且规定 CentOS 7.7 为最低支持的版本且在启动参数中固化 cgroup.memory=nokmem 选项来规避改问题。

用户使用方式的不合理也导致了非常多问题。早期用户对 Kubernetes 管理工作负载的设计思想不是很了解,加上业务部门的成本压力,很多用户为了应用快速容器化将虚拟机的用法直接搬到了容器上来。有些不规范的实践通过 Kubernetes 提供的机制可以较好的纠正,有些严重的情况则触发了 Docker 和内核在某些特殊场景下的 Bug 影响了集群的稳定性。针对这方面的问题,我们通过为用户分析故障并给出解决方案的方式来帮助用户容器化平滑落地。例如使用探针而不是传统方法对应用进行健康检查,避免大量执行 Exec 进入容器内执行命令而引发容器终止时进程回收的问题。

早期的思考

在 2018 下半年至 2019 上半年这一时期,网易不少业务完成了生产环境大规模容器化落地并且迅速享受到了云原生技术在资源管理和成本控制层面的红利。我们团队在这一过程中积累了许多宝贵的经验,同时欠下了一些技术债:

  • 忽视云原生技术布道的重要性:我们花费了大量时间帮助用户解决不当实践引起的各种问题,这些问题很多是用户可以通过看文档独立解决。但是用户对这些新技术缺少学习动力,并且新接触 Kubernetes 的同事在增长,问题似乎永远解决不完。

  • 缺少团队职责的细分:落地初期许多的问题都是容器化后产生的,而大部分人对云原生技术是比较陌生的,所以很多问题最终都需要我们团队来解决。

  • 不云原生的云原生落地:迫于业务成本压力,业务需要快速完成容器化改造,但是业务用户对该技术缺乏经验。在这样的背景下,我们开发了一些中间层组件帮助用户快速落地,也做了一些不是很云原生的妥协。

  • 没有对集群标准化交付的规范:部分用户使用的是 CentOS 7 操作系统,我们在认识到使用该操作系统运行 Docker 的风险后仍然没有去引导用户在操作系统上的选择,并且在安装操作系统以及内核参数设置这些问题上也缺少把控。

这些技术债无法用对或错去评判,在当时的客观背景下看来是难以避免的,但是这也为我们之后的工作提供了很好的思路。

业务云原生化时期(2019 上半年至 2020 下半年)

由于早期业务在大规模容器化上尝到了甜头,许多业务开始逐步使用 Kubernetes 来编排应用,这一段时间我们管理的集群数量从原来的十多个变成了近百个。而随着 Kubernetes 的进一步推广,公司内部越来越多的人开始学习云原生技术,也有越来越多的 Operator 被部署到集群中。我们团队的职责也变得愈加多样和复杂:

  • 缓解较大规模集群中的稳定性风险。

  • 规范轻舟不同产品团队在 Kubernetes 中各个扩展点的使用。

  • 集群版本管理和维护的问题。

  • 解决业务用户在云原生化过程中遇到的一系列问题。

工作中常见的问题

部分集群连接的 APIServer 客户端数量超过了 4000 个,其中不乏一些用户用脚本对 Pod 资源进行全量 LIST 来获取数据。这些集群的 APIServer 消耗接近 100G 的内存以及 50 核的 CPU 算力,并且 APIServer 所在节点的网卡流量达到了 15G。针对这方面的问题,我们通过分析客户端的的业务类型找出了使用不合理的客户端并进行优化。例如某个 DaemonSet 运行的组件一开始使用了 kube-builder 进行开发且监听了全量的 Node 资源,但是实际上只需要监听本节点 Node 的资源变化,我们使用 client-go 库重写了客户端并且只关注本节点 Node 的资源变化来规避容量问题,并且向轻舟各团队说明了 APIServer 客户端实现上需要注意的事项,借此为契机来推进整体产品的稳定性提升。

轻舟产品中的一些功能实现了 Admission Webhook 进行扩展,但是轻舟当时很多已交付集群的商业化版本中并不包含 Webhook Server 的超时机制,某些 Webhook Server 会在特定场景下卡住无法返回,严重影响的集群稳定性。我们将上游版本中 Webhook 的特性 Cherry Pick 到商业化版本中,并且推动了 Admission Control 这个扩展点使用的规范化,去除了不少产品中不合理的设计和滥用。

最开始我们管理的 Kubernetes 集群并没有很多,所以管理成本是可控的。随着用户的增长,我们需要维护的 Kubernetes 集群越来越多,版本范围也越来越大,包括 1.111.17 之间的多个版本。早期我们虽然建议用户版本升级时需要进行节点下线再上线的流程,但是刚刚容器化的用户当时难以容忍应用的重建,我们承诺了节点热升级的方案,这些方案也大大增加了我们的管理成本。针对这方面的问题,我们学习了 Red Hat 维护商业化操作系统的策略,通过确定内部维护的 1.17 版本为商业化 Kubernetes 版本,我们将内部版本维护的工作控制在这几个方面:合入上游版本的 Bug 修复以及用户需要的特性对某个商业版本进行维护;标准化某个商业版本到下一个商业版本的升级方案;明确轻舟各

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网易杭研

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值