Kubernetes使用八年15个生产经验教训


这篇文章讲述了一家名为Urb-it的公司在使用Kubernetes进行云原生战略方面的经验。他们在八年的实际生产中遇到了许多挑战和教训,包括从自助管理的AWS集群迁移到Azure托管服务、集群崩溃导致的业务中断、Kubernetes的复杂性和安全性问题、以及其他基础设施和运维方面的经验教训。文章总结了他们的经验教训,并分享了关于Kubernetes、Helm、灾难恢复计划、安全性和可观察性等方面的实用建议。


在过去的几年里,Kubernetes 改变了我们的游戏规则。它释放的功能使我们能够更有效地扩展(不稳定的流量),优化我们的基础设施成本,改善我们的开发人员体验,使测试新想法变得更容易,从而显着缩短上市时间/赚钱时间新产品和服务。

我们开始使用 Kubernetes 有点太早了,在我们真正遇到它能解决的问题之前。但从长远来看,尤其是最近几年,事实证明它为我们提供了巨大的价值。

要点:

  • 两次重大集群崩溃、
  • 放弃自我管理、
  • 削减集群成本、工具等等

教训内容
1、Kubernetes 很复杂
您需要对 Kubernetes 的基础设施和运营方面感兴趣并愿意参与其中的工程师。就我们而言,我们需要几位工程师,除了日常职责外,他们还会在必要时将时间投入到 Kubernetes 上,作为“首选”专家。Kubernetes 特定任务的工作负载各不相同。有些几周几乎没有什么可做的,而其他几周则需要更多的关注,例如在集群升级期间。我们不可能将工作轮流分配给整个团队;该技术太复杂,无法每隔一周“跳进跳出”。当然,每个人都需要知道如何使用它(部署、调试等)——但要在更具挑战性的方面表现出色,需要投入时间。此外,拥有一个有远见并制定集群发展战略的领导者也很重要。


2、Kubernetes 证书
经历过两次由于证书过期而导致的集群崩溃,因此熟悉内部 Kubernetes 证书及其过期日期的详细信息至关重要。

3、让 Kubernetes 和 Helm 保持最新状态
当您落后时,它会变得昂贵且乏味。我们总是等待几个月才升级到最新版本,以确保其他人首先遇到任何新版本问题。但即使保持最新,由于 Kubernetes 和 Helm 的新版本(Kubernetes API 从 alfa 到 beta、beta 到 1.0 等),我们仍面临许多耗时的配置文件和图表重写。我知道 Simon 和 Martin 喜欢 Ingress 的所有变化。


4、集中式 Helm 图表
当谈到 Helm 图表时,我们厌倦了为每个版本更改更新所有 70 多个图表,因此我们采用了更通用的“一个图表来统治所有图表”的方法。集中式 Helm 图表方法有很多优点和缺点,但最终,这更适合我们的需求。


5、灾难恢复计划
我再怎么强调这一点都不为过:确保有方法在需要时重新创建集群。是的,您可以在 UI 中单击来创建新集群,但这种方法永远无法大规模或及时地发挥作用。

有不同的方法可以处理这个问题,从简单的 shell 脚本到更高级的方法,如使用 Terraform(或类似的)。 Crossplane 还可用于管理基础设施即代码 (IaC) 等。

对于我们来说,由于团队带宽有限,我们决定存储和使用 shell 脚本。无论您选择哪种方法,请务必不时测试流程,以确保您可以在需要时重新创建集群。

6、密钥备份
制定备份和存储密钥等的策略。如果您的集群消失,您所有的秘密都将消失。相信我,我们亲身经历过这一点;当您拥有多个不同的微服务和外部依赖项时,需要花费大量时间才能使一切恢复正常。

7、与供应商无关 VS“全力以赴”
一开始,在迁移到 AKS 后,我们试图保持集群与供应商无关,这意味着我们将继续使用其他服务进行容器注册表、身份验证、密钥保管库等。是有一天我们可以轻松地转向另一个管理解决方案。虽然与供应商无关是一个好主意,但对我们来说,它带来了很高的机会成本。

