設定多個排程器

Kubernetes 隨附一個預設排程器,此排程器在此處 描述。如果預設排程器不符合您的需求,您可以實作自己的排程器。此外,您甚至可以與預設排程器同時執行多個排程器,並指示 Kubernetes 為您的每個 Pod 使用哪個排程器。讓我們學習如何在 Kubernetes 中使用範例執行多個排程器。

如何實作排程器的詳細描述不在本文檔的範圍內。請參考 Kubernetes 原始碼目錄中 pkg/scheduler 中的 kube-scheduler 實作,以取得正規範例。

開始之前

您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用這些 Kubernetes 實驗場景之一

若要檢查版本,請輸入 kubectl version

封裝排程器

將您的排程器二進位檔封裝到容器映像檔中。為了本範例的目的,您可以使用預設排程器 (kube-scheduler) 作為您的第二個排程器。從 GitHub 複製 Kubernetes 原始碼 並建置原始碼。

git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
make

建立包含 kube-scheduler 二進位檔的容器映像檔。以下是建置映像檔的 Dockerfile

FROM busybox
ADD ./_output/local/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler

將檔案另存為 Dockerfile、建置映像檔並將其推送至登錄檔。本範例將映像檔推送至 Google Container Registry (GCR)。如需更多詳細資訊,請閱讀 GCR 文件。或者,您也可以使用 docker hub。如需更多詳細資訊,請參閱 docker hub 文件

docker build -t gcr.io/my-gcp-project/my-kube-scheduler:1.0 .     # The image name and the repository
gcloud docker -- push gcr.io/my-gcp-project/my-kube-scheduler:1.0 # used in here is just an example

為排程器定義 Kubernetes 部署

現在您已將排程器放入容器映像檔中,請為其建立 Pod 組態並在您的 Kubernetes 叢集中執行。但是,在本範例中,您可以改用 部署,而不是直接在叢集中建立 Pod。部署 管理 Replica Set,而 Replica Set 又管理 Pod,從而使排程器能夠彈性地應對故障。以下是部署組態。將其另存為 my-scheduler.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-scheduler
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-scheduler-as-kube-scheduler
subjects:
- kind: ServiceAccount
  name: my-scheduler
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: system:kube-scheduler
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-scheduler-as-volume-scheduler
subjects:
- kind: ServiceAccount
  name: my-scheduler
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: system:volume-scheduler
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-scheduler-extension-apiserver-authentication-reader
  namespace: kube-system
roleRef:
  kind: Role
  name: extension-apiserver-authentication-reader
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: my-scheduler
  namespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scheduler-config
  namespace: kube-system
data:
  my-scheduler-config.yaml: |
    apiVersion: kubescheduler.config.k8s.io/v1beta2
    kind: KubeSchedulerConfiguration
    profiles:
      - schedulerName: my-scheduler
    leaderElection:
      leaderElect: false    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: scheduler
    tier: control-plane
  name: my-scheduler
  namespace: kube-system
spec:
  selector:
    matchLabels:
      component: scheduler
      tier: control-plane
  replicas: 1
  template:
    metadata:
      labels:
        component: scheduler
        tier: control-plane
        version: second
    spec:
      serviceAccountName: my-scheduler
      containers:
      - command:
        - /usr/local/bin/kube-scheduler
        - --config=/etc/kubernetes/my-scheduler/my-scheduler-config.yaml
        image: gcr.io/my-gcp-project/my-kube-scheduler:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10259
            scheme: HTTPS
          initialDelaySeconds: 15
        name: kube-second-scheduler
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10259
            scheme: HTTPS
        resources:
          requests:
            cpu: '0.1'
        securityContext:
          privileged: false
        volumeMounts:
          - name: config-volume
            mountPath: /etc/kubernetes/my-scheduler
      hostNetwork: false
      hostPID: false
      volumes:
        - name: config-volume
          configMap:
            name: my-scheduler-config

在上述資訊清單中,您使用 KubeSchedulerConfiguration 自訂排程器實作的行為。此組態已在初始化期間透過 --config 選項傳遞給 kube-schedulermy-scheduler-config ConfigMap 儲存組態檔。my-scheduler 部署的 Pod 將 my-scheduler-config ConfigMap 掛載為磁碟區。

在上述排程器組態中,您的排程器實作透過 KubeSchedulerProfile 表示。

另請注意,您建立專用的服務帳戶 my-scheduler,並將 ClusterRole system:kube-scheduler 繫結到它,以便它可以取得與 kube-scheduler 相同的權限。

請參閱 kube-scheduler 文件,以取得其他命令列引數的詳細描述,以及 排程器組態參考,以取得其他可自訂的 kube-scheduler 組態的詳細描述。

在叢集中執行第二個排程器

為了在 Kubernetes 叢集中執行您的排程器,請在 Kubernetes 叢集中建立上述組態中指定的部署

