Модуль 2.3: DaemonSets та StatefulSets
Складність:
[MEDIUM]— Спеціалізовані шаблони навантаженьЧас на проходження: 40-50 хвилин
Передумови: Модуль 2.1 (Поди), Модуль 2.2 (Деплойменти)
Що ви зможете робити
Розділ «Що ви зможете робити»Після цього модуля ви зможете:
- Розгорнути DaemonSets для сервісів на рівні вузлів та StatefulSets для stateful-застосунків
- Пояснити, як іменування подів StatefulSet, прив’язка PVC та упорядковане розгортання відрізняються від Deployments
- Налаштувати tolerations DaemonSet для запуску на вузлах площини управління за потреби
- Діагностувати проблеми StatefulSet (застрягла прив’язка PVC, збої упорядкованого розгортання, DNS headless service)
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Деплойменти чудово працюють для застосунків без стану, але не все є stateless. Деякі навантаження мають особливі вимоги:
- DaemonSets: Коли вам потрібен рівно один Под на кожному вузлі (збір логів, моніторинг, мережеві плагіни)
- StatefulSets: Коли Поди потребують стабільних ідентичностей і постійного сховища (бази даних, розподілені системи)
Іспит CKA перевіряє ваше розуміння того, коли використовувати кожен контролер і як їх діагностувати. Знання правильного інструменту для кожного завдання — ключова навичка адміністратора.
Аналогія зі спеціалізованими командами
Уявіть свій кластер як лікарню. Деплойменти — це терапевти: їх може бути скільки завгодно, вони взаємозамінні, і пацієнтам байдуже, до якого саме потрапити. DaemonSets — це охоронці: потрібен рівно один на кожному вході (вузлі), не більше й не менше. StatefulSets — це хірурги: кожен має унікальну ідентичність, власні виділені інструменти (сховище), і пацієнти звертаються конкретно до «доктора Сміта» (стабільна мережева ідентичність).
Що ви дізнаєтесь
Розділ «Що ви дізнаєтесь»До кінця цього модуля ви зможете:
- Створювати та керувати DaemonSets
- Розуміти, коли використовувати DaemonSets замість Деплойментів
- Створювати та керувати StatefulSets
- Розуміти стабільну мережеву ідентичність і сховище
- Діагностувати проблеми DaemonSet та StatefulSet
Частина 1: DaemonSets
Розділ «Частина 1: DaemonSets»1.1 Що таке DaemonSet?
Розділ «1.1 Що таке DaemonSet?»DaemonSet гарантує, що всі (або деякі) вузли запускають копію Пода.
┌────────────────────────────────────────────────────────────────┐│ DaemonSet ││ ││ Вузол 1 Вузол 2 Вузол 3 ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ ││ │ │ DS Под │ │ │ │ DS Под │ │ │ │ DS Под │ │ ││ │ │(fluentd)│ │ │ │(fluentd)│ │ │ │(fluentd)│ │ ││ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ ││ │ │ │ │ │ │ ││ │ [Поди App] │ │ [Поди App] │ │ [Поди App] │ ││ │ │ │ │ │ │ ││ └─────────────┘ └─────────────┘ └─────────────┘ ││ ││ Коли Вузол 4 приєднується → DaemonSet автоматично створює Под││ Коли Вузол 2 від'єднується → Под видаляється ││ │└────────────────────────────────────────────────────────────────┘1.2 Типові випадки використання DaemonSet
Розділ «1.2 Типові випадки використання DaemonSet»| Випадок використання | Приклад |
|---|---|
| Збір логів | Fluentd, Filebeat |
| Моніторинг вузлів | Node Exporter, Datadog agent |
| Мережеві плагіни | Calico, Cilium, Weave |
| Демони сховища | GlusterFS, Ceph |
| Агенти безпеки | Falco, Sysdig |
1.3 Створення DaemonSet
Розділ «1.3 Створення DaemonSet»apiVersion: apps/v1kind: DaemonSetmetadata: name: fluentd labels: app: fluentdspec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: containers: - name: fluentd image: fluentd:v1.16 resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog hostPath: path: /var/logkubectl apply -f fluentd-daemonset.yaml1.4 DaemonSet проти Деплойменту
Розділ «1.4 DaemonSet проти Деплойменту»| Аспект | DaemonSet | Деплоймент |
|---|---|---|
| Кількість Подів | Один на вузол (автоматично) | Вказана кількість реплік |
| Планування | Обходить планувальник | Використовує планувальник |
| Додавання вузла | Автоматично створює Под | Жодних автоматичних дій |
| Випадок використання | Сервіси рівня вузла | Навантаження застосунків |
1.5 Команди для DaemonSet
Розділ «1.5 Команди для DaemonSet»# Список DaemonSetskubectl get daemonsetskubectl get ds # Скорочена форма
# Опис DaemonSetkubectl describe ds fluentd
# Перевірка Подів, створених DaemonSetkubectl get pods -l app=fluentd -o wide
# Видалення DaemonSetkubectl delete ds fluentdЧи знали ви?
DaemonSets за замовчуванням ігнорують більшість обмежень планування. Вони навіть запускаються на вузлах площини управління, якщо немає taints, які цьому перешкоджають. Використовуйте
nodeSelectorабоtolerationsдля контролю розміщення.
Частина 2: Планування DaemonSet
Розділ «Частина 2: Планування DaemonSet»2.1 Запуск на конкретних вузлах
Розділ «2.1 Запуск на конкретних вузлах»Використовуйте nodeSelector, щоб запускати лише на певних вузлах:
apiVersion: apps/v1kind: DaemonSetmetadata: name: ssd-monitorspec: selector: matchLabels: app: ssd-monitor template: metadata: labels: app: ssd-monitor spec: nodeSelector: disk: ssd # Тільки вузли з цим лейблом containers: - name: monitor image: busybox command: ["sleep", "infinity"]# Додати лейбл до вузлаkubectl label node worker-1 disk=ssd
# DaemonSet запускається лише на вузлах з лейбломkubectl get pods -l app=ssd-monitor -o wide2.2 Толерування Taints
Розділ «2.2 Толерування Taints»DaemonSets часто потребують запуску на вузлах з taints:
apiVersion: apps/v1kind: DaemonSetmetadata: name: node-monitorspec: selector: matchLabels: app: node-monitor template: metadata: labels: app: node-monitor spec: tolerations: # Толерування taint площини управління - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule # Толерування всіх taints (запуск скрізь) - operator: Exists containers: - name: monitor image: prom/node-exporter2.3 Стратегія оновлення
Розділ «2.3 Стратегія оновлення»apiVersion: apps/v1kind: DaemonSetmetadata: name: fluentdspec: updateStrategy: type: RollingUpdate # За замовчуванням rollingUpdate: maxUnavailable: 1 # Оновлення по одному вузлу за раз selector: matchLabels: app: fluentd template: # ...| Стратегія | Поведінка |
|---|---|
RollingUpdate | Поступове оновлення Подів, по одному вузлу за раз |
OnDelete | Оновлення лише після ручного видалення Пода |
Частина 3: StatefulSets
Розділ «Частина 3: StatefulSets»3.1 Що таке StatefulSet?
Розділ «3.1 Що таке StatefulSet?»StatefulSets керують застосунками зі станом та забезпечують:
- Стабільні, унікальні мережеві ідентифікатори
- Стабільне, постійне сховище
- Впорядковане, коректне розгортання та масштабування
┌────────────────────────────────────────────────────────────────┐│ StatefulSet ││ ││ На відміну від Деплойментів, Поди мають стабільні ││ ідентичності: ││ ││ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ││ │ web-0 │ │ web-1 │ │ web-2 │ ││ │ (завжди 0) │ │ (завжди 1) │ │ (завжди 2) │ ││ │ │ │ │ │ │ ││ │ PVC: data-0 │ │ PVC: data-1 │ │ PVC: data-2 │ ││ │ DNS: web-0... │ │ DNS: web-1... │ │ DNS: web-2... │ ││ └───────────────┘ └───────────────┘ └───────────────┘ ││ ││ Якщо web-1 зупиняється і перезапускається: ││ - Все ще має ім'я web-1 (не web-3) ││ - Повторно підключає PVC data-1 ││ - Те саме DNS-ім'я: web-1.nginx.default.svc.cluster.local ││ │└────────────────────────────────────────────────────────────────┘3.2 Випадки використання StatefulSet
Розділ «3.2 Випадки використання StatefulSet»| Випадок використання | Приклад |
|---|---|
| Бази даних | PostgreSQL, MySQL, MongoDB |
| Розподілені системи | Kafka, Zookeeper, etcd |
| Пошукові системи | Elasticsearch |
| Черги повідомлень | RabbitMQ |
3.3 Вимоги StatefulSet
Розділ «3.3 Вимоги StatefulSet»StatefulSets вимагають Headless Service для мережевої ідентичності:
# Headless Service (обов'язковий)apiVersion: v1kind: Servicemetadata: name: nginx labels: app: nginxspec: ports: - port: 80 name: web clusterIP: None # Це робить його headless selector: app: nginx---# StatefulSetapiVersion: apps/v1kind: StatefulSetmetadata: name: webspec: serviceName: nginx # Повинен посилатися на headless service replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: data mountPath: /usr/share/nginx/html volumeClaimTemplates: # Створює PVC для кожного Пода - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi3.4 Стабільна мережева ідентичність
Розділ «3.4 Стабільна мережева ідентичність»# DNS-імена Подів відповідають шаблону:# <ім'я-пода>.<ім'я-сервісу>.<namespace>.svc.cluster.local
# Для StatefulSet "web" з headless service "nginx":web-0.nginx.default.svc.cluster.localweb-1.nginx.default.svc.cluster.localweb-2.nginx.default.svc.cluster.local
# Інші Поди можуть звертатися до конкретних екземплярів:curl web-0.nginxcurl web-1.nginx3.5 Стабільне сховище
Розділ «3.5 Стабільне сховище»# Кожен Под отримує власний PVC з іменем:# <volumeClaimTemplates.name>-<ім'я-пода>data-web-0data-web-1data-web-2
# При перезапуску Під повторно підключає свій конкретний PVC# Дані зберігаються між перезапусками ПодаЧи знали ви?
Коли ви видаляєте StatefulSet, PVC НЕ видаляються автоматично. Це функція безпеки — ваші дані зберігаються. Щоб очистити сховище, вручну видаліть PVC після видалення StatefulSet.
Частина 4: Операції з StatefulSet
Розділ «Частина 4: Операції з StatefulSet»4.1 Впорядковане створення та видалення
Розділ «4.1 Впорядковане створення та видалення»Масштабування вгору (0 → 3):web-0 створено й готово → web-1 створено й готово → web-2 створено
Масштабування вниз (3 → 1):web-2 завершено → web-1 завершено → web-0 залишається
Кожен Під очікує, поки попередній буде в стані Running та Ready4.2 Політика керування Подами
Розділ «4.2 Політика керування Подами»apiVersion: apps/v1kind: StatefulSetmetadata: name: webspec: podManagementPolicy: OrderedReady # За замовчуванням — послідовно # podManagementPolicy: Parallel # Всі одночасно (як Деплоймент)| Політика | Поведінка |
|---|---|
OrderedReady | Послідовне створення/видалення (за замовчуванням) |
Parallel | Всі Поди створюються/видаляються одночасно |
4.3 Стратегія оновлення
Розділ «4.3 Стратегія оновлення»apiVersion: apps/v1kind: StatefulSetmetadata: name: webspec: updateStrategy: type: RollingUpdate rollingUpdate: partition: 2 # Оновлювати лише Поди >= 2Partition дає змогу робити канаркові розгортання:
- З
partition: 2лише web-2 отримує оновлення - web-0 та web-1 залишаються на старій версії
- Корисно для тестування оновлень на підмножині Подів
4.4 Команди для StatefulSet
Розділ «4.4 Команди для StatefulSet»# Список StatefulSetskubectl get statefulsetskubectl get sts # Скорочена форма
# Описkubectl describe sts web
# Масштабуванняkubectl scale sts web --replicas=5
# Перевірка Подів (зверніть увагу на впорядковані імена)kubectl get pods -l app=nginx
# Перевірка PVC (один на кожен Під)kubectl get pvc
# Видалення StatefulSet (PVC залишаються!)kubectl delete sts web
# Ручне видалення PVCkubectl delete pvc data-web-0 data-web-1 data-web-2Частина 5: Деплоймент проти StatefulSet
Розділ «Частина 5: Деплоймент проти StatefulSet»5.1 Порівняння
Розділ «5.1 Порівняння»| Аспект | Деплоймент | StatefulSet |
|---|---|---|
| Імена Подів | Випадковий суфікс (nginx-5d5dd5d5fb-xyz) | Порядковий індекс (web-0, web-1) |
| Мережева ідентичність | Немає (використовуйте Service) | Стабільний DNS для кожного Пода |
| Сховище | Спільне або відсутнє | Виділений PVC для кожного Пода |
| Порядок масштабування | Будь-який порядок | Послідовний (впорядкований) |
| Поступове оновлення | Випадковий порядок | Зворотний порядок (спочатку N-1) |
| Випадок використання | Застосунки без стану | Застосунки зі станом |
5.2 Коли що використовувати
Розділ «5.2 Коли що використовувати»┌────────────────────────────────────────────────────────────────┐│ Вибір правильного контролера ││ ││ Чи потребує кожен Під унікальну ідентичність? ││ │ ││ ├── Ні ──► Чи потрібен один Під на кожному вузлі? ││ │ │ ││ │ ├── Так ──► DaemonSet ││ │ │ ││ │ └── Ні ──► Деплоймент ││ │ ││ └── Так ──► Чи потрібне постійне сховище? ││ │ ││ └── Так/Ні ──► StatefulSet ││ │└────────────────────────────────────────────────────────────────┘Історія з практики: Катастрофа з базою даних
Одна команда розгорнула PostgreSQL за допомогою Деплойменту з PVC. Все працювало — поки Під не було переплановано на інший вузол. Новий Під отримав іншу IP-адресу, реплікація зламалася, і резервний сервер не міг знайти основний. Перехід на StatefulSet зі стабільною мережевою ідентичністю вирішив усе. Використовуйте правильний інструмент!
Частина 6: Headless Services — глибоке занурення
Розділ «Частина 6: Headless Services — глибоке занурення»6.1 Що таке Headless Service?
Розділ «6.1 Що таке Headless Service?»Service з clusterIP: None. Замість балансування навантаження DNS повертає IP-адреси окремих Подів.
# Звичайний ServiceapiVersion: v1kind: Servicemetadata: name: nginx-regularspec: selector: app: nginx ports: - port: 80# DNS: nginx-regular → ClusterIP (з балансуванням)
---# Headless ServiceapiVersion: v1kind: Servicemetadata: name: nginx-headlessspec: clusterIP: None # Headless! selector: app: nginx ports: - port: 80# DNS: nginx-headless → Повертає всі IP Подів# DNS: web-0.nginx-headless → IP конкретного Пода6.2 Порівняння DNS-резолюції
Розділ «6.2 Порівняння DNS-резолюції»# Звичайний service — повертає ClusterIPnslookup nginx-regular# Server: 10.96.0.10# Address: 10.96.0.10#53# Name: nginx-regular.default.svc.cluster.local# Address: 10.96.100.50 (ClusterIP)
# Headless service — повертає IP Подівnslookup nginx-headless# Server: 10.96.0.10# Address: 10.96.0.10#53# Name: nginx-headless.default.svc.cluster.local# Address: 10.244.1.5 (IP Пода)# Address: 10.244.2.6 (IP Пода)# Address: 10.244.3.7 (IP Пода)Типові помилки
Розділ «Типові помилки»| Помилка | Проблема | Рішення |
|---|---|---|
| StatefulSet без headless Service | Поди не отримують стабільних DNS-імен | Створіть headless Service з відповідним selector |
| Видалення StatefulSet з очікуванням автоочищення PVC | Дані залишаються, квота сховища витрачається | Вручну видаліть PVC, якщо дані не потрібні |
| Використання Деплойменту для баз даних | Немає стабільної ідентичності, проблеми зі сховищем | Використовуйте StatefulSet для навантажень зі станом |
| DaemonSet на всіх вузлах несподівано | Запускається й на площині управління | Додайте відповідні tolerations/nodeSelector |
| Неправильне serviceName у StatefulSet | DNS-резолюція не працює | Переконайтеся, що serviceName відповідає імені headless Service |
Тест
Розділ «Тест»-
Що гарантує запуск рівно одного Пода на кожному вузлі?
Відповідь
**DaemonSet**. Він автоматично створює Під на кожному вузлі (або на вибраних вузлах через nodeSelector) і видаляє Поди при видаленні вузлів. -
Навіщо StatefulSets потрібен headless Service?
Відповідь
Headless Service (clusterIP: None) надає стабільні DNS-імена для кожного Пода. Без нього Поди не мали б передбачуваних мережевих ідентичностей. Формат DNS: `<ім'я-пода>.<ім'я-сервісу>..svc.cluster.local`. -
Що відбувається з PVC при видаленні StatefulSet?
Відповідь
PVC **НЕ** видаляються автоматично. Це функція безпеки для збереження даних. Вам потрібно вручну видалити PVC, якщо ви хочете звільнити сховище. -
Чим масштабування StatefulSet відрізняється від Деплойменту?
Відповідь
StatefulSets масштабуються **послідовно**. Масштабування вгору: web-0, потім web-1, потім web-2 (кожен очікує, поки попередній буде Ready). Масштабування вниз: у зворотному порядку. Деплойменти масштабують Поди паралельно.
Практична вправа
Розділ «Практична вправа»Завдання: Створити DaemonSet і StatefulSet, зрозуміти їхню поведінку.
Кроки:
Частина A: DaemonSet
Розділ «Частина A: DaemonSet»- Створіть DaemonSet:
cat > node-monitor-ds.yaml << 'EOF'apiVersion: apps/v1kind: DaemonSetmetadata: name: node-monitorspec: selector: matchLabels: app: node-monitor template: metadata: labels: app: node-monitor spec: containers: - name: monitor image: busybox command: ["sh", "-c", "while true; do echo $(hostname); sleep 60; done"] resources: limits: memory: 50Mi cpu: 50mEOF
kubectl apply -f node-monitor-ds.yaml- Перевірте, що на кожному вузлі рівно один Під:
kubectl get pods -l app=node-monitor -o widekubectl get ds node-monitor# DESIRED = CURRENT = READY = кількість вузлів- Перегляньте логи Пода конкретного вузла:
kubectl logs -l app=node-monitor --all-containers- Очищення DaemonSet:
kubectl delete ds node-monitorrm node-monitor-ds.yamlЧастина B: StatefulSet
Розділ «Частина B: StatefulSet»- Створіть headless Service і StatefulSet:
cat > statefulset-demo.yaml << 'EOF'apiVersion: v1kind: Servicemetadata: name: nginxspec: clusterIP: None selector: app: nginx ports: - port: 80---apiVersion: apps/v1kind: StatefulSetmetadata: name: webspec: serviceName: nginx replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80EOF
kubectl apply -f statefulset-demo.yaml- Спостерігайте за впорядкованим створенням:
kubectl get pods -l app=nginx -w# web-0 Running, потім web-1, потім web-2- Перевірте стабільну мережеву ідентичність:
# Створіть тестовий Підkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup web-0.nginxkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup web-1.nginx- Масштабуйте вниз і спостерігайте за порядком:
kubectl scale sts web --replicas=1kubectl get pods -l app=nginx -w# web-2 завершується, потім web-1- Масштабуйте назад вгору:
kubectl scale sts web --replicas=3kubectl get pods -l app=nginx -w# web-1 створюється, потім web-2- Очищення:
kubectl delete -f statefulset-demo.yamlrm statefulset-demo.yamlКритерії успіху:
- Можете створювати DaemonSets
- Розумієте поведінку «один Під на вузол»
- Можете створювати StatefulSets з headless Services
- Розумієте впорядковане масштабування
- Знаєте, коли використовувати кожен контролер
Практичні вправи
Розділ «Практичні вправи»Вправа 1: Створення DaemonSet (Ціль: 3 хвилини)
Розділ «Вправа 1: Створення DaemonSet (Ціль: 3 хвилини)»# Створіть DaemonSetcat << 'EOF' | kubectl apply -f -apiVersion: apps/v1kind: DaemonSetmetadata: name: log-collectorspec: selector: matchLabels: app: log-collector template: metadata: labels: app: log-collector spec: containers: - name: collector image: busybox command: ["sleep", "infinity"]EOF
# Перевіркаkubectl get ds log-collectorkubectl get pods -l app=log-collector -o wide
# Очищенняkubectl delete ds log-collectorВправа 2: DaemonSet з nodeSelector (Ціль: 5 хвилин)
Розділ «Вправа 2: DaemonSet з nodeSelector (Ціль: 5 хвилин)»# Додайте лейбл до вузлаNODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')kubectl label node $NODE disk=ssd
# Створіть DaemonSet з nodeSelectorcat << 'EOF' | kubectl apply -f -apiVersion: apps/v1kind: DaemonSetmetadata: name: ssd-onlyspec: selector: matchLabels: app: ssd-only template: metadata: labels: app: ssd-only spec: nodeSelector: disk: ssd containers: - name: app image: busybox command: ["sleep", "infinity"]EOF
# Перевірка — повинен запуститися лише на вузлі з лейбломkubectl get pods -l app=ssd-only -o wide
# Очищенняkubectl delete ds ssd-onlykubectl label node $NODE disk-Вправа 3: Базовий StatefulSet (Ціль: 5 хвилин)
Розділ «Вправа 3: Базовий StatefulSet (Ціль: 5 хвилин)»# Створіть headless service та StatefulSetcat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Servicemetadata: name: dbspec: clusterIP: None selector: app: db ports: - port: 5432---apiVersion: apps/v1kind: StatefulSetmetadata: name: dbspec: serviceName: db replicas: 3 selector: matchLabels: app: db template: metadata: labels: app: db spec: containers: - name: postgres image: busybox command: ["sleep", "infinity"]EOF
# Спостерігайте за впорядкованим створеннямkubectl get pods -l app=db -w &sleep 30kill %1
# Перевірте іменаkubectl get pods -l app=db
# Очищенняkubectl delete sts dbkubectl delete svc dbВправа 4: Тест DNS для StatefulSet (Ціль: 5 хвилин)
Розділ «Вправа 4: Тест DNS для StatefulSet (Ціль: 5 хвилин)»# Створіть StatefulSet з headless servicecat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Servicemetadata: name: nginxspec: clusterIP: None selector: app: nginx ports: - port: 80---apiVersion: apps/v1kind: StatefulSetmetadata: name: webspec: serviceName: nginx replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginxEOF
# Дочекайтеся готовностіkubectl wait --for=condition=ready pod/web-0 pod/web-1 --timeout=60s
# Тест DNS-резолюціїkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup nginxkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup web-0.nginxkubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup web-1.nginx
# Очищенняkubectl delete sts webkubectl delete svc nginxВправа 5: Порядок масштабування StatefulSet (Ціль: 3 хвилини)
Розділ «Вправа 5: Порядок масштабування StatefulSet (Ціль: 3 хвилини)»# Створіть StatefulSetcat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Servicemetadata: name: order-testspec: clusterIP: None selector: app: order-test ports: - port: 80---apiVersion: apps/v1kind: StatefulSetmetadata: name: orderspec: serviceName: order-test replicas: 1 selector: matchLabels: app: order-test template: metadata: labels: app: order-test spec: containers: - name: nginx image: nginxEOF
# Масштабуйте вгору і спостерігайте за порядкомkubectl scale sts order --replicas=3kubectl get pods -l app=order-test -w &sleep 30kill %1
# Масштабуйте вниз і спостерігайте за зворотним порядкомkubectl scale sts order --replicas=1kubectl get pods -l app=order-test -w &sleep 30kill %1
# Очищенняkubectl delete sts orderkubectl delete svc order-testВправа 6: Діагностика — DaemonSet не запускається на вузлі
Розділ «Вправа 6: Діагностика — DaemonSet не запускається на вузлі»# Додайте taint до вузлаNODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')kubectl taint node $NODE special=true:NoSchedule
# Створіть DaemonSet без tolerationcat << 'EOF' | kubectl apply -f -apiVersion: apps/v1kind: DaemonSetmetadata: name: no-tolerationspec: selector: matchLabels: app: no-toleration template: metadata: labels: app: no-toleration spec: containers: - name: app image: busybox command: ["sleep", "infinity"]EOF
# Перевірка — не запуститься на вузлі з taintkubectl get pods -l app=no-toleration -o widekubectl get ds no-toleration
# ВАШЕ ЗАВДАННЯ: Виправити, додавши toleration# (Видаліть і створіть заново з toleration)
# Очищенняkubectl delete ds no-tolerationkubectl taint node $NODE special-Рішення
cat << 'EOF' | kubectl apply -f -apiVersion: apps/v1kind: DaemonSetmetadata: name: with-tolerationspec: selector: matchLabels: app: with-toleration template: metadata: labels: app: with-toleration spec: tolerations: - key: special operator: Equal value: "true" effect: NoSchedule containers: - name: app image: busybox command: ["sleep", "infinity"]EOF
kubectl get pods -l app=with-toleration -o widekubectl delete ds with-tolerationВправа 7: Завдання — Визначте правильний контролер
Розділ «Вправа 7: Завдання — Визначте правильний контролер»Для кожного сценарію визначте, що використовувати — Деплоймент, DaemonSet чи StatefulSet:
- Веб-застосунок з 5 репліками
- Збирач логів на кожному вузлі
- Кластер бази даних PostgreSQL
- REST API сервіс
- Prometheus node exporter
- Кластер Kafka
- nginx reverse proxy
Відповіді
- Деплоймент — Веб-застосунок без стану
- DaemonSet — Потрібен один на кожному вузлі
- StatefulSet — Потребує стабільної ідентичності та сховища
- Деплоймент — REST API без стану
- DaemonSet — Агент моніторингу на кожному вузлі
- StatefulSet — Розподілена система зі стабільною ідентичністю
- Деплоймент — Проксі без стану (якщо не потрібен конкретний екземпляр)
Наступний модуль
Розділ «Наступний модуль»Модуль 2.4: Jobs та CronJobs — Пакетні навантаження та заплановані завдання.