本文已发布一年多。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不准确。

Cluster API v1alpha3 带来新功能和改进的用户体验

Cluster API Logo: Turtles All The Way Down

Cluster API 是一个 Kubernetes 项目,旨在为集群创建、配置和管理提供声明式、Kubernetes 风格的 API。它在核心 Kubernetes 之上提供了可选的、附加的功能,用于管理 Kubernetes 集群的生命周期。

在 2019 年 10 月发布 v1alpha2 后,Cluster API 社区的许多成员在加利福尼亚州旧金山会面,计划下一次发布。该项目刚刚经历了重大的转型,交付了新的架构,承诺使项目更容易被用户采用,并加快社区的构建速度。在那两天里,我们找到了共同的目标:实现管理生产集群的关键功能,使其用户体验更加直观,并让开发变得愉快。

Cluster API 的 v1alpha3 版本为任何在生产环境中大规模运行 Kubernetes 的人带来了重要功能。其中包括:

对于任何想要理解 API,或者重视简单而强大的命令行界面的人来说,新版本带来了:

最后,对于任何为其定制基础设施或软件需求扩展 Cluster API 的人来说:

所有这一切都得益于众多贡献者的辛勤工作。

声明式控制平面管理

特别感谢 Jason DeTiberus, Naadir Jeewa, 和 Chuck Ha

基于 Kubeadm 的控制平面 (KCP) 提供了声明式 API,用于部署和扩缩容 Kubernetes 控制平面,包括 etcd。这是许多 Cluster API 用户一直在等待的功能!到目前为止,要部署和扩缩容控制平面,用户必须创建特殊构建的 Machine 资源。要缩减控制平面,他们必须手动从 etcd 集群中移除成员。KCP 实现了部署、扩缩容和升级的自动化。

什么是 Kubernetes 控制平面? Kubernetes 控制平面核心是 kube-apiserver 和 etcd。如果其中任何一个不可用,就无法处理 API 请求。这不仅影响核心 Kubernetes API,也影响使用 CRD 实现的 API。其他组件,如 kube-scheduler 和 kube-controller-manager,也很重要,但对可用性没有同样的影响。

控制平面最初很重要,因为它负责调度工作负载。然而,一些工作负载可以在控制平面中断期间继续运行。如今,工作负载依赖于 operator、服务网格和 API 网关,它们都使用控制平面作为平台。因此,控制平面的可用性比以往任何时候都更加重要。

管理控制平面是集群操作中最复杂的部分之一。由于典型的控制平面包括 etcd,它是有状态的,操作必须按正确顺序执行。控制平面副本可能并且确实会发生故障,而保持控制平面可用性意味着能够替换发生故障的节点。

控制平面可能遭受完全中断(例如 etcd 永久丢失 quorum),而恢复(以及定期备份)有时是唯一可行的选择。

更多详情,请参阅 Kubernetes 文档中关于 Kubernetes 组件的部分。

这里是一个 3 副本控制平面的示例,用于 Cluster API Docker 基础设施,该基础设施为测试和开发而维护。为简洁起见,未显示其他所需的资源,如 Cluster 和 Infrastructure Template,这些资源通过其名称和命名空间引用。

apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
kind: KubeadmControlPlane
metadata:
  name: example
spec:
  infrastructureTemplate:
    apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
    kind: DockerMachineTemplate
    name: example
    namespace: default
  kubeadmConfigSpec:
    clusterConfiguration:
  replicas: 3
  version: 1.16.3

使用 kubectl 部署此控制平面

kubectl apply -f example-docker-control-plane.yaml

像扩缩容其他 Kubernetes 资源一样扩缩容控制平面

kubectl scale kubeadmcontrolplane example  --replicas=5
kubeadmcontrolplane.controlplane.cluster.x-k8s.io/example scaled

将控制平面升级到 Kubernetes 发布版本的更新补丁

kubectl patch kubeadmcontrolplane example --type=json -p '[{"op": "replace", "path": "/spec/version", "value": "1.16.4"}]'

控制平面副本数量 默认情况下,KCP 配置为管理 etcd,并且需要奇数个副本。如果 KCP 配置为不管理 etcd,则建议使用奇数,但不是必需的。奇数个副本可确保最佳 etcd 配置。要了解为什么 etcd 集群应具有奇数个成员,请参阅 etcd 常见问题解答

作为核心 Cluster API 组件,KCP 可与任何提供固定控制平面端点(即负载均衡器或虚拟 IP)的 v1alpha3 兼容基础设施提供商一起使用。此端点使请求能够到达多个控制平面副本。

什么是基础设施提供商? 计算资源(例如机器、网络等)的来源。社区维护着 AWS、Azure、Google Cloud 和 VMWare 的提供商。详细信息请参阅 Cluster API 手册中的提供商列表

分布式控制平面节点以降低风险

特别感谢 Vince Prignano, 和 Chuck Ha

Cluster API 用户现在可以在不同的故障域中部署节点,从而降低因域中断导致集群故障的风险。这对于控制平面尤其重要:如果某个域中的节点发生故障,只要控制平面对其他域中的节点可用,集群就可以继续运行。

