
如果你选择在公共云中运行Kubernetes集群,那么你可能需要了解Kubernetes云控制器管理器(Cloud Controller Manager)。虽然云控制器管理器在大多数关于 Kubernetes 组件的讨论中并不显眼,但它在简化Kubernetes在云中的部署和管理方面起着至关重要的作用。
为了提供关于为什么以及如何使用云控制器管理器的指导,本文将解释该组件的工作原理、重要性以及如何开始使用它。
什么是 Kubernetes 云控制器管理器?
云控制器管理器是 Kubernetes 中的一个组件,它将 Kubernetes 集群与特定的云平台集成——如 Amazon Web Services(AWS)、Microsoft Azure 和 Google Cloud Platform(GCP)。
云控制器管理器是 Kubernetes 控制平面的一部分,控制平面是负责管理 Kubernetes 集群的核心服务集。
云控制器管理器的作用是什么?
云控制器管理器解决了工程师在云中部署 Kubernetes 时面临的一个关键挑战:需要将 Kubernetes 与各种云平台进行集成,而每个云平台的工作方式都不同。
为了理解为什么这很重要,我们可以从基础设施的角度来看待 Kubernetes。理论上,Kubernetes 之所以如此流行的原因之一是它是一个开源、与厂商无关的平台。这意味着,Kubernetes 在设置集群时不太依赖于你选择的部署位置——无论是在本地还是在各种公共云中,它的工作方式基本一致。
换句话说,Kubernetes 理论上对每个节点(即构成 Kubernetes 集群的服务器)进行相同的处理。无论节点运行的是什么操作系统内核、什么类型的 CPU,是虚拟机还是裸金属,都不应该影响 Kubernetes 的行为。
然而,不同的云平台在托管 Kubernetes 集群时确实存在细微的差异。每个云提供商使用不同的 API 来创建和管理作为 Kubernetes 节点的服务器,以及配置网络负载均衡器等资源。
这意味着 Kubernetes 不能完全忽视其所托管的基础设施平台,无法做到真正的与厂商无关。它需要能够支持托管集群的平台所特有的 API。
这就是云控制器管理器的作用。云控制器管理器基本上充当了一个兼容层,将通用的 Kubernetes 请求——比如“识别节点的 IP 地址”或“创建负载均衡器”——转换为适用于特定云平台的 API 请求。
云控制器管理器的好处
云控制器管理器的主要好处在于,它为 Kubernetes 提供了一种与云提供商的 API 交互的简单方式,用户不需要进行特殊的配置或编写代码。集群管理员只需要选择要集成的云平台,然后启用相应的云控制器管理器。
此外,从 Kubernetes 项目的角度来看,云控制器管理器的好处在于它将与云相关的兼容性逻辑分离为一个独立的组件。这样,Kubernetes 控制平面无需直接构建对每个云平台 API 的支持,而是采用插件架构,使各个云提供商可以编写 Kubernetes 与其 API 集成所需的逻辑,然后将其作为一个组件提供给 Kubernetes 用户,用户可以选择启用。
这种方法使云提供商能够根据需要更新兼容层,以保持与其 API 的同步。同时,它也避免了 Kubernetes 开发人员需要负责维护核心代码库中的兼容性逻辑。
何时使用云控制器管理器
在大多数情况下,决定是否使用云控制器管理器是相对简单的。基本的考虑因素如下:
- 如果你在公共云平台上运行 Kubernetes,你应该启用该组件。例外情况是,当你的集群非常简单,并且不包含任何复杂的节点或网络配置时。在这种情况下,云控制器管理器可能不是必需的,因为你不会发出需要使用云提供商 API 的请求。
- 如果你在自己管理的裸金属服务器上运行 Kubernetes,则不需要云控制器管理器,因为 Kubernetes 可以直接与节点和其他资源进行交互,而不必使用特定的 API。
如何使用云控制器管理器
在大多数 Kubernetes 发行版中,云控制器管理器默认安装,但默认情况下并未启用。(一个例外是大多数托管的 Kubernetes 服务,如 Amazon EKS,默认使用云控制器管理器来与云主机环境集成。)
如果你在没有使用托管云服务的情况下部署了 Kubernetes 集群,并且希望启用云控制器管理器,可以在集群中的 kube-controller-manager、kube-apiserver 和 kubelet 配置设置中添加以下选项:
--cloud-provider=external
(注意:如果 kube-controller-manager、kube-apiserver 或 kubelet 已经在运行,修改配置后需要停止并重新启动它们,才能使更改生效。)
然后,部署与你所使用的云平台相匹配的云控制器管理器。你可以通过创建一个 DaemonSet 来完成此操作,以下是 Kubernetes 文档中的示例 YAML 代码:
# 这是在集群中将 cloud-controller-manager 设置为 DaemonSet 的示例。
# 假设你的主节点能够运行 pod,并且有 role node-role.kubernetes.io/master
# 请注意,这个 DaemonSet 并不能直接适用于你的云平台,它只是
# 提供一个参考模板。
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:cloud-controller-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
k8s-app: cloud-controller-manager
name: cloud-controller-manager
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: cloud-controller-manager
template:
metadata:
labels:
k8s-app: cloud-controller-manager
spec:
serviceAccountName: cloud-controller-manager
containers:
- name: cloud-controller-manager
# 对于内建的提供商,我们使用 registry.k8s.io/cloud-controller-manager
# 这可以替换为其他外部提供商的镜像
image: registry.k8s.io/cloud-controller-manager:v1.8.0
command:
- /usr/local/bin/cloud-controller-manager
- --cloud-provider=[YOUR_CLOUD_PROVIDER] # 请在此处添加你自己的云提供商!
- --leader-elect=true
- --use-service-account-credentials
# 这些标志对于每个云提供商都会有所不同
- --allocate-node-cidrs=true
- --configure-cloud-routes=true
- --cluster-cidr=172.17.0.0/16
tolerations:
# 这对于 CCM 启动至关重要
- key: node.cloudprovider.kubernetes.io/uninitialized
value: "true"
effect: NoSchedule
# 以下是为了让 DaemonSet 能在控制平面节点上运行
# 如果你的控制平面节点不应运行 pod,请删除这些 tolerations
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
# 这是为了限制 CCM 只在主节点上运行
# 节点选择器可能根据你的集群设置有所不同
nodeSelector:
node-role.kubernetes.io/master: ""
确保根据需要更改示例代码中的 `YOUR_CLOUD_PROVIDER` 字段和网络设置。
另外,你也可以根据云提供商的控制器管理器代码构建并运行容器镜像。Azure 提供了如何在其 GitHub 仓库中执行此操作的指南,GCP 也在 GitHub 上维护着云控制器管理器的代码。同样,AWS 提供了在 GitHub 上使用预存在资源部署云控制器管理器的文档。











