Налаштування кількох планувальників

Kubernetes постачається зі стандартним планувальником. Якщо стандартний планувальник не підходить для ваших потреб, ви можете реалізувати власний. До того, ви можете одночасно запускати кілька планувальників поряд зі стандартним планувальником і вказувати Kubernetes, який планувальник використовувати для кожного з ваших Podʼів. Тепер навчимося запускати кілька планувальників в Kubernetes на прикладі.

Детальний опис того, як реалізувати планувальник, виходить за рамки цього документа. Будь ласка, зверніться до реалізації kube-scheduler в pkg/scheduler в теці вихідних кодів Kubernetes для канонічного прикладу.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Для перевірки версії введіть kubectl version.

Упакування планувальника

Упакуйте ваш планувальник у контейнерний образ. Для цілей цього прикладу ви можете використовувати стандартний планувальник (kube-scheduler) як ваш другий планувальник. Клонуйте вихідний код Kubernetes з GitHub і зберіть планувальник з сирців.

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 .     # Назва образу та репозиторію
gcloud docker -- push gcr.io/my-gcp-project/my-kube-scheduler:1.0 # тут є лише прикладом

Визначення розгортання Kubernetes для планувальника

Тепер, коли ви маєте ваш планувальник у контейнерному образі, створіть конфігурацію Podʼа для нього і запустіть його у вашому кластері Kubernetes. Але замість того, щоб створювати Pod безпосередньо в кластері, ви можете використовувати Deployment для цього прикладу. Deployment керує 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 для налаштування поведінки вашої реалізації планувальника. Ця конфігурація була передана kube-scheduler під час ініціалізації за допомогою параметра --config. Конфігураційний файл зберігається у ConfigMap my-scheduler-config. Pod Deployment my-scheduler монтує ConfigMap my-scheduler-config як том.

У вищезгаданій конфігурації планувальника ваша реалізація планувальника представлена за допомогою KubeSchedulerProfile.

Також зверніть увагу, що ви створюєте окремий службовий обліковий запис my-scheduler і привʼязуєте до нього кластерну роль system:kube-scheduler, щоб він міг отримати ті ж привілеї, що й kube-scheduler.

Будь ласка, зверніться до документації kube-scheduler для детального опису інших параметрів командного рядка та довідкової інформації щодо конфігурації планувальника для детального опису інших налаштовуваних конфігурацій kube-scheduler.

Запуск другого планувальника в кластері

Щоб запустити ваш планувальник у кластері Kubernetes, створіть Deployment вказаний у конфігурації вище у кластері 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
...

У цьому списку ви повинні побачити Pod "Running" my-scheduler, на додачу до стандартного планувальника kube-scheduler.

Увімкнення обрання лідера

Щоб запустити кілька планувальників з увімкненим обранням лідера, ви повинні зробити наступне:

Оновіть наступні поля для KubeSchedulerConfiguration у ConfigMap my-scheduler-config у вашому YAML файлі:

  • leaderElection.leaderElect до true
  • leaderElection.resourceNamespace до <lock-object-namespace>
  • leaderElection.resourceName до <lock-object-name>

Якщо у вашому кластері увімкнено RBAC, ви повинні оновити кластерну роль system:kube-scheduler. Додайте імʼя вашого планувальника до імен ресурсів у правилі, яке застосовується до ресурсів endpoints та leases, як у наступному прикладі:

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
    
  • Специфікація Podʼа з default-scheduler

    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
    
  • Специфікація Podʼа з my-scheduler

    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 повинно відповідати імені, яке було надано планувальнику в полі schedulerName профілю KubeSchedulerProfile.

    Збережіть цей файл як pod3.yaml і надішліть його до кластера Kubernetes.

    kubectl create -f pod3.yaml
    

    Переконайтеся, що всі три Podʼи працюють.

    kubectl get pods
    

Перевірка, що Podʼи були заплановані за допомогою бажаних планувальників

Для спрощення роботи з цими прикладами ми не перевірили, що Podʼи дійсно були заплановані за допомогою бажаних планувальників. Ми можемо перевірити це, змінивши порядок подання конфігурацій Podʼів і розгортання вище. Якщо ми передамо всі конфігурації Podʼів до кластера Kubernetes перед передачею конфігурації розгортання планувальника, ми побачимо, що Pod annotation-second-scheduler залишається в стані "Pending" назавжди, тоді як інші два Podʼи заплановані. Після надсилання конфігурації розгортання планувальника і запуску нашого нового планувальника, Pod annotation-second-scheduler також запланується.

Як альтернативу, ви можете переглянути записи "Scheduled" у лозі подій, щоб перевірити, що Podʼи були заплановані бажаними планувальниками.

kubectl get events

Ви також можете використовувати власну конфігурацію планувальника або власний контейнерний образ для основного планувальника кластера, змінивши його статичний маніфест Podʼа на відповідних вузлах панелі управління.

Змінено August 27, 2024 at 9:57 PM PST: Removing the reviewers section from the front matter (81a711722d)