雲控制器管理器管理

特性狀態: Kubernetes v1.11 [beta]

由於雲提供商開發和釋出的速度與 Kubernetes 專案不同,將提供商特定的程式碼抽象到 cloud-controller-manager 二進位制檔案允許雲廠商獨立於 Kubernetes 核心程式碼進行演進。

cloud-controller-manager 可以連結到任何滿足 cloudprovider.Interface 的雲提供商。為了向後相容,Kubernetes 核心專案提供的 cloud-controller-manager 使用與 kube-controller-manager 相同的雲庫。 Kubernetes 核心中已支援的雲提供商預計將使用樹內 cloud-controller-manager 逐步脫離 Kubernetes 核心。

管理

要求

每個雲提供商都有自己的一套運行雲提供商整合服務的需求,這應該與執行 kube-controller-manager 的需求沒有太大區別。通常你需要:

  • 雲認證/授權:你的雲提供商可能需要令牌或 IAM 規則來允許訪問其 API
  • Kubernetes 認證/授權:cloud-controller-manager 可能需要設定 RBAC 規則才能與 Kubernetes apiserver 通訊
  • 高可用性:與 kube-controller-manager 類似,你可能希望使用領導者選舉(預設為開啟)為雲控制器管理器設定高可用性。

執行 cloud-controller-manager

成功執行 cloud-controller-manager 需要對你的叢集配置進行一些更改。

  • kubeletkube-apiserverkube-controller-manager 必須根據使用者對外部 CCM 的使用情況進行設定。如果使用者使用外部 CCM(而不是 Kubernetes Controller Manager 中的內部雲控制器迴圈),則必須指定 --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(容器儲存介面)的發展以及對彈性卷外掛的更強支援,雲控制器管理器將新增必要的支援,以便雲可以完全與卷整合。在此處瞭解更多關於樹外 CSI 卷外掛的資訊 here

可伸縮性

cloud-controller-manager 查詢雲提供商的 API 以檢索所有節點的資訊。對於非常大的叢集,請考慮可能的瓶頸,例如資源需求和 API 速率限制。

雞生蛋還是蛋生雞的問題

雲控制器管理器專案的目標是將雲功能的開發與 Kubernetes 核心專案解耦。不幸的是,Kubernetes 專案的許多方面都假定雲提供商功能與專案緊密整合。因此,採用這種新架構可能會產生幾種情況,即正在請求來自雲提供商的資訊,但云控制器管理器可能無法在原始請求完成之前返回該資訊。

一個很好的例子是 Kubelet 中的 TLS 引導功能。TLS 引導假設 Kubelet 能夠向雲提供商(或本地元資料服務)請求其所有地址型別(私有、公共等),但云控制器管理器無法在未首先初始化的情況下設定節點的地址型別,這需要 kubelet 具有 TLS 證書才能與 apiserver 通訊。

隨著這項倡議的發展,將在即將釋出的版本中進行更改以解決這些問題。

下一步

要構建和開發你自己的雲控制器管理器,請閱讀 開發雲控制器管理器