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 # тут є лише прикладом
Тепер, коли ви маєте ваш планувальник у контейнерному образі, створіть конфігурацію 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/v1
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.
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 до trueleaderElection.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ʼа без вказаного імені планувальника
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ʼів до кластера Kubernetes перед передачею конфігурації розгортання планувальника, ми побачимо, що Pod annotation-second-scheduler залишається в стані "Pending" назавжди, тоді як інші два Podʼи заплановані. Після надсилання конфігурації розгортання планувальника і запуску нашого нового планувальника, Pod annotation-second-scheduler також запланується.
Як альтернативу, ви можете переглянути записи "Scheduled" у лозі подій, щоб перевірити, що Podʼи були заплановані бажаними планувальниками.
kubectl get events
Ви також можете використовувати власну конфігурацію планувальника або власний контейнерний образ для основного планувальника кластера, змінивши його статичний маніфест Podʼа на відповідних вузлах панелі управління.