什么是故障域? 故障域是一种对因某种故障而变得不可用的资源进行分组的方式。例如,在许多公有云中,“可用区”是默认的故障域。一个区域对应一个数据中心。因此,如果特定数据中心因停电或自然灾害而宕机,该区域中的所有资源将变得不可用。如果您在自己的硬件上运行 Kubernetes,您的故障域可能是机架、网络交换机或配电单元。

基于 Kubeadm 的控制平面将节点分布到不同的故障域中。为了最大限度地减少在域中断事件中丢失多个节点的机会,它会尝试均匀分布它们:它会在现有节点最少的故障域中部署新节点,并会在现有节点最多的故障域中移除现有节点。

MachineDeployment 和 MachineSet 不会在故障域之间分布节点。要将工作节点部署到多个故障域中,请为每个故障域创建一个 MachineDeployment 或 MachineSet。

故障域 API 适用于任何基础设施。这是因为每个基础设施提供商都有自己的故障域映射方式。该 API 是可选的,因此如果您的基础设施不够复杂,不需要故障域,则无需支持它。此示例适用于 Cluster API Docker 基础设施提供商。请注意,其中两个域被标记为适合控制平面节点,而第三个则不适合。基于 Kubeadm 的控制平面只会在标记为适合的域中部署节点。

apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
kind: DockerCluster
metadata:
  name: example
spec:
  controlPlaneEndpoint:
    host: 172.17.0.4
    port: 6443
  failureDomains:
    domain-one:
      controlPlane: true
    domain-two:
      controlPlane: true
    domain-three:
      controlPlane: false

由 Cluster API 项目维护的 AWS 基础设施提供商 (CAPA) 将故障域映射到 AWS 可用区。使用 CAPA,您可以将集群部署到多个可用区。首先,为多个可用区定义子网。CAPA 控制器将为每个可用区定义一个故障域。使用 KubeadmControlPlane 部署控制平面:它会将副本分布到不同的故障域中。最后,为每个故障域创建一个单独的 MachineDeployment。

自动化替换不健康节点

特别感谢 Alberto García Lamela, 和 Joel Speed

节点不健康的原因有很多。kubelet 进程可能停止。容器运行时可能存在错误。内核可能存在内存泄漏。磁盘可能空间不足。CPU、磁盘或内存硬件可能发生故障。可能发生停电。此类故障在大规模集群中尤其常见。

Kubernetes 旨在容忍这些故障,并帮助您的应用也容忍它们。然而,在集群资源耗尽、Pod 被驱逐或根本无法调度之前,只有有限数量的节点可以不健康。应尽快修复或替换不健康的节点。

Cluster API 现在包含一个 MachineHealthCheck 资源以及一个监视节点健康状况的控制器。当它检测到不健康的节点时,会将其移除。(另一个 Cluster API 控制器会检测到节点已被移除并将其替换。)您可以根据需要配置控制器。您可以配置在移除节点之前等待多久。您还可以设置不健康节点的数量阈值。达到阈值后,不再移除节点。等待时间可用于容忍短暂的中断,阈值可防止同时替换过多节点。

该控制器只会移除由 Cluster API MachineSet 管理的节点。控制器不移除控制平面节点,无论是基于 Kubeadm 的控制平面管理的,还是像 v1alpha2 中那样由用户管理的。更多详情,请参阅 MachineHealthCheck 的限制和注意事项

这里是一个 MachineHealthCheck 的示例。更多详情,请参阅 Cluster API 手册中的配置 MachineHealthCheck

apiVersion: cluster.x-k8s.io/v1alpha3
kind: MachineHealthCheck
metadata:
  name: example-node-unhealthy-5m
spec:
  clusterName: example
  maxUnhealthy: 33%
  nodeStartupTimeout: 10m
  selector:
    matchLabels:
      nodepool: nodepool-0
  unhealthyConditions:
  - type: Ready
    status: Unknown
    timeout: 300s
  - type: Ready
    status: "False"
    timeout: 300s

支持基础设施管理的节点组

特别感谢 Juan-Lee PangCecile Robert-Michon

如果您运行大型集群,您需要创建和销毁数百个节点,有时只需几分钟。尽管公有云使得处理大量节点成为可能,但为创建或删除每个节点都进行单独的 API 请求可能会影响扩缩容性能。例如,API 请求可能需要延迟以保持在速率限制内。

一些公有云提供 API,可以将节点组作为一个单一实体进行管理。例如,AWS 有 AutoScaling Groups,Azure 有 Virtual Machine Scale Sets,GCP 有 Managed Instance Groups。通过此版本 Cluster API,基础设施提供商可以添加对这些 API 的支持,并且用户可以使用 MachinePool 资源部署 Cluster API Machine 组。更多信息请参阅 Cluster API 仓库中的提案

实验性功能 MachinePool API 是一个实验性功能,默认情况下未启用。鼓励用户试用并报告其满足需求的程度。

Cluster API 用户体验,重塑

clusterctl

特别感谢 Fabrizio Pandini