一段时间后,我们决定全力投入 AKS 相关的 Azure 产品,例如容器注册表、安全扫描、身份验证等。对我们来说,这改善了开发人员体验,简化了安全性(使用 Azure Entra 进行集中访问管理) Id) 等,从而加快了上市时间并降低了成本(数量效益)。

8、客户资源定义
是的,我们全力投入 Azure 产品,但我们的指导方针是尽可能少地使用自定义资源定义,而是使用内置的 Kubernetes 资源。然而,我们有一些例外,比如 Traefik,因为 Ingress API 不能满足我们的所有需求。

9、安全性
Kubernetes 中的安全性是一个广阔的主题,以下是我们经验中的一些要点,但请注意,这绝不是挑战的完整描述。

访问控制
简而言之,Kubernetes 默认情况下并没有过度限制。因此,我们投入了大量时间来加强访问,为 Pod 和容器实施最小权限原则。此外,由于特定的漏洞,无特权的攻击者有可能将其权限升级为 root,从而绕过 Linux 命名空间限制,在某些情况下,甚至逃离容器以获得主机节点上的 root 访问权限。至少可以说不好。

您应该设置只读根文件系统,禁用服务帐户令牌自动挂载,禁用权限升级,删除所有不必要的功能等等。在我们的具体设置中,我们使用 Azure Policy 和 Gatekeeper 来确保我们没有部署不安全的容器。

在 AKS 内的 Kubernetes 设置中,我们利用基于角色的访问控制 (RBAC) 的稳健性来进一步增强安全性和访问管理。

容器漏洞
有很多很好的工具可以扫描和验证容器和 Kubernetes 的其他部分。我们使用 Azure Defender 和 Azure Defender for Containers 来满足我们的一些需求

10、可观察性
监控
确保随着时间的推移跟踪内存、CPU 等的使用情况,以便您可以观察集群的性能并确定新功能是否正在改善或恶化其性能。这样,就可以更轻松地为不同的 pod 找到并设置“正确”的限制(找到正确的平衡很重要,因为如果 pod 内存不足,它就会被杀死)。

警报
完善我们的警报系统是一个过程,但最终,我们将所有警报定向到我们的 Slack 渠道。当集群未按预期运行或出现任何不可预见的问题时,这种方法可以方便地接收通知。

记录
将所有日志整合到一处,以及强大的跟踪 ID 策略(例如OpenTelemetry或类似策略)对于任何微服务架构都至关重要。我们花了 2 到 3 年的时间才把这件事做好。如果我们早点实施它,将会节省我们大量的时间。


11、在已知峰值期间预缩放
即使使用自动缩放器,我们有时也会缩放得太慢。利用流量数据和常识(我们是物流公司,节假日有高峰),我们在高峰到来前一天手动扩容集群(ReplicaSet),第二天再缩容(缓慢处理第二个高峰)可能出现的波)。

12、集群内的Drone 
我们将 Drone构建系统保留在舞台集群中;它有一些好处,但也有一些缺点。由于它位于同一个集群中,因此很容易扩展和使用。然而,当同时构建太多时,它会消耗几乎所有的资源,导致 Kubernetes 急于启动新节点。最好的解决方案可能是将其作为纯粹的 SaaS 解决方案,而不必担心产品本身的托管和维护。

13、选择正确的节点类型
这是非常特定于上下文的,但根据节点类型,AKS 会保留大约 10-30% 的可用内存(用于内部 AKS 服务)。因此,对于我们来说,我们发现使用更少但更大的节点类型是有益的。此外,由于我们在许多服务上运行 .Net,因此我们需要选择具有高效且可观的 IO 的节点类型。(.Net 经常写入磁盘以进行 JIT 和日志记录,如果这需要网络访问,则会变得很慢。我们还确保节点磁盘/缓存的大小至少与配置的总节点磁盘大小相同,再次,防止网络跳转的需要)。

14、预留实例
您可能会认为这种方法有点违背云的灵活性,但对我们来说,保留关键实例一两年可以节省大量成本。在许多情况下,与“现收现付”方式相比,我们可以节省 50-60%。是的,这对团队来说已经是足够多的蛋糕了。

15、k9s
https://k9scli.io/对于任何想要比纯kubectl高一级抽象的人来说都是很棒的工具