Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.
Керування кластером
1 - Запуск автономного Kublet
Цей посібник показує, як запустити автономний екземпляр kubelet.
У вас можуть бути різні причини для запуску автономного kubelet. Цей посібник спрямований на ознайомлення вас з Kubernetes, навіть якщо у вас немає багато досвіду роботи з ним. Ви можете слідувати цьому посібнику і дізнатися про налаштування вузла, основних (статичних) Podʼів та як Kubernetes керує контейнерами.
Після того, як ви пройдете цей посібник, ви можете спробувати використовувати кластер, який має панель управління для керування podʼами та вузлами, а також іншими типами обʼєктів. Ознайомтесь з прикладом в розділі Привіт, minikube.
Ви також можете запустити kubelet в автономному режимі для задоволення операційних потреб, таких як запуск панелі управління для високо доступного, стійкого до збоїв кластера. Цей посібник не охоплює деталі, необхідні для запуску високодоступної панелі управління.
Цілі
- Встановлення
cri-oтаkubeletв системах Linux та їх запуск як службsystemd. - Запуск Podʼа для
nginxщо очікує запитів на порту TCP 80 за IP адресою Podʼа. - Дізнатись, як різні компоненти взаємодіють один з одним.
Увага:
Конфігурація kubelet, яка використовується у цьому посібнику, є небезпечною за своєю конструкцією і не повинна не повинна використовуватися в промисловому середовищі.Перш ніж ви розпочнете
- Адміністраторський (
root) доступ до системи Linux, яка використовуєsystemdтаiptables(абоnftablesз емуляцієюiptables). - Доступ до Інтернету для завантаження компонентів, необхідних для роботи з підручником, зокрема
- Середовище виконання контейнерів що підтримує Kubernetes (CRI).
- Мережеві втулки (їх часто називають Container Networking Interface (CNI))
- Необхідні інструменти CLI:
curl,tar,jq.
Підготовка системи
Конфігурація підкачки
Стандартно kubelet не запускається, якщо на вузлі виявлено використання файлу підкачки (swap). Це означає, що підкачку необхідно або вимкнути, або налаштувати толерантність до неї у kubelet.
Примітка:
Якщо налаштувати kubelet на толерантність до підкачки, kubelet все одно конфігурує Podʼи (та контейнери в цих Podʼах) таким чином, щоб вони не використовували область підкачки. Дізнатися, як Podʼи можуть фактично використовувати доступну підкачку, можна в розділі управління памʼяттю підкачки на Linux-вузлах.Якщо у вас увімкнена підкачка, вимкніть її або додайте параметр failSwapOn: false у файл конфігурації kubelet.
Щоб перевірити, чи увімкнена підкачка:
sudo swapon --show
Якщо команда не виводить жодної інформації, то підкачка вже вимкнена.
Щоб тимчасово вимкнути підкачку:
sudo swapoff -a
Щоб зробити це налаштування постійним після перезавантаження:
Переконайтеся, що підкачка вимкнена в файлі /etc/fstab або у файлі systemd.swap, залежно від того, як вона була налаштована на вашій системі.
Увімкнення пересилання пакетів IPv4
Щоб перевірити, чи увімкнено пересилання пакетів IPv4:
cat /proc/sys/net/ipv4/ip_forward
Якщо результатом є 1, пересилання вже увімкнено. Якщо результатом є 0, виконайте наступні кроки.
Щоб увімкнути пересилання пакетів IPv4, створіть конфігураційний файл, який встановлює параметр net.ipv4.ip_forward у значення 1:
sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
EOF
Застосуйте зміни до системи:
sudo sysctl --system
Результат буде подібним до цього:
...
* Applying /etc/sysctl.d/k8s.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
Завантаження, встановлення та налаштування компонентів
Встановлення середовища виконання контейнерів
Завантажте найновіші доступні версії необхідних пакетів (рекомендовано).
Цей підручник пропонує встановити середовище виконання контейнерів CRI-O (зовнішнє посилання).
Існує кілька способів встановлення середовища виконання CRI-O, залежно від вашого дистрибутиву Linux. Хоча CRI-O рекомендує використовувати пакети deb або rpm, у цьому підручнику використовується скрипт статичного бінарного пакета проєкту CRI-O Packaging, щоб спростити процес і зробити його незалежним від дистрибутиву.
Скрипт встановлює та налаштовує додаткове необхідне програмне забезпечення, таке як cni-plugins для контейнерної мережі та crun і runc для запуску контейнерів.
Скрипт автоматично визначить архітектуру процесора вашої системи (amd64 або arm64), а також обере та встановить найновіші версії програмних пакетів.
Налаштування CRI-O
Відвідайте сторінку випусків (зовнішнє посилання).
Завантажте скрипт статичного бінарного пакета:
curl https://raw.githubusercontent.com/cri-o/packaging/main/get > crio-install
Запустіть інсталяційний скрипт:
sudo bash crio-install
Увімкніть і запустіть службу crio:
sudo systemctl daemon-reload
sudo systemctl enable --now crio.service
Швидка перевірка:
sudo systemctl is-active crio.service
Результат подібний до:
active
Детальна перевірка служби:
sudo journalctl -f -u crio.service
Встановлення мережевих втулків
Інсталятор cri-o встановлює та налаштовує пакет cni-plugins. Ви можете перевірити встановлення, виконавши таку команду:
/opt/cni/bin/bridge --version
Результат буде подібний до:
CNI bridge plugin v1.5.1
CNI protocol versions supported: 0.1.0, 0.2.0, 0.3.0, 0.3.1, 0.4.0, 1.0.0
Щоб перевірити стандартну конфігурацію:
cat /etc/cni/net.d/11-crio-ipv4-bridge.conflist
Результат буде подібний до:
{
"cniVersion": "1.0.0",
"name": "crio",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"ranges": [
[{ "subnet": "10.85.0.0/16" }]
]
}
}
]
}
Примітка:
Переконайтеся, що стандартний діапазонsubnet (10.85.0.0/16) не перетинається з будь-якою з ваших активних мереж. Якщо є перетин, ви можете відредагувати файл і змінити його відповідно. Після зміни перезапустіть службу.Завантаження та встановлення
Завантажте останній стабільний випуск kubelet.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubelet"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubelet"
Налаштування:
sudo mkdir -p /etc/kubernetes/manifests
sudo tee /etc/kubernetes/kubelet.yaml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
webhook:
enabled: false # НЕ використовуйте у промислових кластерах!
authorization:
mode: AlwaysAllow # НЕ використовуйте у промислових кластерах!
enableServer: false
logging:
format: text
address: 127.0.0.1 # Restrict access to localhost
readOnlyPort: 10255 # НЕ використовуйте у промислових кластерах!
staticPodPath: /etc/kubernetes/manifests
containerRuntimeEndpoint: unix:///var/run/crio/crio.sock
EOF
Примітка:
Оскільки ви не встановлюєте промисловий кластер, у вас використовується звичайний HTTP порт (readOnlyPort: 10255) для неавтентифікованих запитів до API kubelet.
У цьому посібнику вебхук автентифікації вимкнено, а режим авторизації встановлено на AlwaysAllow. Ви можете дізнатися більше про режими авторизації та вебхук автентифікації, щоб правильно налаштувати kubelet в автономному режимі для вашого середовища.
Перегляньте розділ Порти та протоколи, щоб зрозуміти, які порти використовують компоненти Kubernetes.
Встановлення:
chmod +x kubelet
sudo cp kubelet /usr/bin/
Створіть файл служби systemd:
sudo tee /etc/systemd/system/kubelet.service <<EOF
[Unit]
Description=Kubelet
[Service]
ExecStart=/usr/bin/kubelet \
--config=/etc/kubernetes/kubelet.yaml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
Аргумент командного рядка --kubeconfig було навмисно пропущено у файлі конфігурації конфігураційного файлу служби. Цей аргумент задає шлях до файлу kubeconfig файл, який визначає, як підключатися до сервера API, вмикаючи режим сервера API. Якщо його не вказати, увімкнеться автономний режим.
Увімкніть та запустіть службу kubelet:
sudo systemctl daemon-reload
sudo systemctl enable --now kubelet.service
Швидкий тест:
sudo systemctl is-active kubelet.service
Вивід має бути подібним до:
active
Докладна перевірка служби:
sudo journalctl -u kubelet.service
Перевірте точку доступу API kubelet /healthz:
curl http://localhost:10255/healthz?verbose
Вивід має бути подібним до:
[+]ping ok
[+]log ok
[+]syncloop ok
healthz check passed
Запит до точки доступу до API kubelet /pods:
curl http://localhost:10255/pods | jq '.'
Вивід має бути подібним до:
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {},
"items": null
}
Запуск Podʼів в kubelet
В автономному режимі ви можете запускати Podʼи за допомогою маніфестів Pod'ів. Маніфести можуть або знаходитися у локальній файловій системі, або бути отриманими по HTTP з джерела конфігурації.
Створіть маніфест для Pod:
cat <<EOF > static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
Скопіюйте файл маніфесту static-web.yaml до теки /etc/kubernetes/manifests.
sudo cp static-web.yaml /etc/kubernetes/manifests/
Дізнатись відомості про kubelet та Pod
Мережевий втулок Podʼа створює мережевий міст (cni0) і пару інтерфейсів veth для кожного Podʼа (один з пари знаходиться всередині новоствореного Podʼа, а інший — на рівні хосту).
Зверніться до точки доступу до API kubelet за адресою http://localhost:10255/pods:
curl http://localhost:10255/pods | jq '.'
Отримання IP-адреси static-web Podʼа:
curl http://localhost:10255/pods | jq '.items[].status.podIP'
Вивід має бути подібним до:
"10.85.0.4"
Приєднайтеся до сервера nginx за адресою http://<IP>:<Порт> (стандартний порт 80), в цьому випадку:
curl http://10.85.0.4
Вивід має бути подібним до:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Де шукати більш детальну інформацію
Якщо вам потрібно діагностувати проблему, пов'язану з роботою цього посібника, ви можете зазирнути в наступні теки для моніторингу та усунення несправностей:
/var/lib/cni
/var/lib/containers
/var/lib/kubelet
/var/log/containers
/var/log/pods
Очищення
kubelet
sudo systemctl disable --now kubelet.service
sudo systemctl daemon-reload
sudo rm /etc/systemd/system/kubelet.service
sudo rm /usr/bin/kubelet
sudo rm -rf /etc/kubernetes
sudo rm -rf /var/lib/kubelet
sudo rm -rf /var/log/containers
sudo rm -rf /var/log/pods
Середовище виконання контейнерів
sudo systemctl disable --now crio.service
sudo systemctl daemon-reload
sudo rm -rf /usr/local/bin
sudo rm -rf /usr/local/lib
sudo rm -rf /usr/local/share
sudo rm -rf /usr/libexec/crio
sudo rm -rf /etc/crio
sudo rm -rf /etc/containers
Мережеві втулки
sudo rm -rf /opt/cni
sudo rm -rf /etc/cni
sudo rm -rf /var/lib/cni
Висновок
На цій сторінці було розглянуто основні аспекти розгортання kubelet в автономному режимі. Тепер ви готові розгортати Podʼи та тестувати додаткову функціональність.
Зверніть увагу, що в автономному режимі kubelet не підтримує отримання конфігурацій Podʼів із панелі управління (оскільки немає підключення до панелі управління).
Також ви не можете використовувати ConfigMap або Secret для налаштування контейнерів у статичному Pod.
Що далі
- Ознайомтесь з Hello, minikube, щоб дізнатися, як запускати Kubernetes з панеллю управління. Інструмент minikube допоможе вам налаштувати тренувальний кластер на вашому компʼютері.
- Дізнайтесь більше про Мережеві втулки
- Дізнайтесь більше про Середовища виконання контейнерів
- Дізнайтесь більше про kubelet
- Дізнайтесь більше про статичні Podʼи
2 - Налаштування свопу на вузлах Kubernetes
Ця сторінка містить приклад того, як створити та налаштувати своп на вузлі Kubernetes за допомогою kubeadm.
- Створити своп на вузлі Kubernetes за допомогою kubeadm.
- Навчитися налаштовувати як зашифрований, так і незашифрований своп.
- Навчитися вмикати своп при завантаженні системи.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж 1.33.Для перевірки версії введіть kubectl version.
Вам потрібен принаймні один робочий вузол у кластері, який має працювати під керуванням операційної системи Linux. Для цього прикладу необхідно встановити інструмент kubeadm, дотримуючись кроків, описаних у інструкції з встановлення kubeadm.
На кожному робочому вузлі, де ви будете налаштовувати своп, потрібні такі утиліти:
fallocatemkswapswapon
Для зашифрованого свопу (рекомендовано) також потрібен:
cryptsetup
Встановлення кластера з підтримкою свопу через kubeadm
Створення своп-файлу та активація свопу
Якщо своп не увімкнено, потрібно створити своп на вузлі. У наступних розділах показано, як створити 4ГіБ своп як у зашифрованому, так і незашифрованому варіанті.
Зашифрований своп-файл можна налаштувати так. Зверніть увагу, що цей приклад використовує утиліту cryptsetup (доступна у більшості дистрибутивів Linux).
# Виділення місця та обмеження доступу
fallocate --length 4GiB /swapfile
chmod 600 /swapfile
# Створення зашифрованого пристрою на основі виділеного місця
cryptsetup --type plain --cipher aes-xts-plain64 --key-size 256 -d /dev/urandom open /swapfile cryptswap
# Форматування swap-простору
mkswap /dev/mapper/cryptswap
# Активація swap для підкачки
swapon /dev/mapper/cryptswap
Незашифрований swap-файл можна налаштувати так.
# Виділення місця та обмеження доступу
fallocate --length 4GiB /swapfile
chmod 600 /swapfile
# Форматування swap-простору
mkswap /swapfile
# Активація swap для підкачки
swapon /swapfile
Перевірка, що своп увімкнено
Перевірити, чи своп увімкнено, можна за допомогою команд swapon -s або free.
Приклад swapon -s:
Filename Type Size Used Priority
/dev/dm-0 partition 4194300 0 -2
Приклад free -h:
total used free shared buff/cache available
Mem: 3.8Gi 1.3Gi 249Mi 25Mi 2.5Gi 2.5Gi
Swap: 4.0Gi 0B 4.0Gi
Увімкнення swap при завантаженні
Після налаштування swap, щоб він запускався при завантаженні, зазвичай або створюють systemd-юнит для активації (зашифрованого) swap, або додають рядок типу /swapfile swap swap defaults 0 0 у /etc/fstab.
Використання systemd для активації swap дозволяє затримати запуск kubelet до моменту, коли swap буде доступний, якщо це потрібно. Аналогічно, systemd дозволяє залишати swap активним до завершення роботи kubelet (і, зазвичай, вашого контейнерного рантайму).
Налаштування kubelet
Після активації своп на вузлі потрібно налаштувати kubelet для його використання. Вам потрібно вибрати поведінку свопу для цього вузла. Для цього посібника ви налаштуєте поведінку LimitedSwap.
Знайдіть і відредагуйте файл конфігурації kubelet, а також:
- встановіть
failSwapOnна false - встановіть
memorySwap.swapBehaviorна LimitedSwap
# цей фрагмент додається у конфігураційний файл kubelet
failSwapOn: false
memorySwap:
swapBehavior: LimitedSwap
Щоб ці налаштування набули чинності, потрібно перезапустити kubelet. Зазвичай це робиться за допомогою команди:
systemctl restart kubelet.service
Ви повинні переконатися, що kubelet тепер працює нормально і що ви можете запускати Podʼи, які використовують своп-памʼять за потреби.
3 - Встановлення драйверів та виділення пристроїв з DRA
Kubernetes v1.35 [stable](стандартно увімкнено)Цей посібник показує, як встановити драйвери Динамічного виділення ресурсів (DRA) у вашому кластері та як використовувати їх разом з API DRA для виділення пристроїв для Pod. Ця сторінка призначена для адміністраторів кластерів.
Динамічне виділення ресурсів (DRA) дозволяє кластеру керувати доступністю та виділенням апаратних ресурсів для задоволення вимог Podʼів до апаратних ресурсів та налаштувань. Щоб підтримати це, суміш вбудованих компонентів Kubernetes (таких як планувальник Kubernetes, kubelet і kube-controller-manager) та сторонніх драйверів від власників пристроїв (які називаються драйверами DRA) спільно відповідають за оголошення, виділення, підготовку, монтування, перевірку стану, скасування підготовки та очищення ресурсів протягом усього життєвого циклу Podʼа. Ці компоненти обмінюються інформацією через серію специфічних для DRA API в групі API resource.k8s.io, включаючи DeviceClasses, ResourceSlices, ResourceClaims, а також нові поля в самій специфікації Pod.
Цілі
- Розгорнути приклад драйвера DRA
- Розгорнути Pod, що виконує заявку на апаратні ресурси за допомогою API DRA
- Видалити Pod, який має заявку
Перш ніж ви розпочнете
Ваш кластер повинен підтримувати RBAC. Ви можете спробувати цей посібник з кластером, який використовує механізм авторизації, відмінний від RBAC, але в цьому випадку вам доведеться адаптувати кроки щодо визначення ролей і дозволів.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Цей посібник був протестований з вузлами Linux, хоча він також може працювати з іншими типами вузлів.
Версія вашого Kubernetes сервера має бути не старішою ніж v1.34.Для перевірки версії введіть kubectl version.
Якщо ваш кластер наразі не працює під управлінням Kubernetes 1.35, перегляньте документацію щодо версії Kubernetes, яку ви плануєте використовувати.
Дослідження початкового стану кластера
Ви можете витратити деякий час, щоб спостерігати за початковим станом кластера з увімкненим DRA, особливо якщо ви не використовували ці API раніше. Якщо ви налаштували новий кластер для цього посібника, без встановленого драйвера та ще не задоволених заявок Pod, вивід цих команд не покаже жодних ресурсів.
Отримайте список DeviceClasses:
kubectl get deviceclassesВивід буде схожий на цей:
No resources foundОтримайте список ResourceSlices:
kubectl get resourceslicesВивід буде схожий на цей:
No resources foundОтримайте список ResourceClaims та ResourceClaimTemplates
kubectl get resourceclaims -A kubectl get resourceclaimtemplates -AВивід буде схожий на цей:
No resources found No resources found
На даний момент ви підтвердили, що DRA увімкнено та налаштовано правильно в кластері, і що жоден драйвер DRA ще не оголосив жодних ресурсів API DRA.
Встановлення демонстраційного драйвера DRA
Драйвери DRA — це сторонні програми, які працюють на кожному вузлі вашого кластера, щоб взаємодіяти з апаратним забезпеченням цього вузла та вбудованими компонентами DRA Kubernetes. Процедура встановлення залежить від вибраного вами драйвера, але, ймовірно, розгортається як DaemonSet на всіх або вибраних вузлах (з використанням selectors або подібних механізмів) у вашому кластері.
Перевірте документацію вашого драйвера на наявність конкретних інструкцій щодо встановлення, які можуть включати чарт Helm, набір маніфестів або інші інструменти розгортання.
Цей посібник використовує приклад драйвера, який можна знайти в репозиторії kubernetes-sigs/dra-example-driver, щоб продемонструвати встановлення драйвера. Цей приклад драйвера оголошує симульовані GPU для Kubernetes, з якими можуть взаємодіяти ваші Podʼи.
Підготовка кластера до встановлення драйвера
Щоб спростити очищення, створіть простір імен з назвою dra-tutorial:
Створіть простір імен:
kubectl create namespace dra-tutorial
У промисловому середовищі ви, напевно, використовували б раніше випущений або кваліфікований образ від постачальника драйвера або вашої організації, і ваші вузли повинні мати доступ до реєстру образів, де зберігається образ драйвера. У цьому навчальному посібнику ви будете використовувати публічно випущений образ dra-example-driver, щоб змоделювати доступ до образу драйвера DRA.
Підтвердіть, що ваші вузли мають доступ до образу, виконавши наступну команду зсередини одного з вузлів вашого кластера:
docker pull registry.k8s.io/dra-example-driver/dra-example-driver:v0.2.0
Розгортання компонентів драйвера DRA
Для цього навчального посібника ви встановите критично важливі компоненти демонстраційного драйвера ресурсів окремо за допомогою kubectl.
Створіть DeviceClass, що представляє типи пристроїв, які підтримує цей драйвер DRA:
apiVersion: resource.k8s.io/v1 kind: DeviceClass metadata: name: gpu.example.com spec: selectors: - cel: expression: "device.driver == 'gpu.example.com'"kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/deviceclass.yamlСтворіть службовий обліковий запис, кластерну роль і привʼязку кластерної ролі, які будуть використовуватися драйвером для отримання дозволів на взаємодію з Kubernetes API в цьому кластері:
Створіть Service Account:
apiVersion: v1 kind: ServiceAccount metadata: name: dra-example-driver-service-account namespace: dra-tutorial labels: app.kubernetes.io/name: dra-example-driver app.kubernetes.io/instance: dra-example-driverkubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/serviceaccount.yamlСтворіть ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: dra-example-driver-role rules: - apiGroups: ["resource.k8s.io"] resources: ["resourceclaims"] verbs: ["get"] - apiGroups: [""] resources: ["nodes"] verbs: ["get"] - apiGroups: ["resource.k8s.io"] resources: ["resourceslices"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/clusterrole.yamlСтворіть ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: dra-example-driver-role-binding subjects: - kind: ServiceAccount name: dra-example-driver-service-account namespace: dra-tutorial roleRef: kind: ClusterRole name: dra-example-driver-role apiGroup: rbac.authorization.k8s.iokubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/clusterrolebinding.yaml
Створіть PriorityClass для DRA драйвера. PriorityClass запобігає витісненню компонента драйвера DRA, який відповідає за важливі операції життєвого циклу для Podʼів з заявками. Дізнайтеся більше про пріоритет Podʼів та виселення тут.
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: dra-driver-high-priority value: 1000000 globalDefault: false description: "This priority class should be used for DRA driver pods only."kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/priorityclass.yamlРозгорніть фактичний драйвер DRA як DaemonSet, налаштований на запуск прикладу двійкового файлу драйвера з вищезазначеними дозволами.
apiVersion: apps/v1 kind: DaemonSet metadata: name: dra-example-driver-kubeletplugin namespace: dra-tutorial labels: app.kubernetes.io/name: dra-example-driver spec: selector: matchLabels: app.kubernetes.io/name: dra-example-driver updateStrategy: type: RollingUpdate template: metadata: labels: app.kubernetes.io/name: dra-example-driver spec: priorityClassName: dra-driver-high-priority serviceAccountName: dra-example-driver-service-account securityContext: {} containers: - name: plugin securityContext: privileged: true image: registry.k8s.io/dra-example-driver/dra-example-driver:v0.2.0 imagePullPolicy: IfNotPresent command: ["dra-example-kubeletplugin"] resources: {} # Драйвери для промислового використання повинні завжди надавати пробу життєздатності # Для цього прикладу ми просто пропускаємо її. # livenessProbe: # grpc: # port: 51515 # service: liveness # failureThreshold: 3 # periodSeconds: 10 env: - name: CDI_ROOT value: /var/run/cdi - name: KUBELET_REGISTRAR_DIRECTORY_PATH value: "/var/lib/kubelet/plugins_registry" - name: KUBELET_PLUGINS_DIRECTORY_PATH value: "/var/lib/kubelet/plugins" - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace # Кількість пристроїв, які демонстраційний драйвер буде імітувати. - name: NUM_DEVICES value: "9" - name: HEALTHCHECK_PORT value: "51515" volumeMounts: - name: plugins-registry mountPath: "/var/lib/kubelet/plugins_registry" - name: plugins mountPath: "/var/lib/kubelet/plugins" - name: cdi mountPath: /var/run/cdi volumes: - name: plugins-registry hostPath: path: "/var/lib/kubelet/plugins_registry" - name: plugins hostPath: path: "/var/lib/kubelet/plugins" - name: cdi hostPath: path: /var/run/cdikubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/daemonset.yamlDaemonSet налаштовано з точками монтування томів, необхідними для взаємодії з підлягаючим текою Container Device Interface (CDI), і для відкриття його сокета для
kubeletчерез текуkubelet/plugins.
Перевірка встановлення драйвера DRA
Отримайте список Podʼів DaemonSet драйвера DRA на всіх робочих вузлах:
kubectl get pod -l app.kubernetes.io/name=dra-example-driver -n dra-tutorialВивід буде схожий на цей:
NAME READY STATUS RESTARTS AGE dra-example-driver-kubeletplugin-4sk2x 1/1 Running 0 13s dra-example-driver-kubeletplugin-cttr2 1/1 Running 0 13sПочаткова відповідальність локального драйвера DRA кожного вузла полягає в оновленні відомостей кластера про те, які пристрої доступні для Podʼів на цьому вузлі, публікуючи його метадані в API ResourceSlices. Ви можете перевірити цей API, щоб побачити, що кожен вузол з драйвером оголошує клас пристрою, який він представляє.
Перевірте наявність доступних ResourceSlices:
kubectl get resourceslicesВивід буде схожий на цей:
NAME NODE DRIVER POOL AGE kind-worker-gpu.example.com-k69gd kind-worker gpu.example.com kind-worker 19s kind-worker2-gpu.example.com-qdgpn kind-worker2 gpu.example.com kind-worker2 19s
На даний момент ви успішно встановили приклад драйвера DRA та підтвердили його початкову конфігурацію. Тепер ви готові використовувати DRA для планування Podʼів.
Запит ресурсів та розгортання Podʼа
Щоб запитати ресурси за допомогою DRA, ви створюєте ResourceClaims або ResourceClaimTemplates, які визначають ресурси, які потрібні вашим Podʼам. У демонстраційному драйвері для симульованих пристроїв GPU доступний атрибут ємності памʼяті. Цей розділ показує, як використовувати Загальна мова виразів для зазначення ваших вимог у ResourceClaim, вибору цього ResourceClaim у специфікації Podʼа та спостереження за виділенням ресурсів.
Цей посібник демонструє лише один базовий приклад ResourceClaim DRA. Читайте Динамічне виділення ресурсів, щоб дізнатися більше про ResourceClaims.
Створення ResourceClaim
У цьому розділі ви створюєте ResourceClaim і посилаєтеся на нього в Pod. Яким би не був запит, поле deviceClassName є обовʼязковим, звужуючи обсяг запиту до конкретного класу пристрою. Сам запит може включати вираз Загальна мова виразів, який посилається на атрибути, які можуть бути оголошені драйвером, що керує цим класом пристроїв.
У цьому прикладі ви створите запит на будь-який GPU, що оголошує понад 10Gi ємності памʼяті. Атрибут, що експонує ємність від прикладного драйвера, має форму device.capacity['gpu.example.com'].memory. Зверніть увагу, що імʼя запиту встановлено на some-gpu.
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: some-gpu
namespace: dra-tutorial
spec:
devices:
requests:
- name: some-gpu
exactly:
deviceClassName: gpu.example.com
selectors:
- cel:
expression: "device.capacity['gpu.example.com'].memory.compareTo(quantity('10Gi')) >= 0"
kubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/example/resourceclaim.yaml
Створення Pod, який посилається на цей ResourceClaim
Нижче наведено маніфест Pod, що посилається на ResourceClaim, який ви щойно створили, some-gpu, у полі spec.resourceClaims.resourceClaimName. Локальне імʼя для цього запиту, gpu, потім використовується в полі spec.containers.resources.claims.name, щоб виділити запит для підлеглого контейнера Pod.
apiVersion: v1
kind: Pod
metadata:
name: pod0
namespace: dra-tutorial
labels:
app: pod
spec:
containers:
- name: ctr0
image: ubuntu:24.04
command: ["bash", "-c"]
args: ["export; trap 'exit 0' TERM; sleep 9999 & wait"]
resources:
claims:
- name: gpu
resourceClaims:
- name: gpu
resourceClaimName: some-gpukubectl apply --server-side -f http://k8s.io/examples/dra/driver-install/example/pod.yaml
Підтвердіть, що pod розгорнуто:
kubectl get pod pod0 -n dra-tutorialВивід буде схожий на цей:
NAME READY STATUS RESTARTS AGE pod0 1/1 Running 0 9s
Дослідження стану DRA
Після створення Podʼа кластер намагається запланювати цей Pod на вузол, де Kubernetes може задовольнити ResourceClaim. У цьому навчальному посібнику драйвер DRA розгорнуто на всіх вузлах і оголошено симульовані GPU на всіх вузлах, всі з яких мають достатню оголошену ємність для задоволення заявки Podʼа, тому Kubernetes може планувати цей Pod на будь-якому вузлі та може виділити будь-який з симульованих GPU на цьому вузлі.
Коли Kubernetes виділяє симульований GPU для Pod, демонстраційний драйвер додає змінні середовища в кожен контейнер, до якого він виділений, щоб вказати, які GPU мали б бути впроваджені в них реальним драйвером ресурсів і як вони мали б бути налаштовані, тому ви можете перевірити ці змінні середовища, щоб побачити, як Podʼи оброблялися системою.
Перевірте логи Pod, які повідомляють імʼя симульованого GPU, що був виділений:
kubectl logs pod0 -c ctr0 -n dra-tutorial | grep -E "GPU_DEVICE_[0-9]+=" | grep -v "RESOURCE_CLAIM"Вивід буде схожий на цей:
declare -x GPU_DEVICE_0="gpu-0"Перевірте стан обʼєкта ResourceClaim:
kubectl get resourceclaims -n dra-tutorialВивід буде схожий на цей:
NAME STATE AGE some-gpu allocated,reserved 34sУ цьому виводі стовпець
STATEпоказує, що ResourceClaim виділено та зарезервовано.Перевірте деталі ResourceClaim
some-gpu. Виразstatusв ResourceClaim містить інформацію про виділений пристрій і Pod, для якого він був зарезервований:kubectl get resourceclaim some-gpu -n dra-tutorial -o yamlВивід буде схожий на цей:
1apiVersion: resource.k8s.io/v1 2kind: ResourceClaim 3metadata: 4 creationTimestamp: "2025-08-20T18:17:31Z" 5 finalizers: 6 - resource.kubernetes.io/delete-protection 7 name: some-gpu 8 namespace: dra-tutorial 9 resourceVersion: "2326" 10 uid: d3e48dbf-40da-47c3-a7b9-f7d54d1051c3 11spec: 12 devices: 13 requests: 14 - exactly: 15 allocationMode: ExactCount 16 count: 1 17 deviceClassName: gpu.example.com 18 selectors: 19 - cel: 20 expression: device.capacity['gpu.example.com'].memory.compareTo(quantity('10Gi')) 21 >= 0 22 name: some-gpu 23status: 24 allocation: 25 devices: 26 results: 27 - device: gpu-0 28 driver: gpu.example.com 29 pool: kind-worker 30 request: some-gpu 31 nodeSelector: 32 nodeSelectorTerms: 33 - matchFields: 34 - key: metadata.name 35 operator: In 36 values: 37 - kind-worker 38 reservedFor: 39 - name: pod0 40 resource: pods 41 uid: c4dadf20-392a-474d-a47b-ab82080c8bd7Щоб перевірити, як драйвер обробив виділення пристрою, отримайте журнали для Podʼів DaemonSet драйвера:
kubectl logs -l app.kubernetes.io/name=dra-example-driver -n dra-tutorialВивід буде схожий на цей:
I0729 05:11:52.679057 1 driver.go:84] NodePrepareResource is called: number of claims: 1 I0729 05:11:52.684450 1 driver.go:112] Returning newly prepared devices for claim '79e1e8d8-7e53-4362-aad1-eca97678339e': [&Device{RequestNames:[some-gpu],PoolName:kind-worker,DeviceName:gpu-4,CDIDeviceIDs:[k8s.gpu.example.com/gpu=common k8s.gpu.example.com/gpu=79e1e8d8-7e53-4362-aad1-eca97678339e-gpu-4],}]
Тепер ви успішно розгорнули Pod, який запитує пристрої за допомогою DRA, перевірили, що Pod було заплановано на відповідний вузол, і побачили, що повʼязані види API DRA були оновлені зі статусом виділення.
Видалення Podʼа, що має заявку
Коли Pod з заявкою видаляється, драйвер DRA деалокує ресурс, щоб він був доступний для майбутнього планування. Щоб перевірити цю поведінку, видаліть Pod, який ви створили на попередніх кроках, і спостерігайте за відповідними змінами в ResourceClaim та драйвері.
Видаліть Pod
pod0:kubectl delete pod pod0 -n dra-tutorialВивід буде схожий на цей:
pod "pod0" deleted
Спостереження за станом DRA
Коли Pod видаляється, драйвер деалокує пристрій з ResourceClaim і оновлює ресурс ResourceClaim в API Kubernetes. ResourceClaim має стан pending, поки він не буде згаданий у новому Pod.
Перевірте стан ResourceClaim
some-gpu:kubectl get resourceclaims -n dra-tutorialВивід буде схожий на цей:
NAME STATE AGE some-gpu pending 76sПеревірте, що драйвер обробив скасування підготовки пристрою для цього запиту, перевіривши журнали драйвера:
kubectl logs -l app.kubernetes.io/name=dra-example-driver -n dra-tutorialВивід буде схожий на цей:
I0820 18:22:15.629376 1 driver.go:138] UnprepareResourceClaims is called: number of claims: 1
Тепер ви видалили Pod, який мав заявку, і спостерігали, що драйвер вживав заходів для скасування підготовки підлягаючого апаратного ресурсу та оновлення API DRA, щоб відобразити, що ресурс знову доступний для майбутнього планування.
Очищення
Щоб очистити ресурси, які ви створили в цьому навчальному посібнику, виконайте ці кроки:
kubectl delete namespace dra-tutorial
kubectl delete deviceclass gpu.example.com
kubectl delete clusterrole dra-example-driver-role
kubectl delete clusterrolebinding dra-example-driver-role-binding
kubectl delete priorityclass dra-driver-high-priority
Що далі
4 - Посібник з роботи з просторами імен
Kubernetes namespaces допомагають різним проєктам, командам або клієнтам спільно використовувати кластер Kubernetes.
Вони це роблять, надаючи наступне:
- Область для Імен.
- Механізм для прикріплення авторизації та політики до підрозділу кластера.
Використання кількох просторів імен є необовʼязковим.
У цьому прикладі показано, як використовувати простори імен Kubernetes для розділення вашого кластера.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
Передумови
У цьому прикладі передбачається наступне:
- У вас є кластер Kubernetes.
- Ви маєте базове розуміння що таке Pod, Service та Deployment в Kubernetes.
Стандартний простір імен
Типово кластер Kubernetes створює стандартний простір імен default під час створення кластера для утримання стандартного набору Podʼів, Serviceʼів та Deploymentʼів, що використовуються кластером.
Якщо у вас є свіжий кластер, ви можете перевірити доступні простори імен, виконавши наступне:
kubectl get namespaces
NAME STATUS AGE
default Active 13m
Створення нових просторів імен
Для цієї вправи ми створимо два додаткові простори імен Kubernetes для зберігання нашого контенту.
Уявімо собі сценарій, де організація використовує спільний кластер Kubernetes для розробки та операційної експлуатації.
Команда розробки хоче мати простір в кластері, де вони можуть переглядати список Podʼів, Serviceʼів та Deploymentʼів, які вони використовують для створення та запуску свого застосунку. У цьому просторі ресурси Kubernetes приходять і йдуть, і обмеження на те, хто може або не може змінювати ресурси, не є жорсткими, щоб забезпечити гнучкість розробки.
Операційна команда хоче мати простір в кластері, де вони можуть дотримуватися строгих процедур щодо того, хто може або не може маніпулювати набором Podʼів, Serviceʼів та Deploymentʼів, які підтримують операційну роботу.
Одним із шаблонів, який ця організація може використовувати, є розбиття кластера Kubernetes на два простори імен: development та production.
Створімо два нових простори імен для зберігання нашої роботи.
Використовуйте файл namespace-dev.yaml, який описує простір імен development:
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: development
Створіть простір імен development за допомогою kubectl.
kubectl create -f https://k8s.io/examples/admin/namespace-dev.yaml
Збережіть наступний вміст у файл namespace-prod.yaml, який описує простір імен production:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: production
А потім створімо простір імен production за допомогою kubectl.
kubectl create -f https://k8s.io/examples/admin/namespace-prod.yaml
Щоб бути впевненими, що все правильно, перелічімо всі простори імен у нашому кластері.
kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 32m <none>
development Active 29s name=development
production Active 23s name=production
Створення Podʼів у кожному просторі імен
Простір імен Kubernetes надає область для Podʼів, Service та Deployment у кластері.
Користувачі, які взаємодіють з одним простором імен, не бачать вмісту в іншому просторі імен.
Щоб продемонструвати це, запустімо простий Deployment та Podʼи у просторі імен development.
Спочатку перевіримо поточний контекст:
kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: REDACTED
server: https://130.211.122.180
name: lithe-cocoa-92103_kubernetes
contexts:
- context:
cluster: lithe-cocoa-92103_kubernetes
user: lithe-cocoa-92103_kubernetes
name: lithe-cocoa-92103_kubernetes
current-context: lithe-cocoa-92103_kubernetes
kind: Config
preferences: {}
users:
- name: lithe-cocoa-92103_kubernetes
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
- name: lithe-cocoa-92103_kubernetes-basic-auth
user:
password: h5M0FtUUIflBSdI7
username: admin
kubectl config current-context
lithe-cocoa-92103_kubernetes
Наступний крок — визначення контексту для клієнта kubectl для роботи в кожному просторі імен. Значення полів "cluster" та "user" копіюються з поточного контексту.
kubectl config set-context dev --namespace=development \
--cluster=lithe-cocoa-92103_kubernetes \
--user=lithe-cocoa-92103_kubernetes
kubectl config set-context prod --namespace=production \
--cluster=lithe-cocoa-92103_kubernetes \
--user=lithe-cocoa-92103_kubernetes
Типово, ці команди додають два контексти, які зберігаються у файлі .kube/config. Тепер ви можете переглянути контексти та перемикатися між двома новими контекстами запитів, залежно від того, з яким простором імен ви хочете працювати.
Щоб переглянути нові контексти:
kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: REDACTED
server: https://130.211.122.180
name: lithe-cocoa-92103_kubernetes
contexts:
- context:
cluster: lithe-cocoa-92103_kubernetes
user: lithe-cocoa-92103_kubernetes
name: lithe-cocoa-92103_kubernetes
- context:
cluster: lithe-cocoa-92103_kubernetes
namespace: development
user: lithe-cocoa-92103_kubernetes
name: dev
- context:
cluster: lithe-cocoa-92103_kubernetes
namespace: production
user: lithe-cocoa-92103_kubernetes
name: prod
current-context: lithe-cocoa-92103_kubernetes
kind: Config
preferences: {}
users:
- name: lithe-cocoa-92103_kubernetes
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
- name: lithe-cocoa-92103_kubernetes-basic-auth
user:
password: h5M0FtUUIflBSdI7
username: admin
Перемкнімся, щоб працювати у просторі імен development.
kubectl config use-context dev
Ви можете перевірити поточний контекст за допомогою наступного:
kubectl config current-context
dev
На цьому етапі всі запити, які ми робимо до кластера Kubernetes з командного рядка, зосереджені на просторі імен development.
Створімо деякий вміст.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: snowflake
name: snowflake
spec:
replicas: 2
selector:
matchLabels:
app: snowflake
template:
metadata:
labels:
app: snowflake
spec:
containers:
- image: registry.k8s.io/serve_hostname
imagePullPolicy: Always
name: snowflake
Застосуйте маніфест для створення Deployment
kubectl apply -f https://k8s.io/examples/admin/snowflake-deployment.yaml
Ми створили розгортання, кількість реплік якого становить 2, що запускає Pod під назвою snowflake з базовим контейнером, який обслуговує імʼя хосту.
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
snowflake 2/2 2 2 2m
kubectl get pods -l app=snowflake
NAME READY STATUS RESTARTS AGE
snowflake-3968820950-9dgr8 1/1 Running 0 2m
snowflake-3968820950-vgc4n 1/1 Running 0 2m
І це чудово, розробники можуть робити все, що вони хочуть, і їм не потрібно хвилюватися про вплив на вміст у просторі імен production.
Тепер перейдемо до простору імен production та покажемо, як ресурси в одному просторі імен приховані від іншого.
kubectl config use-context prod
Простір імен production повинен бути порожнім, і наступні команди не повернуть нічого.
kubectl get deployment
kubectl get pods
Операційна діяльність вимагає догляду за худобою, тому створімо кілька Podʼів для худоби.
kubectl create deployment cattle --image=registry.k8s.io/serve_hostname --replicas=5
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
cattle 5/5 5 5 10s
kubectl get pods -l app=cattle
NAME READY STATUS RESTARTS AGE
cattle-2263376956-41xy6 1/1 Running 0 34s
cattle-2263376956-kw466 1/1 Running 0 34s
cattle-2263376956-n4v97 1/1 Running 0 34s
cattle-2263376956-p5p3i 1/1 Running 0 34s
cattle-2263376956-sxpth 1/1 Running 0 34s
На цьому етапі повинно бути зрозуміло, що ресурси, які користувачі створюють в одному просторі імен, приховані від іншого простору імен.
З розвитком підтримки політики в Kubernetes ми розширимо цей сценарій, щоб показати, як можна надавати різні правила авторизації для кожного простору імен.