早在我加入 urb-it 之前,他们就决定使用 Kubernetes 作为其云原生战略的基石。 这种选择背后有两个原因:使用 Kubernetes 来满足快速扩展的期望,以及利用其容器编排功能为应用程序提供更动态、更有弹性和更高效的环境。 同时,Kubernetes 与我们的微服务架构非常契合。
早期决策
该公司很早就决定选择 Kubernetes,因为初创公司(或任何公司)都对它有很深的依赖性,并且需要学习很多技术知识。 除此之外,我们是否遇到了只有 kubernetes 才能解决的问题?
有人可能会争辩说,我们可以从一个相当大的单体开始,在扩展和其他问题变得更加明显之前不要转向 Kubernetes(或其他工具)。 此外,Kubernetes 当时仍处于开发的早期阶段。 但是,让我们下次深入研究。
8年生产经验
我们已经在生产环境中运行 Kubernetes 超过 8 年了(每个 Kubernetes 都有一个单独的集群),在此期间我们做出了不同的决定。 有些错误仅仅是由于“运气不好”,而另一些错误则是由于部分(如果不是完全)未能理解底层技术。 Kubernetes 很强大,但它也很复杂。
由于没有任何大规模运行 Kubernetes 的经验,我们不得不迎接挑战。
从 AWS 上的自托管迁移到 Azure (AKS) 上的托管。
在最初的几年里,我们在 AWS 上运行了一个自我管理的集群。 如果我没记错的话,我们最初没有选择使用 Azure Kubernetes Service (AKS)、Google Kubernetes Engine (GKE)、Amazon Elastic Kubernetes Service (EKS),因为它们当时没有官方托管解决方案。 正是在 Amazon Web Services (AWS) 自托管平台上,我们经历了 UBB-IT 历史上第一次也是最可怕的集群崩溃,稍后会详细介绍。
由于我们是一个小团队,因此要完全掌握我们需要的所有新功能是具有挑战性的。 同时,管理自托管集群需要持续的关注和维护,这增加了我们的工作量。
当托管解决方案正式发布时,我们花时间评估了 AKS、GKE 和 EKS。 在我们看来,所有这些解决方案都比我们自己管理它们好几倍,我们可以很容易地预见到迁移带来的快速投资回报。
当时,我们平台的 50% 是.NET、50% Python,并且已在使用 Azure 服务总线、Azure SQL Server 和其他 Azure 服务。 因此,将群集迁移到 Azure 的好处是显而易见的,我们不仅能够更轻松地集成这些服务,而且还能够利用 Azure 主干网络基础结构,并节省与离开外部网络和 VNET 相关的成本(这在混合 AWS 和 Azure 设置中是无法避免的)。 此外,我们的许多工程师都熟悉 Azure 及其生态系统,学习曲线较低。
作为奖励,当我们在 AKS 上进行初始设置时,我们不必为控制平面节点(主节点)付费,从而节省了节点费用。
在 2018 年冬天,我们进行了迁移,尽管多年来我们遇到了 AKS 问题,但我们并不后悔这次迁移。
群集崩溃
在使用 AWS 进行自托管时,我们经历了大规模的集群崩溃,导致我们的大多数系统和产品出现故障。 根 CA 证书、etcd 证书和 API 服务器证书都已过期,导致集群停止工作并变得无法管理。 当时,Kube-AWS 对解决方案的支持非常有限。 尽管我们请来了一位专家来指导我们,但我们最终不得不从头开始重建整个集群。
我们认为每个 git 存储库中都有所有权和头盔图表,但令人惊讶的是,并非所有服务都是如此。 最重要的是,库中没有用于创建群集的任何配置的存储。 我们正在与时间赛跑,以重建集群并填充我们所有的服务和产品。 其中一些服务需要重新设计 helm 图表以创建缺少的配置。 有时 dev1 会问 dev2:“你还记得这个服务应该有多少 CPU 或 RAM,或者它应该有什么样的网络和端口访问吗? “更不用说记住什么钥匙了,它们已经随风消失了。
我们花了几天时间重新启动集群并使其启动并运行。 退一步说,这不是我们最自豪的时刻。
由于积极主动的沟通,我们没有通过使用透明度、诚实和保留客户关系等措施来失去任何业务或客户。
群集崩溃
你可能会猜到:第二次崩溃不可能是由证书引起的,你一定从第一次崩溃中吸取了教训,对吧? 没错,但不完全是。
不幸的是,在为崩溃 1 重新创建集群时,我们使用的特定版本的 kube-aws 存在问题。 创建新集群时,它不会将 etcd 证书的到期日期设置为我们提供的到期日期,而是使用默认的一年期限。 因此,在第一次集群崩溃整整一年后,证书过期了,我们又经历了一次集群崩溃。 这一次恢复起来要容易得多,我们不必重建一切,但这仍然是一个地狱般的周末。
注1:其他公司也和我们一样受到此漏洞的影响,但这并没有帮助我们的客户......
注2:我们原计划在一年后更新所有证书,但为了给自己留有余地,我们将到期日期设置为两年(如果我没记错的话)。 因此,虽然我们计划更新证书,但错误比我们领先一步。
自 2018 年以来,我们没有发生过集群崩溃......希望我没有乌鸦的喙。
经验 教训
1.Kubernetes 很复杂您需要对 Kubernetes 的基础设施和运营方面感兴趣并愿意参与的工程师。
在我们的案例中,我们需要一些工程师在日常工作之外处理 Kubernetes,在必要时作为“首选专家”解决问题。 正如您可能想象的那样,特定于 Kubernetes 的任务的工作负载各不相同,从几周几乎没有到没有,到几周的高度集中(例如在集群升级期间)。
不可能在整个团队中轮换工作,而且技术太复杂了,无法每隔一周在工作之间“来回跳跃”。 当然,每个人都需要知道如何使用它(包括部署、调试等),但要在更具挑战性的领域脱颖而出,专门的学习时间是必不可少的。 此外,拥有一位有远见和专注战略的领导者也很重要。
2.Kubernetes 证书由于两次证书过期而经历过集群崩溃,因此精通 Kubernetes 内部证书及其到期日期的详细信息至关重要。
3.保持 kubernetes 和 helm 更新一旦你落后了,使用这两个工具的成本就会增加,问题就会出现。 我们总是等待几个月才能升级到最新版本,以查看其他用户在使用新版本时会遇到哪些问题。 但即使我们保持版本更新,我们也会受到各种新版本 Kubernetes 和 Helm 的影响(Kubernetes API 从 Alfa 到 Beta 和 Beta 到 10等),并面临大量耗时的配置文件和图表重写工作。我知道 Simon 和 Martin 喜欢 Ingress 的所有变体。
4.集中式舵手图表说到舵图表,我们厌倦了每次版本更改都必须更新七十多个图表,因此我们采用了更通用的“一张地图”方法。 使用集中式 helm chart 有利有弊,但最终这种方法更符合我们的需求。
5.灾难恢复计划我怎么强调都不为过:如果需要,请确保您有办法重新创建集群。 是的,您可以单击用户界面来创建新集群,但这种方法无法大规模使用,或者时间至关重要。
有不同的方法可以解决这个问题,从简单的 shell 脚本到更高级的方法,如使用 terraform(或类似)。 Crossplane 还可用于管理基础设施,即 (IAC) 等。 对于我们来说,由于团队的带宽有限,我们选择存储和使用 shell 脚本。 无论选择哪种方法,请确保不时测试该过程,以确保可以在需要时重新创建群集。
6.备份密钥制定关键的备份和存储策略。 如果集群消失,则所有密钥都将丢失。 相信我,我们已经亲身经历过这种情况,当你有多个不同的微服务和外部依赖项时,需要很多时间才能恢复正常。
7.与供应商无关与“全部投注”。最初,在迁移到 AKS 后,我们尽量不将群集绑定到供应商,这意味着我们将继续将其他服务用于容器注册表、身份验证、密钥库等。 这个想法是,有一天我们可以轻松地迁移到另一个托管解决方案。 虽然与商无关是个好主意,但对我们来说,机会成本很高。 一段时间后,我们决定全面使用与 AKS 相关的 Azure 产品,例如容器注册表、安全扫描、身份验证等。 对我们来说,这改善了开发人员体验,简化了安全性(使用 Azure Entra ID 进行集中访问管理)等,从而缩短了上市时间并降低了成本(产生优势)。
8.客户资源定义是的,我们全面使用 Azure 产品,但我们的指导原则是尽量减少自定义资源定义,而是使用内置的 Kubernetes 资源。 但是,也有一些例外,例如 Traefik,因为 Ingress API 不能满足我们的所有需求。
9.安全见下文。
10.可观察性见下文。
11.在已知峰值期间进行预缩放即使使用自动缩放器,我们有时也会缩放得太慢。 利用流量数据和常识(我们是一家物流公司,节假日有高峰),我们在高峰前一天手动放大集群(replicaset),然后在高峰后的第二天缩小规模(慢慢缩小以应对可能的第二波高峰)。
12.集群中的无人机我们将无人机构建系统保留在舞台集群中,这是好事也是坏事。 因为在同一个集群中,它易于扩展和使用; 但是,如果你同时构建太多,它几乎会消耗你所有的资源,导致 Kubernetes 急于启动新节点。 最好的解决方案可能是使其成为一个纯粹的 SaaS 解决方案,而不必担心产品本身的托管和维护。
13.选择正确的节点类型选择节点类型非常具体,但根据节点类型,AKS 会保留大约 10-30% 的可用内存(用于 AKS 内部服务)。 因此,我们发现使用更少但更大的节点类型是有益的。 此外,由于我们在很多服务上运行.NET,因此需要选择具有高效、高容量 IO 的节点类型。 (..NET 经常将 JIT 和日志写入磁盘,如果这需要网络访问,则速度会变慢。 我们还确保节点磁盘缓存的大小至少与配置的节点磁盘的总大小相同,以避免再次发生网络跳转。
14.预留实例您可能会认为这种方法有点违背云的灵活性,但对我们来说,将关键实例保留一两年可以节省大量成本。 在许多情况下,与“现收现付”方法相比,我们可以节省 50%-60%,这是相当可观的。
15.k9s对于想要比 kubectl 更高抽象级别的用户来说,这是一个很好的工具。
可观察性
1.监测确保在一段时间内跟踪内存、CPU 等,以便观察集群的运行状况,并确定新功能是提高还是降低集群性能。 这样可以更轻松地为不同的 Pod 查找和设置“正确”的限制(找到正确的平衡很重要,因为如果内存不足,Pod 将被杀死)。
2.警报完善警报系统需要一个过程,但最终我们将所有警报都定向到 Slack 频道。 当群集未按预期运行或出现意外问题时,很容易获取信息。
3.伐木将所有日志整合到一个位置,以及强大的跟踪 ID 策略(例如 OpenTelemetry 或类似软件),对于任何微服务架构都至关重要。 我们花了两三年时间才到达那里。 如果我们早点实施它,我们将节省大量时间。
安全
Kubernetes 中的安全问题是一个巨大的话题,我强烈建议深入研究它们以了解所有细微差别(例如,请参阅 NSA、CISA 的 Kubernetes 强化指南)。 以下是我们从经验中得出的一些结论,但请注意,这些并非详尽无遗。
1.存取控制简而言之,Kubernetes 的默认限制并不过分。 因此,我们投入了大量时间来收紧访问权限,并实现 Pod 和容器的最小权限原则。 此外,由于存在特定漏洞,非特权攻击者可能会将其权限提升为 root 权限,从而规避 Linux 命名空间限制,在某些情况下,甚至会逃避容器以获取主机节点上的 root 访问权限。 这不是一件好事。
您应该设置只读根文件系统、禁用服务帐户令牌自动挂载、禁用权限提升、放弃所有不必要的功能等。 在我们的特定设置中,我们使用 Azure Policy 和 Gatekeeper 来确保不部署不安全的容器。
在 AKS 的 Kubernetes 设置中,我们利用基于角色的访问控制 (RBAC) 的强大功能来进一步加强安全性和访问管理。
2.容器漏洞有很多好的工具可以扫描和验证容器和 Kubernetes 的其他部分。 我们使用 Azure Defender 和 Azure Defender for Containers 来满足我们的一些需求。
注意:与其陷入“分析瘫痪”,即试图找到具有各种花哨功能的完美工具,不如选择一个工具并直接进入。
多年实践的长期设置
1.部署像许多其他公司一样,我们使用 Helm 来管理和简化在 Kubernetes 上部署和打包应用程序。 因为我们很久以前就开始使用 helm,而且它最初是.NET GO j**a Python PHP 是混合的,所以我不记得我重写了多少次 helm 图表。
2.可观察性我们开始使用 loggly 和 fluentd 进行集中式日志记录,但几年后,我们切换到 Elastic 和 Kibana(ELK 堆栈)。 对我们来说,使用 Elastic 和 Kibana 更方便,因为它们的可用性更广,而且在我们的设置中更便宜。
3.容器注册表我们从码头开始,这是一个很好的产品。 但随着迁移到 Azure,使用 Azure 容器注册表变得很自然,因为它是集成的,因此对我们来说是一个更“本机”的解决方案。 (随后,我们还将容器放在 Azure 安全顾问下)。
4.管道从一开始,我们就使用无人机来建造集装箱。 一开始,支持容器和 Docker 的 CI 系统并不多,而且它们不提供 ** 配置。 多年来,无人机为我们提供了很好的服务。 在 Harness 收购 Drone 后,它变得有点混乱,但在我们屈服并迁移到高级版本后,我们拥有了我们需要的所有功能。
游戏规则的改变者
在过去的几年里,Kubernetes 改变了我们的游戏规则。 它释放了使我们能够更高效地扩展(以应对流量波动)、优化基础设施成本、改善开发人员体验以及更轻松地测试新想法的功能,从而大大缩短了新产品和服务的上市时间和盈利时间。
我们开始使用 Kubernetes 的时间有点太早了,在我们真正遇到它可以解决的问题之前。 但从长远来看,尤其是近年来,它已被证明对我们具有重要价值。
结论
回顾这八年的经历,我们有很多故事要分享,其中许多故事已经消失在记忆中。 我希望你发现形成的过程、所犯的错误以及在此过程中吸取的经验教训对你有所帮助。
感谢您的阅读。 特别感谢 Matin、Simon 和 Niklas 对本文的宝贵意见。
作者丨Anders J nsson Compilation丨onehunnit**丨mediumcom/@.anders/learnings-from-our-8-years-of-kubernetes-in-production-two-major-cluster-crashes-ditching-self-0257c09d36cd*本文由DBAPLUS社区编译,如有需要**,请获得授权并注明出处! 欢迎广大技术人员投稿,投稿邮箱:editor@dbapluscn