完成 Kubernetes 史上最大规模迁移

早自 Kubernetes v1.7 起,Kubernetes 项目就开始追求取消集成内置云驱动 (KEP-2395)。 虽然这些集成对于 Kubernetes 的早期发展和增长发挥了重要作用,但它们的移除是由两个关键因素驱动的: 为各云启动维护数百万行 Go 代码的原生支持所带来的日趋增长的复杂度,以及将 Kubernetes 打造为真正的供应商中立平台的愿景。

历经很多发布版本之后,我们很高兴地宣布所有云驱动集成组件已被成功地从核心 Kubernetes 仓库迁移到外部插件中。 除了实现我们最初的目标之外,我们还通过删除大约 150 万行代码,将核心组件的可执行文件大小减少了大约 40%, 极大简化了 Kubernetes。

由于受影响的组件众多,而且关键代码路径依赖于五个初始云驱动(Google Cloud、AWS、Azure、OpenStack 和 vSphere) 的内置集成,因此此次迁移是一项复杂且耗时的工作。 为了成功完成此迁移,我们必须从头开始构建四个新的子系统:

  1. 云控制器管理器(Cloud controller manager)KEP-2392
  2. API 服务器网络代理KEP-1281
  3. kubelet 凭证提供程序插件KEP-2133
  4. 存储迁移以使用 CSIKEP-625

就与内置功能实现完全的特性等价而言,每个子系统都至关重要, 并且需要迭代多个版本才能使每个子系统达到 GA 级别并具有安全可靠的迁移路径。 下面详细介绍每个子系统。

云控制器管理器

云控制器管理器是这项工作中引入的第一个外部组件,取代了 kube-controller-manager 和 kubelet 中直接与云 API 交互的功能。 这个基本组件负责通过施加元数据标签来初始化节点。所施加的元数据标签标示节点运行所在的云区域和可用区, 以及只有云驱动知道的 IP 地址。 此外,它还运行服务控制器,该控制器负责为 LoadBalancer 类型的 Service 配置云负载均衡器。

Kubernetes 组件

要进一步了解相关信息,请阅读 Kubernetes 文档中的云控制器管理器

API 服务器网络代理

API 服务器网络代理项目于 2018 年与 SIG API Machinery 合作启动,旨在取代 kube-apiserver 中的 SSH 隧道功能。 该隧道器原用于安全地代理 Kubernetes 控制平面和节点之间的流量,但它重度依赖于 kube-apiserver 中所嵌入的、特定于提供商的实现细节来建立这些 SSH 隧道。

现在,API 服务器网络代理成为 kube-apiserver 中 GA 级别的扩展点。 提供了一种通用代理机制,可以通过一个安全的代理将流量从 API 服务器路由到节点, 从而使 API 服务器无需了解其运行所在的特定云驱动。 此项目还引入了 Konnectivity 项目,该项目在生产环境中的采用越来越多。

你可以在其 README 中了解有关 API 服务器网络代理的更多信息。

kubelet 的凭据提供程序插件

kubelet 凭据提供程序插件的开发是为了取代 kubelet 的内置功能,用于动态获取用于托管在 Google Cloud、AWS 或 Azure 上的镜像仓库的凭据。 原来所实现的功能很方便,因为它允许 kubelet 无缝地获取短期令牌以从 GCR、ECR 或 ACR 拉取镜像 然而,与 Kubernetes 的其他领域一样,支持这一点需要 kubelet 具有不同云环境和 API 的特定知识。

凭据驱动插件机制于 2019 年推出,为 kubelet 提供了一个通用扩展点用于执行插件的可执行文件, 进而为访问各种云上托管的镜像动态提供凭据。 可扩展性扩展了 kubelet 获取短期令牌的能力,且不受限于最初的三个云驱动。

要了解更多信息,请阅读用于认证镜像拉取的 kubelet 凭据提供程序

存储插件从树内迁移到 CSI

容器存储接口(Container Storage Interface,CSI)是一种控制平面标准,用于管理 Kubernetes 和其他容器编排系统中的块和文件存储系统,已在 1.13 中进入正式发布状态。 它的设计目标是用可在 Kubernetes 集群中 Pod 内运行的驱动程序替换直接内置于 Kubernetes 中的树内卷插件。 这些驱动程序通过 Kubernetes API 与 kube-controller-manager 存储控制器通信,并通过本地 gRPC 端点与 kubelet 进行通信。 现在,所有主要云和存储供应商一起提供了 100 多个 CSI 驱动,使 Kubernetes 中运行有状态工作负载成为现实。

然而,如何处理树内卷 API 的所有现有用户仍然是一个重大挑战。 为了保持 API 向后兼容性,我们在控制器中构建了一个 API 转换层,把树内卷 API 转换为等效的 CSI API。 这使我们能够将所有存储操作重定向到 CSI 驱动程序,为我们在不删除 API 的情况下删除内置卷插件的代码铺平了道路。

你可以在 Kubernetes 树内卷到 CSI 卷的迁移进入 Beta 阶段

下一步是什么?

过去几年,这一迁移工程一直是 SIG Cloud Provider 的主要关注点。 随着这一重要里程碑的实现,我们将把努力转向探索新的创新方法,让 Kubernetes 更好地与云驱动集成,利用我们多年来构建的外部子系统。 这包括使 Kubernetes 在混合环境中变得更加智能,其集群中的节点可以运行在公共云和私有云上, 以及为外部驱动的开发人员提供更好的工具和框架,以简化他们的集成工作,提高效率。

在规划所有这些新特性、工具和框架的同时,SIG Cloud Provider 并没有忘记另一项同样重要的工作:测试。 SIG 未来活动的另一个重点领域是改进云控制器测试以涵盖更多的驱动。 这项工作的最终目标是创建一个包含尽可能多驱动的测试框架,以便我们让 Kubernetes 社区对其 Kubernetes 环境充满信心。

如果你使用的 Kubernetes 版本早于 v1.29 并且尚未迁移到外部云驱动,我们建议你查阅我们之前的博客文章 Kubernetes 1.29:云驱动集成现在是单独的组件。 该博客包含与我们所作的变更相关的详细信息,并提供了有关如何迁移到外部驱动的指导。 从 v1.31 开始,树内云驱动将被永久禁用并从核心 Kubernetes 组件中删除。

如果你有兴趣做出贡献,请参加我们的每两周一次的 SIG 会议!