Налаштування кількох планувальників
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.
Примітка:
Щоб визначити, чи відповідає планувальник за планування конкретного Podʼа, полеspec.schedulerName
в PodTemplate або Pod маніфесті повинно збігатися з полем schedulerName
профілю 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>
Примітка:
Панель управління створює обʼєкти блокування для вас, але простір імен вже повинен існувати. Ви можете використовувати простір іменkube-system
.Якщо у вашому кластері увімкнено 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ʼа на відповідних вузлах панелі управління.