如果您是 Cluster API 的新手,您的初体验很可能来自该项目的命令行工具 clusterctl。而随着新的 Cluster API 发布,它已经被重新设计得比以往更易于使用。该工具就是您只需几个步骤即可部署第一个工作负载集群所需的全部。

首先,使用 clusterctl init [获取基础设施和引导提供商的配置](https://cluster-api.sigs.k8s.io/clusterctl/commands/init.html),并部署组成 Cluster API 的所有组件。其次,使用 clusterctl config cluster [创建工作负载集群清单](https://cluster-api.sigs.k8s.io/clusterctl/commands/config-cluster.html)。这个清单只是一系列 Kubernetes 对象。要创建工作负载集群,只需对清单执行 kubectl apply。如果这个流程看起来很熟悉,请不要惊讶:使用 Cluster API 部署工作负载集群就像使用 Kubernetes 部署应用工作负载一样!

Clusterctl 还能帮助进行“第二天”操作。使用 clusterctl move [迁移 Cluster API 自定义资源](https://cluster-api.sigs.k8s.io/clusterctl/commands/move.html),例如 Cluster 和 Machine,从一个[管理集群](https://cluster-api.sigs.k8s.io/reference/glossary.html#management-cluster)到另一个。这一步——也称为[枢纽](https://cluster-api.sigs.k8s.io/reference/glossary.html#pivot)——对于创建一个使用 Cluster API 管理自身的工作负载集群是必需的。最后,当有新的 Cluster API 版本可用时,使用 clusterctl upgrade [升级所有已安装的组件](https://cluster-api.sigs.k8s.io/clusterctl/commands/upgrade.html)。

还有一点!Clusterctl 不仅是一个命令行工具。它也是一个 Go 库!可以将该库视为构建在 Cluster API 之上的项目的集成点。clusterctl 的所有命令行功能都在该库中提供,这使得将其轻松集成到您的技术栈中。要开始使用该库,请阅读其[文档](https://pkg.go.dev/sigs.k8s.io/cluster-api@v0.3.1/cmd/clusterctl/client?tab=doc)。

Cluster API 文档集

感谢众多贡献者!

该项目的[文档](https://cluster-api.sigs.k8s.io/)非常丰富。新用户应先了解一些[架构背景](https://cluster-api.sigs.k8s.io/user/concepts.html),然后通过[快速入门](https://cluster-api.sigs.k8s.io/user/quick-start.html)创建自己的集群。clusterctl 工具拥有自己的[参考文档](https://cluster-api.sigs.k8s.io/clusterctl/overview.html)。[开发者指南](https://cluster-api.sigs.k8s.io/developer/guide.html)为任何有兴趣为项目做贡献的人提供了大量信息。

除了内容本身,该项目的文档网站使用起来也很愉快。它可搜索,有大纲,甚至支持不同的颜色主题。如果您觉得这个网站很像另一个社区项目 [Kubebuilder](https://book.kubebuilder.io/) 的文档,那并非巧合!非常感谢 Kubebuilder 的作者们创建了优秀的文档示例。也非常感谢 [mdBook](https://github.com/rust-lang/mdBook) 的作者们创建了优秀的文档构建工具。

集成与自定义

端到端测试框架

特别感谢 Chuck Ha

Cluster API 项目被设计为可扩展的。例如,任何人都可以开发自己的基础设施和引导提供商。然而,提供商以统一的方式工作非常重要。并且,由于项目仍在发展中,确保提供商与核心项目的新版本保持同步需要付出努力。

端到端测试框架为开发者提供了一套标准测试,用于验证他们的提供商是否与当前版本的 Cluster API 正确集成,并帮助识别在 Cluster API 或提供商新版本发布后发生的任何回归问题。

有关该框架的更多详细信息,请参见 Cluster API 文档集中的[测试](https://cluster-api.sigs.k8s.io/developer/testing.html?highlight=e2e#running-the-end-to-end-tests)以及仓库中的 [README](https://github.com/kubernetes-sigs/cluster-api/tree/master/test/framework)。

提供商实现者指南

感谢众多贡献者!

社区为许多流行的基础设施维护[基础设施提供商](https://cluster-api.sigs.k8s.io/reference/providers.html)。然而,如果您想构建自己的基础设施或引导提供商,[提供商实现者指南](https://cluster-api.sigs.k8s.io/developer/providers/implementers-guide/overview.html)解释了整个过程,从创建 git 仓库,到为您的提供商创建 CustomResourceDefinitions,再到设计、实现和测试控制器。

积极开发中 提供商实现者指南正在积极开发中,可能尚未反映 v1alpha3 版本的所有变更。

加入我们!

Cluster API 项目是一个非常活跃的项目,涵盖了许多感兴趣的领域。如果您是基础设施专家,可以为其中一个基础设施提供商做贡献。如果您喜欢构建控制器,您会找到创新的机会。如果您对测试分布式系统感到好奇,可以帮助开发项目的端到端测试框架。无论您的兴趣和背景如何,您都能对项目产生实际影响。

来我们的每周会议上向社区介绍自己吧,我们会在会议中留出专门的时间进行问答环节。您也可以在 Kubernetes Slack 和 Kubernetes 论坛中找到维护者和用户。请查看下面的链接。我们期待您的加入!