遵循精益方法可以帮助我们显著提高 Kubernetes 的投资回报率,改善工作负载性能,并节省维护和故障排除的时间。
译自 What Does It Mean to Keep Clusters Lean?,作者 Ant Weiss。
随着 Kubernetes 成为构建现代软件交付平台的事实标准,有效管理集群 变得越来越重要。这一过程催生了“保持集群精益”的流行口号。
您是否在实践DevOps?这意味着您是精益的!精益原则位于 DevOps 方法论的核心。并非偶然,CALMS 思维框架(由 DevOps 先驱 John Willis 和 Damon Edwards 提出,并由 Jez Humble 进一步发展)中的“L”代表精益交付实践。
现代 DevOps 实践植根于精益管理原则。这些原则,包括准时制零件交付和消除浪费,最初由二战后日本的丰田生产系统 (TPS) 定义。后来,在 1990 年代,西方创造了“精益”一词来描述这些理念。诸如“改变世界的机器”之类的书籍解释了 TPS 以及精益管理如何在全球范围内传播到各个行业,包括软件开发。
“精益软件开发”一书由 Mary 和 Tom Poppendieck 于 2003 年出版,定义了软件交付中遇到的浪费类型,并描述了如何通过结构化的持续改进流程来消除这些浪费。
云原生世界中的精益原则
简而言之,精益管理的原则如下:
- 专注于价值
- 消除浪费
- 追求持续改进
遵循这些原则,企业可以更快地交付价值,减少浪费,并实现更高的生产质量。
云原生基础设施旨在通过提供云资源(无需冗长的规划流程和未充分利用的服务器场)来快速交付高质量软件并优化价值流。自治工程团队部署自治微服务,这些微服务异步且高效地与其他服务交互。
当然,这是理想情况。但在现实生活中,大多数 Kubernetes 集群都是浪费的,而且不够可靠。它们中发生的事情太多了,无法在不应用明确定义的方法的情况下有效地管理它们。
随着 Kubernetes 成为运行生产级软件(无论是 Web 服务、批处理还是数据管道)的事实标准方式,人们越来越认识到,只有通过有意识地保持集群精益,才能实现令人满意的云 ROI,从而在充满挑战的全球 IT 市场中保持竞争力。
保持集群精益
以下是一些帮助保持 Kubernetes 集群精益的实践。
1. 专注于价值
一旦我们将交付平台标准化为使用 Kubernetes,将大多数工作负载运行在那里是有意义的。但是,我们的工作负载及其提供的价值类型可能会有很大差异。长期运行的 Web 服务的可靠性标准与 ML 模型训练或定期批处理作业的可靠性标准不同。此外,还需要考虑环境成熟度。开发实验、性能测试、CI 作业和一次性维护程序具有不同的可用性要求和合理的运营成本。
节点选择
根据所需的可用性级别和节省的工程时间,定义用于集群的 VM 实例类型(例如,选择抢占式实例而不是预留容量)。
您可以使用LearnK8S Kubernetes 实例计算器 进行初始规划。
所有云提供商现在都提供基于专用操作系统(如 Bottlerocket OS)或 ARM 处理器的优化实例。
使用此类实例可以使我们的集群更精益、更便宜,但需要事先验证它们是否适合我们的特定工作负载。
网络拓扑限制
仔细选择集群的网络拓扑结构会对云账单产生重大影响,尤其是在运行数据密集型工作负载时。在创建大多数集群时,默认情况下会在三个可用区中运行数据平面以提高可用性。集群内跨 AZ 网络传输的每个字节都会花费您额外的几分钱。因此,当可用性不是我们想要实现的价值的一部分(例如,对于后台批处理)时,有意义地覆盖默认设置并在同一个 AZ 中运行所有节点。
存储配置
Kubernetes 提供多种存储选项,它们在持久性、可用性和性能级别方面有所不同。专注于提供的价值,我们可以为工作负载选择最合适的存储类型。
2. 消除风险
最初的丰田生产系统开创了安灯线的概念——一根贯穿整个工厂的电缆,任何工人可以拉动它来停止生产线。这个想法是管理层信任工人是他们所在领域的专家,因此他们应该在发现任何他们认为对生产质量构成风险的问题时拉动电缆。任何潜伏的风险都可能导致后续的重大浪费。Kubernetes 的工作方式相同。因此,在考虑浪费之前,应该处理具有潜在安全性和可靠性风险的工作负载。
以下是一些常见的 Kubernetes 工作负载风险及其缓解方法:
未定义的资源请求和限制
当未定义请求和限制时,Kubernetes 调度程序将所有 pod 都视为 BestEffort pod。这意味着没有任何可靠性保证。这可以通过使用 LimitRange 对象来一定程度地防止,但需要持续的 pod 调整大小(下一节中描述)来缓解这种情况。
资源请求和限制不足
这意味着我们的 pod 没有获得所需的资源,这会导致意外故障和延迟增加,从而影响应用程序的可靠性。
容器重启
容器是临时的,可以在发生故障时无缝重启。这是最常见的 Kubernetes 工作负载类型(如 Deployment 和 DaemonSet)的默认操作模式。然而,频繁发生的重启表明存在问题。无论是应用程序错误、权限问题还是配置错误的存活探测,我们都希望尽快对其进行故障排除和修复,以保持集群精益。
这里还有其他类型的风险。我们需要一个目标可观察性系统来发现并提醒我们集群中的可靠性风险,以及智能自主自动化来修复最常见的问题。
3. 消除浪费
如前所述,大多数集群需要更高效地利用。换句话说,使用大量云资源会导致过度支出。
我们希望为工作负载提供尽可能多的资源,这是可以理解的——没有工程师希望他们的应用程序因为 CPU 限制而像乌龟一样缓慢爬行,或者因为 OOM 杀死而悲惨地死亡。但遗憾的是,即使给一个容器提供三到四倍的资源,也无法提供可靠性保证!同一节点上可能存在其他配置错误的容器,它们具有不足的请求和过度的限制,导致我们的容器即使在我们的慷慨帮助下也无法获得资源。
要达到所需的可靠性和成本目标,唯一的方法是了解集群中浪费的来源,并建立一个持续消除浪费的过程。
以下是一些每个 Kubernetes 管理员都应该采用的实践,以保持其集群无浪费:
Pod 调整大小
代码语言:javascript复制apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
正确定义 pod 中容器的资源请求和限制会影响所有内容,从基本调度和驱逐到 HPA 操作和节点自动扩展。问题是,这需要大量的工作才能确定。性能测试 可以帮助进行初始定义。然而,Kubernetes 环境的动态性要求我们持续监控运行时资源消耗并相应地更新配置,最好以自动化的方式。这是确保我们的容器在需要时获得所需资源的唯一方法。
节点利用率监控
即使我们的容器资源经过优化,我们仍然会遇到额外的浪费,因为我们的节点选择不是最佳的。这可能是由于在适当的时候没有使用折扣 Spot 实例和预留实例,或者配置了资源无法被活动工作负载有效利用的实例类型。精益集群必须由一个自动化系统进行管理,该系统提供节点组和类型级别的节点利用率的细粒度可见性,并提供智能建议,以重新配置节点池以进行进一步优化。
4. 及时供应
未使用的基础设施会浪费我们的资金,并产生不必要的维护开销,而不会增加任何额外价值。精益方法的核心是在需要时提供资源,并在不再需要时释放资源。
以下是一些保持集群精益的方法:
自动扩展
自动扩展功能使 Kubernetes 真正成为云原生。然而,它们是可选的!定义自动扩展需要在 Pod(HPA、VPA、KEDA)或节点级别(cluster-autoscaler、Karpenter 等)进行额外的配置。保持集群精益意味着投资于此配置,持续验证自动扩展算法的效率,并对其进行优化以适应系统不断变化的需求。
即时节点供应
并非所有节点自动扩展器都是相同的。例如,传统的 cluster-autoscaler 的效率受到静态 ASG 配置的限制。精益意味着在需要时精确地供应我们需要的资源——因此,精益集群迁移到 Karpenter(如果在 AWS 上)或节点自动供应(在 GCP 和 Azure 上)。
动态环境管理
一个完善的 Kubernetes 自动化设置允许我们通过在现有集群中创建命名空间或启动新的集群来快速配置新环境。这种易用性会导致许多资源未被充分利用。保持精益需要制定一个操作策略来管理这些环境,并在不再需要时将其退役。请参阅 此处 以了解如何在非工作时间将 Kubernetes 资源置于休眠状态的示例。
5. 持续优化
精益方法基于持续改进的理念——即始终寻找使生产流程更高效、提高质量和减少浪费的额外方法。
同样,我们希望通过自动化资源分配、分析成本和性能趋势、重新定义 SLO 以及不懈地消除风险来持续优化 Kubernetes 集群。
总结
遵循精益方法可以帮助我们显著提高 Kubernetes 的投资回报率,改善工作负载性能,并节省用于维护和故障排除的时间。
为了保持集群精益——请遵循以下指南:
- 专注于价值
- 消除风险
- 消除浪费
- 即时供应
- 持续优化
愿您的集群保持精益!