kubectl create -f my-scheduler.yaml

驗證排程器 Pod 是否正在執行

kubectl get pods --namespace=kube-system
NAME                                           READY     STATUS    RESTARTS   AGE
....
my-scheduler-lnf4s-4744f                       1/1       Running   0          2m
...

除了此清單中的預設 kube-scheduler Pod 之外,您應該會看到一個「執行中」的 my-scheduler Pod。

啟用領導者選舉

若要執行啟用領導者選舉的多個排程器,您必須執行以下操作

更新 YAML 檔案中 my-scheduler-config ConfigMap 中 KubeSchedulerConfiguration 的下列欄位

  • leaderElection.leaderElecttrue
  • leaderElection.resourceNamespace<lock-object-namespace>
  • leaderElection.resourceName<lock-object-name>

如果您的叢集上已啟用 RBAC,您必須更新 system:kube-scheduler 叢集角色。將您的排程器名稱新增至套用於 endpointsleases 資源的規則之 resourceNames,如下列範例所示

kubectl edit clusterrole system:kube-scheduler
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-scheduler
rules:
  - apiGroups:
      - coordination.k8s.io
    resources:
      - leases
    verbs:
      - create
  - apiGroups:
      - coordination.k8s.io
    resourceNames:
      - kube-scheduler
      - my-scheduler
    resources:
      - leases
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resourceNames:
      - kube-scheduler
      - my-scheduler
    resources:
      - endpoints
    verbs:
      - delete
      - get
      - patch
      - update

為 Pod 指定排程器

現在您的第二個排程器正在執行中,請建立一些 Pod,並指示它們由預設排程器或您部署的排程器進行排程。為了使用特定的排程器來排程給定的 Pod,請在該 Pod 規格中指定排程器的名稱。讓我們看看三個範例。

  • 未指定任何排程器名稱的 Pod 規格

    apiVersion: v1
    kind: Pod
    metadata:
      name: no-annotation
      labels:
        name: multischeduler-example
    spec:
      containers:
      - name: pod-with-no-annotation-container
        image: registry.k8s.io/pause:2.0

    當未提供排程器名稱時,Pod 會自動使用預設排程器進行排程。

    將此檔案儲存為 pod1.yaml 並提交到 Kubernetes 叢集。

    kubectl create -f pod1.yaml
    
  • 具有 default-scheduler 的 Pod 規格

    apiVersion: v1
    kind: Pod
    metadata:
      name: annotation-default-scheduler
      labels:
        name: multischeduler-example
    spec:
      schedulerName: default-scheduler
      containers:
      - name: pod-with-default-annotation-container
        image: registry.k8s.io/pause:2.0
    

    排程器是透過將排程器名稱作為 spec.schedulerName 的值來指定的。在本例中,我們提供預設排程器的名稱,即 default-scheduler

    將此檔案儲存為 pod2.yaml 並提交到 Kubernetes 叢集。

    kubectl create -f pod2.yaml
    
  • 具有 my-scheduler 的 Pod 規格

    apiVersion: v1
    kind: Pod
    metadata:
      name: annotation-second-scheduler
      labels:
        name: multischeduler-example
    spec:
      schedulerName: my-scheduler
      containers:
      - name: pod-with-second-annotation-container
        image: registry.k8s.io/pause:2.0
    

    在本例中,我們指定此 Pod 應使用我們部署的排程器 my-scheduler 進行排程。請注意,spec.schedulerName 的值應與 KubeSchedulerProfile 對應的 schedulerName 欄位中為排程器提供的名稱相符。

    將此檔案儲存為 pod3.yaml 並提交到 Kubernetes 叢集。

    kubectl create -f pod3.yaml
    

    驗證所有三個 Pod 都在執行中。

    kubectl get pods
    

驗證 Pod 是否使用所需的排程器進行排程

為了讓您更容易完成這些範例,我們沒有驗證 Pod 實際上是否使用所需的排程器進行排程。我們可以透過變更上述 Pod 和部署組態提交的順序來驗證。如果我們在提交排程器部署組態之前,將所有 Pod 組態提交到 Kubernetes 叢集,我們會看到 Pod annotation-second-scheduler 永遠保持在「Pending」狀態,而其他兩個 Pod 則會被排程。一旦我們提交排程器部署組態並且我們的新排程器開始執行,annotation-second-scheduler Pod 也會被排程。

或者,您可以查看事件記錄中的「Scheduled」條目,以驗證 Pod 是否由所需的排程器進行排程。

kubectl get events

您也可以透過修改叢集主要排程器在相關控制平面節點上的靜態 Pod 清單,來使用自訂排程器組態或叢集的自訂容器映像。

上次修改時間:2023 年 12 月 14 日上午 9:24 PST:Update references to the config APIs (2fe79a7c28)