云控制器管理器管理

功能状态: Kubernetes v1.11 [测试版]

由于云提供商的开发和发布速度与 Kubernetes 项目不同,因此将特定于提供商的代码抽象到 云控制器管理器 二进制文件允许云供应商独立于核心 Kubernetes 代码进行演进。

云控制器管理器 可以链接到任何满足 cloudprovider.Interface 的云提供商。为了向后兼容,核心 Kubernetes 项目中提供的 云控制器管理器 使用与 kube-controller-manager 相同的云库。Kubernetes 核心已经支持的云提供商预计将使用树内云控制器管理器从 Kubernetes 核心过渡出去。

管理

要求

每个云都有自己的一套运行其云提供商集成的要求,这与运行 kube-controller-manager 时的要求应该没有太大区别。作为一般经验法则,您需要

  • 云身份验证/授权:您的云可能需要令牌或 IAM 规则才能允许访问其 API
  • Kubernetes 身份验证/授权:云控制器管理器可能需要设置 RBAC 规则才能与 Kubernetes API 服务器通信
  • 高可用性:与 kube-controller-manager 一样,您可能希望使用领导者选举(默认情况下启用)为云控制器管理器设置高可用性。

运行云控制器管理器

成功运行云控制器管理器需要对集群配置进行一些更改。

  • 必须根据用户对外部 CCM 的使用情况设置 kubeletkube-apiserverkube-controller-manager。如果用户拥有外部 CCM(而不是 Kubernetes 控制器管理器中的内部云控制器循环),则必须指定 --cloud-provider=external。否则,不应指定它。

请记住,将集群设置为使用云控制器管理器将在以下几个方面改变您的集群行为

  • 指定 --cloud-provider=external 的组件将在初始化期间添加一个带有 NoSchedule 效果的污点 node.cloudprovider.kubernetes.io/uninitialized。这标志着该节点在可以调度工作之前需要来自外部控制器的第二次初始化。请注意,如果云控制器管理器不可用,则集群中的新节点将保持不可调度状态。污点很重要,因为调度程序可能需要有关节点的云特定信息,例如其区域或类型(高 CPU、GPU、高内存、竞价型实例等)。
  • 集群中节点的云信息将不再使用本地元数据检索,而是所有检索节点信息的 API 调用都将通过云控制器管理器进行。这可能意味着您可以限制 kubelet 对云 API 的访问权限,以提高安全性。对于较大的集群,您可能需要考虑云控制器管理器是否会达到速率限制,因为它现在负责从集群内部向您的云发出的几乎所有 API 调用。

云控制器管理器可以实现

  • 节点控制器 - 负责使用云 API 更新 Kubernetes 节点,并删除在您的云上删除的 Kubernetes 节点。
  • 服务控制器 - 负责针对 LoadBalancer 类型的服务在您的云上进行负载均衡。
  • 路由控制器 - 负责在您的云上设置网络路由
  • 如果您正在运行树外提供程序,则您希望实现的任何其他功能。

示例

如果您使用的云当前在 Kubernetes 核心得到支持,并且您想采用云控制器管理器,请参阅 Kubernetes 核心中的云控制器管理器

对于不在 Kubernetes 核心中的云控制器管理器,您可以在云供应商或 SIG 维护的存储库中找到相应的项目。

对于 Kubernetes 核心已经存在的提供程序,您可以将树内云控制器管理器作为 DaemonSet 在您的集群中运行,使用以下内容作为指南

# This is an example of how to set up cloud-controller-manager as a Daemonset in your cluster.
# It assumes that your masters can run pods and has the role node-role.kubernetes.io/master
# Note that this Daemonset will not work straight out of the box for your cloud, this is
# meant to be a guideline.

---
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
        # for in-tree providers we use registry.k8s.io/cloud-controller-manager
        # this can be replaced with any other image for out-of-tree providers
        image: registry.k8s.io/cloud-controller-manager:v1.8.0
        command:
        - /usr/local/bin/cloud-controller-manager
        - --cloud-provider=[YOUR_CLOUD_PROVIDER]  # Add your own cloud provider here!
        - --leader-elect=true
        - --use-service-account-credentials
        # these flags will vary for every cloud provider
        - --allocate-node-cidrs=true
        - --configure-cloud-routes=true
        - --cluster-cidr=172.17.0.0/16
      tolerations:
      # this is required so CCM can bootstrap itself
      - key: node.cloudprovider.kubernetes.io/uninitialized
        value: "true"
        effect: NoSchedule
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      # this is to restrict CCM to only run on master nodes
      # the node selector may vary depending on your cluster setup
      nodeSelector:
        node-role.kubernetes.io/master: ""

限制

运行云控制器管理器会带来一些可能的限制。尽管这些限制将在即将发布的版本中得到解决,但重要的是,您必须了解生产工作负载的这些限制。

对卷的支持

云控制器管理器没有实现 kube-controller-manager 中的任何卷控制器,因为卷集成也需要与 kubelet 进行协调。随着我们发展 CSI(容器存储接口)并为 Flex 卷插件添加更强大的支持,将在云控制器管理器中添加必要的支持,以便云可以与卷完全集成。在此处详细了解树外 CSI 卷插件 此处

可扩展性

云控制器管理器查询云提供商的 API 以检索所有节点的信息。对于非常大的集群,请考虑可能的瓶颈,例如资源需求和 API 速率限制。

鸡和蛋

云控制器管理器项目的目标是将云功能的开发与核心 Kubernetes 项目分离。不幸的是,Kubernetes 项目的许多方面都假设云提供商功能已紧密集成到项目中。因此,采用这种新架构可能会造成几种情况,即请求从云提供商处获取信息,但云控制器管理器可能无法在原始请求完成之前返回该信息。

Kubelet 中的 TLS 引导功能就是一个很好的例子。TLS 引导假设 Kubelet 能够向云提供商(或本地元数据服务)询问其所有地址类型(私有、公共等),但云控制器管理器无法在未先初始化的情况下设置节点的地址类型,这要求 kubelet 具有 TLS 证书才能与 API 服务器通信。

随着这项计划的发展,将在即将发布的版本中进行更改以解决这些问题。

下一步是什么

要构建和开发您自己的云控制器管理器,请阅读 开发云控制器管理器