Перейти до вмісту

Модуль 2.4: Оновлення безпеки Kubernetes

Hands-On Lab Available
K8s Cluster advanced 40 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [СЕРЕДНЯ] — повторення матеріалу CKA з акцентом на безпеці

Час на проходження: 35–40 хвилин

Передумови: знання оновлень із CKA, досвід роботи з kubeadm


Що ви зможете зробити

Розділ «Що ви зможете зробити»

Після завершення цього модуля ви зможете:

  1. Оцінювати CVE-бюлетені Kubernetes та вікна підтримки релізів, щоб обрати безпечну ціль для оновлення.
  2. Перевіряти свідчення на рівні кластера, нод, площини управління та робочих навантажень перед затвердженням оновлення Kubernetes.
  3. Впроваджувати робочий процес оновлення через kubeadm, який зберігає резервні копії, дотримання правил розбіжності версій (version skew) та засоби контролю безпеки.
  4. Діагностувати збої RBAC, admission, політик та бенчмарків після оновлення, перш ніж повертати трафік до звичайного стану.
  5. Проєктувати стратегії оновлення для керованих і самокерованих кластерів, які мінімізують вікна вразливості з боку безпеки.

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Гіпотетичний сценарій: у понеділок зранку виходить бюлетень про вразливість, у якому сказано, що виправлення доступне лише в новіших патч-релізах Kubernetes, ніж той, на якому працює ваш робочий кластер. Кластер усе ще планує Поди, дашборди зелені, і бізнес волів би почекати до наступного щомісячного вікна обслуговування. З погляду безпеки цей спокій на поверхні оманливий, адже бюлетень перетворив невідому слабкість на задокументовану вимогу до оновлення, яку можуть прочитати атакувальники, аудитори й захисники.

Іспит CKS трактує оновлення як роботу з безпеки, а не як рутинне господарювання. Від вас очікують уміння читати зв’язок між підтримуваними релізами, виправленнями CVE, версіями компонентів, розбіжністю версій, резервними копіями, поведінкою admission та валідацією після оновлення. Механічні команди kubeadm важливі, але вони лише частина рішення: безпечне оновлення також доводить, що обрана версія містить виправлення, що кожен компонент має право працювати поряд зі своїми сусідами, і що робочі навантаження після зміни стикаються з тими самими або сильнішими засобами контролю безпеки.

Цей модуль переписує рефлекс оновлення з CKA на дисципліну оновлення CKS. Ви почнете з оцінювання того, чи перебуває версія ще в межах вікна підтримки патчів, потім зберете свідчення щодо версій і конфігурації, а потім застосуєте план оновлення на основі kubeadm із перевірками безпеки по обидва боки обслуговування. Наприкінці ви маєте вміти пояснити не лише те, яку команду виконати, а й те, чому ця команда доречна саме в цей момент реагування на безпекову подію.

Наслідки версій для безпеки

Розділ «Наслідки версій для безпеки»

Оновлення безпеки Kubernetes починаються з моделі підтримки релізів, бо саме модель підтримки каже вам, чи може взагалі існувати патч для вашої поточної мінорної версії. Апстрім-проєкт підтримує рухомий набір останніх мінорних релізів, і виправлення безпеки бекпортуються лише всередині цього вікна підтримки. Для цілі 1.35, яку використано в цьому курсі, робочим прикладом є 1.33, 1.34 та 1.35 як підтримувані мінорні версії; 1.32 і старіші перебувають поза прикладовим вікном, і їх слід вважати непідтримуваними для планування безпеки.

+-------------------------------------------------------------+
| VERSION SECURITY LIFECYCLE |
+-------------------------------------------------------------+
| |
| Kubernetes Support Model: |
| --------------------------------------------------------- |
| - 3 minor versions supported at any time |
| - Security fixes backported to all supported minors |
| - Older versions receive no new security patches |
| |
| Example when the target release is 1.35: |
| +-- 1.35 Supported, receives security patches |
| +-- 1.34 Supported, receives security patches |
| +-- 1.33 Supported, receives security patches |
| +-- 1.32 End of life, no new patches |
| +-- 1.31 Unsupported, known issues remain |
| |
| Risk of running unsupported versions: |
| - Known CVEs remain unpatched |
| - Security advisories may not provide a fixed build |
| - Compliance evidence becomes difficult to defend |
| |
+-------------------------------------------------------------+

Важлива деталь полягає в тому, що «працює» і «підтримується» — це різні стани. Кластер на 1.32 може й далі приймати запити до API навіть тоді, коли проєкт припинив випускати пропатчені бінарні файли 1.32, так само як прострочений паспорт усе ще може виглядати як паспорт у вашій шухляді. Операційний ризик не в тому, що кластер негайно зупиняється; ризик у тому, що розкрита вразливість може залишатися присутньою назавжди, якщо ви не перетнете межу мінорної версії.

Зробіть паузу й передбачте: ваш кластер працює на Kubernetes 1.32, а підтримуване прикладове вікно — це 1.33, 1.34 та 1.35. Оголошено критичну CVE, що зачіпає релізи аж до 1.34.2, а ваша поточна версія перебуває поза вікном підтримки. Які варіанти лишаються доступними, і який із них найшвидше зменшує вікно вразливості, не вдаючи, ніби непідтримуваний патч колись з’явиться?

Аудит версій має збирати більше, ніж єдину версію сервера, яку показує типовий виклик kubectl version. API-сервер, controller-manager, scheduler, kubelet’и, образи статичних Подів, образ etcd та клієнтський інструментарій можуть рухатися в різний час протягом оновлення. Коли ви досліджуєте бюлетень про вразливість, вам потрібно достатньо свідчень, щоб довести, який саме компонент уражений і чи не пропустили якусь ноду або Под площини управління під час минулого обслуговування.

Інвентаризація має також включати те, як побудований кластер, бо той самий номер версії Kubernetes може ховати дуже різні операційні обов’язки. Кластер на kubeadm віддає під ваш безпосередній контроль etcd, маніфести статичних Подів, пакети хоста, конфігурацію kubelet та оновлення операційної системи нод. Керований кластер передає розміщений API-сервер у руки провайдера, але образи нод, додатки (add-ons), webhook’и admission, маніфести робочих навантажень та політики просторів імен можуть і далі залишатися вашою відповідальністю.

Для планування безпеки трактуйте дані про версії як свідчення з визначеними межами, а не як єдиний «пройдено/не пройдено». Якщо API-сервер виправлено, але робочий вузол досі запускає уражений kubelet, заплановані там робочі навантаження можуть лишатися вразливими до проблеми на боці ноди. Якщо кожен kubelet пропатчено, але CNI або webhook admission несумісний із новою поведінкою API, кластер може стати менш надійним саме тоді, коли вам потрібне чисте реагування. Якісна робота з оновленнями тримає ці межі видимими.

Terminal window
# Check cluster version
kubectl version
# Check all component versions
kubectl get nodes -o wide
# Check control plane component versions
kubectl get pods -n kube-system -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.containers[0].image}{"\n"}{end}' | grep -E "kube-apiserver|kube-controller|kube-scheduler|etcd"
# Check kubelet versions on nodes
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}: {.status.nodeInfo.kubeletVersion}{"\n"}{end}'

Зрілий аудит також розрізняє факти кластера й факти менеджера пакетів. kubectl get nodes каже вам, яку версію kubelet кожна нода повідомляє API-серверу, але не доводить, що в репозиторії пакетів хоста не чекає новіший патч безпеки. Образи статичних Подів показують, що насправді запускає площина управління, але вони не замінюють приміток до релізів, журналів змін пакетів або бюлетенів провайдера. Трактуйте кластер як місце злочину: зберіть свідчення з API, з ноди та з джерела вендора, перш ніж вирішувати, як реагувати.

Тріаж CVE та вибір цілі для оновлення

Розділ «Тріаж CVE та вибір цілі для оновлення»

Бюлетень про CVE в Kubernetes зазвичай дає вам три фрагменти інформації, важливі для дій: уражені версії, виправлені версії та умови, потрібні для експлуатації. Рівень критичності каже вам, наскільки слід хвилюватися, але рядок із виправленою версією каже вам, що робити. Якщо бюлетень повідомляє, що виправлення містять 1.34.4 та 1.35.0, то «оновіться до новішого Kubernetes» — занадто розпливчасто; план має назвати патч-реліз, який і виправлений, і досяжний з вашого поточного кластера.

+-------------------------------------------------------------+
| KUBERNETES CVE EXAMPLE |
+-------------------------------------------------------------+
| |
| CVE-2024-XXXX: Container Escape via Symlink Attack |
| |
| Severity: HIGH (CVSS 8.8) |
| Affected: v1.26.0 - v1.27.5 |
| Fixed: v1.27.6, v1.28.2, v1.29.0 |
| |
| Impact: |
| A malicious container can write to the host filesystem |
| using a specially crafted symlink |
| |
| Action: |
| Upgrade to a fixed version immediately |
| |
| Where to find CVEs: |
| - kubernetes.io/security |
| - github.com/kubernetes/kubernetes/security/advisories |
| - cve.mitre.org |
| |
+-------------------------------------------------------------+

Найбезпечніша ціль — це зазвичай найменша виправлена версія, що вкладається у ваші обмеження щодо підтримки та розбіжності версій. Якщо робочий кластер уже на 1.34.1, а бюлетень виправлено в 1.34.4, патч-оновлення до 1.34.4 часто менш руйнівне, ніж мінорне оновлення до 1.35.0. Однак якщо поточна мінорна версія непідтримувана, ви не можете чекати на патч, який ніколи не буде зібрано, тож реагуванням стає шлях мінорного оновлення з ретельним поетапним просуванням.

Перш ніж вирішувати, чи можуть пом’якшувальні заходи виграти час, вам слід також прочитати умови експлуатації. CVE, що потребує привілейованих Подів, томів hostPath або вимкненої політики admission, можна тимчасово пом’якшити, посиливши Pod Security Admission, seccomp, AppArmor, RBAC або політику середовища виконання. Ці пом’якшення не скасовують потреби в оновленні, але вони можуть зменшити досяжні шляхи атаки, поки координуються затвердження змін, осушення нод (node drains) та власники робочих навантажень.

Сценарій для вправи: бюлетень повідомляє, що обхід авторизації kube-apiserver зачіпає версії з 1.33.0 до 1.33.8 та з 1.34.0 до 1.34.3, із виправленнями в 1.33.9, 1.34.4 та 1.35.0. Ваш staging-кластер на 1.34.1, робочий на 1.34.2, а кластер розробки на 1.33.7. Перше рішення — це не те, чи оновлювати все до найновішого видимого релізу; перше рішення — яка виправлена ціль відповідає кожній поточній мінорній версії, зберігаючи безпечний порядок.

Для staging та робочого кластера в цьому сценарії перехід на 1.34.4 — це найвужча безпечна зміна, бо обидва кластери вже на 1.34, а виправлений патч існує в цій мінорній версії. Розробку можна перевести на 1.33.9, якщо 1.33 ще підтримується в робочому вікні, або її можна підняти до 1.34.4, якщо організація хоче відрепетирувати ту саму ціль перед робочим середовищем. Якщо 1.33 уже вийшла з підтримки, розробку не слід патчити всередині цієї мінорної версії, бо немає доступного підтримуваного виправленого патча.

Друге рішення — це те, чи потребує експлуатованість проміжних засобів контролю. Якщо обхід досяжний для автентифікованих користувачів із широким доступом до просторів імен, посильте RBAC та політику admission, поки заплановано обслуговування. Якщо обхід потребує вимкненої функції або конфігурації, якою ви не користуєтеся, задокументуйте цей факт, але не використовуйте його як виправдання, щоб залишати версію непропатченою на невизначений термін. Якісна нотатка тріажу відрізняє «наразі недосяжно» від «не уражено», бо це різні твердження.

Третє рішення — це послідовність. Розробка має виконувати команди першою, якщо вона достатньо зв’язана, щоб виявити реальні проблеми сумісності, але достатньо ізольована, щоб збій мав низький вплив на бізнес. Потім staging має довести поведінку робочих навантажень, admission та спостережуваність на об’єктах, подібних до робочих. Робоче середовище має отримати найменшу виправлену ціль лише після того, як репетиція дала точні команди, вивід валідації та тригери відкату. Ця послідовність — це прискорення безпеки, а не затримка, бо вона зменшує невідомі перед найчутливішою зміною.

Перш ніж це запускати, якого виводу ви очікуєте від справної передоновлювальної оцінки? Ви маєте очікувати узгоджені дані про версії, цільовий реліз, що з’являється в примітках до релізу, відсутність несподіваного використання застарілих API критичними робочими навантаженнями та артефакт резервної копії, що існує до зміни будь-якого компонента площини управління.

Terminal window
# 1. Check current version vulnerabilities
kubectl version
# Research CVEs for your version
# 2. Review release notes for security fixes
# https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/
# 3. Backup critical components
kubectl get all -A -o yaml > cluster-backup.yaml
ETCDCTL_API=3 etcdctl snapshot save backup.db
# 4. Check deprecated APIs in use (cluster-wide request traffic)
kubectl get --raw /metrics | grep apiserver_requested_deprecated
# Optional manifest spot-check for critical workloads:
kubectl get pod -n <namespace> <name> -o yaml | grep apiVersion

Цей чеклист навмисно консервативний. Експорт YAML по всіх просторах імен не є повною резервною копією для аварійного відновлення, але він фіксує достатньо наміру робочих навантажень, щоб порівняти стан до та після. Знімок etcd — це високоцінний артефакт площини управління в самокерованому кластері, бо kubeadm не може просто розкрутити назад кожну зміну стану площини управління, якщо API-сервер або сховище даних стають нездоровими. Метрика apiserver_requested_deprecated показує фактичний трафік до застарілих API, а не попередження клієнта kubectl, бо оновлення безпеки може зазнати невдачі з причин, які самі по собі не є вразливостями безпеки.

Обираючи між виправленими релізами, оцінюйте і вразливість, і радіус ураження (blast radius). Патч у межах тієї самої мінорної версії зазвичай має найменшу поведінкову поверхню, тоді як мінорне оновлення може включати вилучення API, зміни feature-gate, зміни значень за замовчуванням та нові очікування бенчмарків. Безпекова відповідь — це не завжди «найновіше негайно»; безпекова відповідь — це «виправлено, підтримується, сумісно й перевірювано в найкоротше відповідальне вікно».

Саме тут судження CKS відрізняється від чистого пригадування команд. Кандидат, який запам’ятав kubeadm upgrade apply, усе ще може ухвалити погане рішення з безпеки, обравши ціль, яка не містить виправлення, пропатчивши лише площину управління або залишивши непідтримувані кластери розробки під’єднаними до того самого конвеєра доставки. Кандидат, який може пояснити вибір цілі, здатен захистити зміну навіть тоді, коли точні деталі бюлетеня відрізняються.

Питання для рішенняНадавайте перевагу патч-оновленню, колиНадавайте перевагу мінорному оновленню, коли
Чи підтримується поточна мінорна версія?Так, і виправлення існує в тій самій мінорній версії.Ні, або виправлення не бекпортоване у вашу мінорну версію.
Чи ймовірні вилучення API?Вам потрібне низькоризикове аварійне виправлення.Ви вже пройшли сканування застарівань у staging.
Чи неоднорідні ноди?Ви можете патчити по одному пулу за раз.Вам потрібно стандартизувати застарілий парк.
Чи задіяний провайдер?Провайдер уже випустив виправлений патч.Політика підтримки провайдера вимагає переходу на новішу мінорну версію.

Безпечний робочий процес оновлення через kubeadm

Розділ «Безпечний робочий процес оновлення через kubeadm»

Оновлення через kubeadm впорядковані, бо API-сервер Kubernetes є якорем сумісності для решти кластера. API-сервер слід оновити перед компонентами, що залежать від його поведінки API, а kubelet’и не повинні бути новішими за API-сервер, якому вони звітують. Цей порядок — не церемонія; він запобігає тому, щоб частково оновлений кластер увійшов у такий зв’язок версій, який проєкт не тестує й не підтримує.

Передоновлювальний етап має дати явний запис про зміну. Цей запис називає поточну версію, цільову версію, уражену CVE або причину обслуговування, розташування резервної копії, висновки щодо застарівань, очікувану розбіжність версій під час обслуговування, тригер відкату та перевірки валідації. У контексті CKS вас можуть і не попросити написати запис про зміну, але мислення в таких термінах робить екзаменаційні команди легшими, бо кожна команда має причину.

Terminal window
# On control plane
sudo apt update
sudo apt install -y kubeadm=1.35.0-*
# Plan the upgrade
sudo kubeadm upgrade plan
# Apply upgrade
sudo kubeadm upgrade apply v1.35.0
# Upgrade kubelet and kubectl
sudo apt install -y kubelet=1.35.0-* kubectl=1.35.0-*
sudo systemctl daemon-reload
sudo systemctl restart kubelet

Послідовність kubeadm відокремлює планування від застосування, бо планування опитує поточний кластер і показує, які версії kubeadm вважає допустимими. Якщо вивід плану не показує очікувану вами виправлену версію, зупиніться й дослідіть конфігурацію репозиторію, підтримувані шляхи оновлення та доступність пакетів, перш ніж змінювати площину управління. Якщо проштовхуватися вперед з іншою версією, ви можете лишитися з кластером, який новіший, але все одно не пропатчений для бюлетеня, що спричинив роботу.

У кластері з кількома площинами управління тиск безпеки не скасовує потреби в дисципліні щодо кворуму та доступності. Оновлюйте по одній ноді площини управління за раз, перевіряйте здоров’я статичних Подів та членство в etcd після кожного кроку, потім переходьте до наступного члена. Для робочих вузлів — осушіть (drain), оновіть kubelet та середовище виконання за потреби, перезапустіть служби, зніміть позначку cordon (uncordon) та переконайтеся, що робочі навантаження повертаються з тією самою позицією безпеки, яку вони мали до зміни.

Кут зору CKS полягає в тому, що кожен операційний крок має побічний ефект для безпеки. Осушення ноди задіює PodDisruptionBudget’и й може виявити робочі навантаження, що працювали як єдині точки відмови. Перезапуск kubelet застосовує нові значення за замовчуванням і може змінити те, як результати admission виявляються на ноді. Оновлення kubectl зменшує ймовірність того, що оператор хибно прочитає поведінку сервера через старіший клієнт, хоча сам kubectl має м’якший допуск щодо розбіжності версій.

Резервні копії заслуговують на особливу увагу, бо резервна копія, яку ніколи не відновлювали, — це лише оптимістичний файл. У самокерованому кластері знімок etcd слід записати у відоме місце, скопіювати з ноди, коли це доречно, та поєднати з командою відновлення й припущеннями щодо сертифікатів, потрібними для його використання. Експорт YAML корисний для порівняння, але саме знімок etcd — це об’єкт, який захищає площину управління від невдалого оновлення або події пошкодження даних.

Керування пакетами теж має бути явним. Закріпіть або оберіть точні версії kubeadm, kubelet та kubectl, потрібні для цілі, потім уникайте автоматичних завдань із пакетами під час вікна обслуговування. Інструмент автоматизації на рівні хоста, який оновлює kubelet зарано, може створити розбіжність версій ще до того, як оператор дістанеться тієї ноди. І навпаки, забування оновити kubelet після площини управління може залишити кластер у технічно робочому, але неповному стані безпеки.

Осушення нод — це ще одне місце, де перетинаються безпека й доступність. Осушення, що зазнає невдачі через суворий PodDisruptionBudget, може виявити робоче навантаження, яке не може витримати обслуговування, тоді як примусове осушення може витіснити критичний Под без достатньої кількості реплік. Під час безпекової надзвичайної ситуації ви можете прийняти більше порушень, ніж зазвичай, але ви маєте ухвалювати це рішення свідомо й фіксувати, які робочі навантаження були захищені, відкладені або оброблені вручну.

Після кожної фази робіть невелику паузу для перевірки, а не чекайте до самого кінця. Підтвердьте образ оновленого Пода площини управління, підтвердьте стан Ready ноди, підтвердьте версію kubelet та підтвердьте, що робочі навантаження переплановані. Ці контрольні точки полегшують виявлення того, який крок спричинив несправність. Вони також допомагають уникнути поширеного режиму збою, коли команда завершує кожну команду з пакетами й лише потім виявляє, що перша нода площини управління була нездоровою.

Який підхід ви обрали б тут і чому: аварійний патч безпосередньо в робочому середовищі після зеленого kubeadm upgrade plan чи коротку репетицію в staging, яка спершу фіксує точні команди, вивід валідації та тригер відкату? Відповідь залежить від експлуатованості й вразливості, але репетиція часто скорочує ризик у робочому середовищі, бо перетворює обслуговування на виконання, а не на з’ясування.

Сумісність, застарівання та розбіжність версій

Розділ «Сумісність, застарівання та розбіжність версій»

Оновлення безпеки часто зазнають невдачі, бо кластер несе старі форми API в новіший API-сервер. Вразливість може бути в kubelet або API-сервері, але обслуговування все одно може бути заблоковане маніфестом Ingress, що використовує версію API, вилучену давно. Саме тому план оновлення безпеки має включати роботу із сумісністю, а не лише встановлення пакетів.

# Old API (may be removed in new version)
apiVersion: extensions/v1beta1
kind: Ingress
# New API
apiVersion: networking.k8s.io/v1
kind: Ingress

Старий і новий фрагменти Ingress навмисно прості, але реальна міграція зазвичай більша за зміну одного рядка. Новіші версії API можуть вимагати інших полів, поведінки за замовчуванням, правил валідації або очікувань контролера. Коли з’являється попередження про застарілий API, виправте модель об’єкта перед оновленням, якщо робоче навантаження важливе; інакше ви ризикуєте виявити потрібні зміни схеми під час вікна обслуговування.

CustomResourceDefinition додають ще один шар, бо API-сервер Kubernetes може бути здоровим, доки оператор усе ще залежить від старої схеми CRD або клієнтської бібліотеки. Перед мінорним оновленням перевірте, чи публікують контролери, webhook’и admission та оператори настанови щодо сумісності для цільового релізу. Патч безпеки, що ламає контролер політик, може випадково зменшити примусове виконання, тож додатки, які беруть участь у рішеннях щодо безпеки, мають бути частиною свідчень про оновлення.

Зміни admission заслуговують на таку саму увагу, бо засоби контролю безпеки часто переходять із застарілих розширень до новіших вбудованих механізмів. PodSecurityPolicy було вилучено в попередніх релізах Kubernetes, і Pod Security Admission є замінною базовою лінією для примусового виконання безпеки Подів на рівні просторів імен. Кластер, що оновлюється без зіставлення наміру старої політики з новими засобами контролю admission, може випадково послабити примусове виконання, навіть попри новіші бінарні файли.

Terminal window
# Check if PodSecurityPolicy is being removed
# (Removed in 1.25, use Pod Security Admission instead)
kubectl get psp 2>&1 | grep -q "the server doesn't have" && echo "PSP already removed"

Feature-gate створюють ще один край сумісності. Gate, який був потрібен, коли функція була бета, може стати непотрібним, вилученим або проігнорованим, коли функція дозріває. Залишення застарілих прапорців feature-gate у маніфестах статичних Подів може ускладнити майбутню діагностику, бо оператори не можуть швидко сказати, які прапорці ще впливають на поведінку, а які є історичними залишками.

Webhook’и admission особливо чутливі під час оновлень, бо вони сидять прямо на шляху запиту до API. Webhook, що використовує старий сертифікат, непідтримуваний API або недоступну службу, може заблокувати створення робочих навантажень саме в той момент, коли ноди осушуються й Подам потрібно переплануватися. Для оновлення безпеки перегляньте політики відмови (failure policies), здоров’я webhook’а, термін дії сертифіката та сумісність із цільовим API-сервером перед початком обслуговування.

# Some security features graduate from beta to stable
# Check if feature gates need updating in API server
# Example: PodSecurity feature (stable since 1.25)
- --feature-gates=PodSecurity=true # May not be needed anymore

Розбіжність версій — це формальна межа навколо цієї роботи із сумісністю. API-сервер має бути найновішим компонентом Kubernetes у кластері; controller-manager та scheduler йдуть слідом упритул; kubelet’и можуть відставати в межах задокументованої політики, але вони не повинні випереджати API-сервер. Правила розбіжності — це не рекомендація щодо продуктивності, бо вони визначають комбінації, які апстрім тестує й підтримує.

+-------------------------------------------------------------+
| VERSION SKEW RULES |
+-------------------------------------------------------------+
| |
| kube-apiserver: |
| +-- Must be the newest component in the cluster |
| |
| kube-controller-manager, kube-scheduler: |
| +-- Same minor as API server or one minor older |
| |
| kubelet: |
| +-- Up to three minors older (kubelet 1.25+) |
| +-- Never newer than the API server |
| |
| kubectl: |
| +-- One minor newer or older is supported |
| |
| Why this matters for security: |
| - Inconsistent versions can produce unexpected behavior |
| - Security fixes may not protect every component equally |
| - Upgrade API server first, then the remaining components |
| |
+-------------------------------------------------------------+

Для kubelet 1.25 і новіших API-сервер на 1.35 може поєднуватися з kubelet’ами аж до 1.32 (на три мінорні версії позаду). До kubelet 1.25 межа становила дві мінорні версії старіше. Див. політику розбіжності версій Kubernetes.

Зробіть паузу й передбачте: що станеться, якщо ви правильно оновите API-сервер до 1.35, але kubelet робочого вузла оновлено перед controller-manager, який усе ще працює на 1.33? Kubelet усе ще може бути допустимим, якщо він не новіший за API-сервер, але зв’язок із controller-manager може порушити розбіжність, щойно API-сервер опиниться на дві мінорні версії попереду, тож кластер може ввійти в стан, що частково функціональний, але непідтримуваний.

Практичний урок — підтримувати карту розбіжності версій під час оновлення, особливо коли той самий кластер торкаються кілька адміністраторів або завдань автоматизації. Запишіть бажаний порядок, тимчасові стани, що є допустимими, та стани, що потребують негайної зупинки. Якщо випадкове оновлення пакета виводить ноду чи компонент за межі політики, ваша наступна дія — не сліпо рухатися далі; це відновити підтримуваний зв’язок, оновивши наступним правильний компонент площини управління або ноду.

Корисна карта розбіжності достатньо мала, щоб її можна було читати під час зміни. Це може бути таблиця в тікеті, що перелічує кожен компонент площини управління, кожен пул нод, поточну версію, цільову версію та допустимий тимчасовий стан. Сенс не в паперовій тяганині; сенс — у спільному усвідомленні ситуації. Коли двоє інженерів працюють паралельно, карта не дає одній людині оновити пул нод, поки інша ще доводить фазу API-сервера.

Валідація, відкат та шляхи для керованих кластерів

Розділ «Валідація, відкат та шляхи для керованих кластерів»

Валідація після оновлення доводить, що кластер безпечніший, а не лише новіший. Перші перевірки — це перевірки життєздатності: Поди API-сервера працюють, ноди в стані Ready, а системні Поди стабільні. Другі перевірки — це перевірки безпеки: RBAC усе ще забороняє те, що має забороняти, admission усе ще відхиляє небезпечні робочі навантаження, NetworkPolicy усе ще існує й примусово виконується CNI, а вивід бенчмарку зрозумілий, а не зігнорований.

Додайте до цього проходу валідації перегляд подій та логів. Події Kubernetes можуть показати відмови admission, збої завантаження образів, проблеми планування та помилки CNI, які проста перевірка Ready пропускає. Логи площини управління можуть показати помилки автентифікації, тайм-аути webhook’ів або повторювані відмови авторизації після зміни API-сервера. Мета — не читати кожен рядок логу вручну; мета — взяти вибірку зі шляхів, що найімовірніше виявлять регресію засобу контролю безпеки, перш ніж користувачі виявлять її опосередковано.

Перевірки спостережуваності слід прив’язати до мети оновлення. Якщо оновлення спричинене CVE в kube-apiserver, спершу огляньте здоров’я API-сервера, автентифікацію, авторизацію, admission та поведінку аудиту. Якщо бюлетень зачіпає kubelet або межу середовища виконання контейнерів, надайте пріоритет версіям нод, логам kubelet, статусу середовища виконання, контекстам безпеки Подів та інвентарю привілейованих робочих навантажень. Цей фокус не дає валідації перетворитися на загальний обхід дашбордів, що виглядає ретельним, але пропускає компонент, який насправді був вразливим.

Логування аудиту заслуговує на особливу увагу під час оновлень безпеки, бо зламаний шлях аудиту може приховати пізніші свідчення. Підтвердьте, що конфігурація політики аудиту все ще завантажується, призначення логів аудиту все ще отримують записи, а високоцінні події, як-от відхилене створення Пода або спроби запуску привілейованих робочих навантажень, лишаються видимими. Кластер може бути технічно пропатчений, водночас ставши важчим для розслідування, а це не добрий результат для безпеки. Валідація має зберігати як виявлення, так і запобігання.

Нарешті, вирішіть, хто підписує оновлену позицію безпеки. Платформні інженери можуть довести здоров’я компонентів, але власникам робочих навантажень може знадобитися підтвердити поведінку застосунку, а інженерам безпеки — прийняти винятки бенчмарку чи тимчасові пом’якшення. Чітка межа підписання не дає оновленню завершитися розпливчастим повідомленням «виглядає добре». Бажаний результат — датований запис, що каже, яка версія працює, які перевірки безпеки пройшли, які винятки лишаються та хто володіє кожним подальшим кроком. Цей артефакт також дозволяє наступному оновленню починати зі свідчень, а не з пам’яті.

Terminal window
# Check Kubernetes security announcements
# https://kubernetes.io/docs/reference/issues-security/security/
# Check specific component for CVEs
trivy image registry.k8s.io/kube-apiserver:v1.35.0
# Check node OS for security updates
apt list --upgradable 2>/dev/null | grep -i security
# Use kube-bench to verify security settings after upgrade
./kube-bench run --targets=master

Бенчмарк-інструменти на кшталт kube-bench корисні після оновлення, бо версія бенчмарку, версія Kubernetes та значення площини управління за замовчуванням взаємодіють. Новий збій не означає автоматично, що оновлення зламало кластер; це може означати, що бенчмарк тепер перевіряє засіб контролю, який раніше не перевірявся, або що цільова версія Kubernetes має інше рекомендоване налаштування. Трактуйте зміни бенчмарку як свідчення, що потребує тріажу, а не як автоматичний доказ потреби у відкаті.

Рішення про відкат слід записати перед початком обслуговування, бо стрес робить розпливчасті критерії небезпечними. Відкочуйтеся, коли API-сервер не може стартувати, автентифікація чи авторизація зламана, здоров’я etcd скомпрометоване або admission відхиляє допустимі критичні робочі навантаження так, що ви не можете швидко це виправити. Не відкочуйтеся лише тому, що після оновлення з’явилося попередження про застарілий API; попередження — це сигнал виправити маніфести, а не причина повторно вводити непропатчену версію.

+-------------------------------------------------------------+
| ROLLBACK TRIGGERS |
+-------------------------------------------------------------+
| |
| Roll back if upgrade causes: |
| --------------------------------------------------------- |
| - API server not starting |
| - Authentication failures |
| - RBAC not working |
| - Networking issues such as CNI incompatibility |
| - Admission controller rejecting valid workloads |
| |
| Do not roll back for: |
| --------------------------------------------------------- |
| - Deprecated API warnings that require manifest fixes |
| - Feature changes that have documented migration paths |
| - Known issues with tested workarounds |
| |
+-------------------------------------------------------------+

Механізм відкату різниться між компонентами. Пакети kubelet зазвичай можна понизити, якщо репозиторій пакетів усе ще містить попередню версію, але kubeadm не підтримує невимушеного пониження площини управління після upgrade apply. Для збою площини управління вашим справжнім відкатом є перевірений знімок etcd та задокументована процедура відновлення, ось чому крок резервного копіювання є вимогою безпеки, а не адміністративною формальністю.

Terminal window
# Check previous kubelet version
journalctl -u kubelet | grep "Kubelet version" | head -1
# Downgrade kubelet (if needed)
sudo apt install kubelet=<previous-version>
sudo systemctl restart kubelet
# Note: kubeadm doesn't support direct downgrade
# For control plane, restore from etcd backup

Іспит часто подає завдання з оновлення як невеликі сценарії, тож тренуйтеся читати намір за кожною командою. Якщо завдання каже перевірити готовність, зберіть свідчення про узгодженість версій та застарілі API. Якщо воно каже перевірити безпеку після оновлення, протестуйте RBAC, admission, вивід бенчмарку та здоров’я системних Подів. Якщо воно каже знайти версію, що виправляє CVE, не вгадуйте з найвищого доступного пакета; з’єднайте рядок із виправленою версією з бюлетеня з ціллю.

Terminal window
# Check current versions match
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}: {.status.nodeInfo.kubeletVersion}{"\n"}{end}'
# All should show same version
# Inconsistent versions = security risk
# Check for deprecated APIs in use
kubectl get --raw /metrics | grep apiserver_requested_deprecated

Метрика apiserver_requested_deprecated — це корисна підказка, бо вона показує запити до застарілих API, які можуть бути неочевидними лише зі статичних маніфестів. Контролери, оператори та інструменти CI можуть і далі використовувати старіші API навіть після того, як YAML застосунку очищено. Під час репетиції оновлення ця метрика допомагає вам ідентифікувати того, хто викликає, перш ніж вилучений API перетвориться з попередження на простій.

Terminal window
# After upgrade, verify security settings
# 1. Check API server is running — expect at least one Running apiserver pod
kubectl get pods -n kube-system | grep apiserver
# 2. Verify RBAC allow + deny with a lab ServiceAccount and RoleBinding
kubectl create namespace upgrade-test --dry-run=client -o yaml | kubectl apply -f -
kubectl create serviceaccount probe-sa -n upgrade-test --dry-run=client -o yaml | kubectl apply -f -
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-lister
namespace: upgrade-test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-lister-binding
namespace: upgrade-test
subjects:
- kind: ServiceAccount
name: probe-sa
namespace: upgrade-test
roleRef:
kind: Role
name: pod-lister
apiGroup: rbac.authorization.k8s.io
EOF
kubectl auth can-i list pods -n upgrade-test --as=system:serviceaccount:upgrade-test:probe-sa
# Expect: yes
kubectl auth can-i create pods -n upgrade-test --as=system:serviceaccount:upgrade-test:probe-sa
# Expect: no
# 3. Confirm admission webhook configurations are registered — expect resource names (may be empty on minimal clusters)
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
# 4. Negative Pod Security Admission test — expect Admission denied for privileged pod
kubectl label namespace upgrade-test pod-security.kubernetes.io/enforce=restricted --overwrite
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: psa-probe
namespace: upgrade-test
spec:
containers:
- name: probe
image: busybox
command: ["sleep", "60"]
securityContext:
privileged: true
EOF
# Expect: error contains "violates PodSecurity"
kubectl delete pod psa-probe -n upgrade-test --ignore-not-found
# 5. Run kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs job/kube-bench

Перевірка RBAC має включати очікування і дозволу, і відмови. Один результат can-i може ввести в оману, якщо ви питаєте лише про дозвіл, який користувач і має мати. Для валідації безпеки протестуйте репрезентативну звичайну дію та репрезентативну заборонену дію із сервісним акаунтом, який ви створили в лабораторії, бо оновлення, що випадково розширює права, може бути небезпечнішим за те, що блокує забагато.

Валідація admission має також включати негативний тест. Перелік конфігурацій webhook’ів підтверджує, що шлях admission зареєстрований, а проба Pod Security Admission у просторі імен restricted підтверджує, що примусове виконання все ще відхиляє небезпечні робочі навантаження. Не запускайте руйнівні проби проти робочих навантажень у продакшені, але доведіть, що шлях політики все ще існує. Успішне оновлення має зберегти і здатність запускати допустимі робочі навантаження, і здатність блокувати недопустимі.

Terminal window
# Question: "Upgrade cluster to version that fixes CVE-2024-XXXX"
# 1. Research CVE (exam may provide info)
# 2. Find fixed version
kubectl version
# 3. Plan upgrade
sudo kubeadm upgrade plan | grep -E "v1\.[0-9]+\.[0-9]+"
# 4. Execute upgrade to fixed version

Зробіть паузу й передбачте: після оновлення з 1.34 до 1.35 ви запускаєте kube-bench і бачите три нові провалені перевірки, яких не було до оновлення. Це може статися, бо змінився профіль бенчмарку, змінилася цільова версія або значення за замовчуванням перейшло з прийнятного на небажане, тож ваше завдання — зіставити кожен висновок із настановою бенчмарку, перш ніж вирішувати, чи це справжня регресія.

Керований Kubernetes змінює механіку, а не міркування про безпеку. EKS, GKE та AKS відокремлюють оновлення площини управління від оновлення нод, і кожен провайдер контролює, які версії доступні в певний момент. Вам усе одно потрібно ідентифікувати виправлену версію, зрозуміти вікна обслуговування провайдера, оновити ноди або образи нод, перевірити поведінку політик та стежити за сумісністю додатків, як-от CNI, CSI, DNS, ingress та webhook’и admission.

+-------------------------------------------------------------+
| MANAGED K8S UPGRADE CONSIDERATIONS |
+-------------------------------------------------------------+
| |
| EKS (AWS): |
| - Control plane upgraded separately from nodes |
| - Managed node groups can auto-upgrade |
| - eksctl upgrade cluster |
| |
| GKE (GCP): |
| - Release channels for automatic upgrades |
| - Maintenance windows for planned upgrades |
| - gcloud container clusters upgrade |
| |
| AKS (Azure): |
| - Auto-upgrade channel available |
| - Node image upgrades separate from control plane upgrade |
| - az aks upgrade |
| |
| Security note: |
| Managed Kubernetes may lag the newest upstream release |
| for stability, so check provider patch timelines |
| |
+-------------------------------------------------------------+

У керованих кластерах поширена помилка безпеки — припускати, що провайдер оновив усе, що має значення. Провайдер зазвичай володіє розміщеною площиною управління, але ви все одно володієте робочими навантаженнями, конфігурацією політик, додатками, пулами нод, webhook’ами admission та багатьма прив’язками ідентичності. Тому безпечний план оновлення керованого кластера включає і команди провайдера, і валідацію на рівні кластера, бо межа спільної відповідальності не зникає під час реагування на CVE.

Час оновлення в керованому середовищі слід порівнювати з вікном вразливості з бюлетеня. Провайдери іноді затримують новий апстрім-патч, поки перевіряють інтеграцію зі своєю платформою, і ця затримка може бути розумною з міркувань стабільності. Ваше завдання — знати опублікований графік патчів провайдера, застосувати компенсувальні засоби контролю, якщо виправлена збірка площини управління ще недоступна, та уникати обіцянок, що апстрім-виправлена версія встановлена, перш ніж провайдер її фактично запропонує.

Оновлення образів нод у керованих службах легко проґавити, бо вони можуть використовувати окрему команду, операцію над пулом або канал автооновлення. Банер версії площини управління може виглядати заспокійливо, тоді як старі ноди досі несуть вразливі kubelet’и, середовища виконання контейнерів або пакети операційної системи. Тому валідація після оновлення має включати версії образів нод, версії kubelet, здоров’я daemonset’ів, статус CNI, поведінку DNS та admission робочих навантажень, а не лише статус площини управління в консолі провайдера.

Патерни та антипатерни

Розділ «Патерни та антипатерни»

Якісна практика оновлення відтворювана, бо реагування на безпекову подію не має залежати від того, хто опинився на чергуванні. Наведені нижче патерни написані як операційні звички, а не гасла. Кожен із них створює свідчення, які може перевірити інший інженер, а кожен антипатерн називає спокусливий короткий шлях, що зазвичай спричиняє збій.

ПатернКоли його застосовуватиЧому він працюєМіркування щодо масштабування
Зіставлення бюлетеня з ціллюБудь-яке оновлення, спричинене CVEВоно з’єднує уражені й виправлені версії з точним релізом.Тримайте зіставлення в записі про зміну для аудиторського перегляду.
Відрепетируваний runbook для kubeadmСамокеровані кластериВоно перетворює обслуговування продакшену на відому послідовність.Оновлюйте його для кожної мінорної версії, бо вилучення накопичуються.
Дошка розбіжності версійОновлення з кількома нодами чи адміністраторамиВоно показує, які тимчасові стани допустимі.Оновлюйте після кожного кроку з площиною управління та пулом нод.
Набір проб безпеки після оновленняКожне оновленняВоно перевіряє поведінку RBAC, admission, політик та бенчмарків.Автоматизуйте проби, але зберігайте людський перегляд для несподіваних відмінностей.
АнтипатернЩо йде не такКраща альтернатива
Оновлення до найновішого видимого пакетаПакет може не бути виправленою чи підтримуваною ціллю, яку ви мали на меті.Обирайте ціль із бюлетенів, приміток до релізів та політики розбіжності.
Трактування оновлень нод як необов’язковихKubelet’и та образи нод можуть зберігати вразливу поведінку.Плануйте оновлення пулів нод та перевіряйте версію кожного kubelet.
Ігнорування трафіку до застарілих APIВилучені API можуть зламати контролери під час чи після оновлення.Перевіряйте маніфести та метрики API-сервера перед обслуговуванням.
Довіра одному зеленому дашбордуПеревірки здоров’я можуть пропустити послаблену авторизацію чи поведінку admission.Запускайте явні проби безпеки після оновлення.

Ці патерни додають невелику дозу церемонії, але церемонія окуповується, коли патч терміновий. Короткий runbook, дошка розбіжності версій та чеклист валідації значно дешевші за імпровізацію під публічним бюлетенем. Антипатерни привабливі, бо економлять хвилини на початку; вони часто коштують годин, коли кластер входить у непідтримуваний стан або повертається зі слабшою позицією безпеки.

Фреймворк для ухвалення рішень

Розділ «Фреймворк для ухвалення рішень»

Використовуйте наведений нижче фреймворк, коли оновлення Kubernetes спричинене безпекою. Починайте з бюлетеня, а не з менеджера пакетів. Ідентифікуйте уражений компонент, уражені версії, виправлені версії, умови експлуатації та чи підтримується ще ваша поточна мінорна версія. Потім вирішіть, чи є патч у межах тієї самої мінорної версії, одно-крокове мінорне оновлення або контрольований провайдером шлях оновлення найменшою відповідальною зміною, що приземляється на виправлену версію.

+-------------------------------------------------------------+
| SECURITY UPGRADE DECISION FLOW |
+-------------------------------------------------------------+
| 1. Does the advisory affect a component you run? |
| +-- No: document why, then monitor. |
| +-- Yes: continue. |
| |
| 2. Is your current minor still supported? |
| +-- Yes: prefer the fixed patch in the same minor. |
| +-- No: plan a supported minor upgrade path. |
| |
| 3. Is exploitation reachable in your environment? |
| +-- Yes: shorten approval and maintenance windows. |
| +-- No: apply mitigations, but still schedule patching. |
| |
| 4. Are deprecations, add-ons, and skew clean? |
| +-- Yes: execute runbook and validate. |
| +-- No: fix blockers or create a staged upgrade. |
+-------------------------------------------------------------+

Фреймворк навмисно відокремлює терміновість від необачності. Досяжна критична вразливість може виправдати аварійне затвердження зміни, але вона не виправдовує пропуску резервного копіювання, перевірок розбіжності версій або валідації безпеки після оновлення. І навпаки, бюлетень із низькою експлуатованістю може дозволити звичайне вікно обслуговування, але він усе одно потребує цільової версії та власника, бо непідтримувані кластери не стають безпечнішими від очікування.

Для самокерованих кластерів на kubeadm рішення часто залежить від того, чи можете ви безпечно перемістити компоненти площини управління та ноди в межах потрібного вікна. Для керованих кластерів рішення залежить від доступності версій у провайдера, вікон обслуговування, поведінки пулів нод та сумісності додатків. В обох випадках остаточне рішення слід записати як операційне речення: «оновити кластер X із версії A до виправленої версії B до дати C, використовуючи пом’якшення D до завершення, та перевірити перевірками E».

  • Підтримка патчів Kubernetes охоплює недавні мінорні релізи. Точні дати рухаються разом із календарем релізів, тож планування безпеки має посилатися на офіційну сторінку патч-релізів, а не на скопійовану вікі-таблицю.

  • Патч у межах тієї самої мінорної версії може бути оновленням безпеки. Перехід із 1.34.1 на 1.34.4 може закрити CVE з меншою поведінковою зміною, ніж стрибок одразу на нову мінорну версію.

  • Політика розбіжності версій — це засіб контролю безпеки. Непідтримувані комбінації компонентів ускладнюють розуміння того, чи справді виправлення захищає той шлях, який вас турбує.

  • Керовані кластери все одно потребують роботи з нодами та додатками. Патч розміщеної площини управління не оновлює автоматично кожен kubelet, образ ноди, CNI, драйвер CSI чи webhook admission.

Збої оновлень безпеки зазвичай походять від браку свідчень, а не браку команд. Послідовність команд легко запам’ятати, але рішення навколо неї потребує доказу того, що кластер уражений, ціль виправлена, а отримана система все ще примусово виконує ті самі засоби контролю.

ПомилкаЧому вона трапляєтьсяЯк її виправити
Пропуск версій без перевірки політики підтримкиКоманди плутають терміновість із дозволом ігнорувати протестовані шляхи оновлення.Оновлюйте по одній мінорній версії за раз, якщо офіційна настанова не каже інакше.
Оновлення робочих вузлів перед площиною управлінняАвтоматизація нод працює незалежно від обслуговування площини управління.Спершу оновіть API-сервер, потім контролери, потім kubelet’и в межах політики розбіжності.
Неперевірка застарівань перед зміноюОператори зосереджуються на CVE й забувають про сумісність API робочих навантажень.Перегляньте примітки до релізу, проскануйте маніфести та огляньте метрики застарілих API.
Відсутність резервної копії etcd перед kubeadm applyКластер виглядає здоровим, тож резервна копія здається затримкою.Зробіть та протестуйте знімок etcd перед зміною самокерованих площин управління.
Запуск непідтримуваних версій поза продакшеномКластери розробки вважають одноразовими, навіть коли вони містять облікові дані.Тримайте всі під’єднані середовища в межах вікна підтримки патчів.
Довіра збоям бенчмарку без тріажуНові версії бенчмарку можуть додавати чи переінтерпретовувати перевірки.Порівняйте старий і новий профілі бенчмарку, потім класифікуйте кожен висновок.
Припущення, що оновлення керованої служби завершує роботуОбов’язки провайдера та клієнта розмиваються під час інцидентів.Перевіряйте пули нод, додатки, робочі навантаження, політики та прив’язки ідентичності окремо.

Перевірка засвоєння

Розділ «Перевірка засвоєння»

Розбіжність версій — це формальна межа навколо цієї роботи із сумісністю. API-сервер має бути найновішим компонентом Kubernetes у кластері; controller-manager та scheduler йдуть слідом упритул; kubelet’и можуть відставати в межах задокументованої політики, але вони не повинні випереджати API-сервер.

Перш ніж продовжити, поясніть, чому kubelet на 1.32 може лишатися допустимим на API-сервері 1.35, тоді як controller-manager на 1.33 — ні. Сильна відповідь називає окремі правила розбіжності для kubelet’ів порівняно з компонентами площини управління та цитує допуск у три мінорні версії для kubelet 1.25+.

Питання 1: Ваша команда безпеки отримує CVE-бюлетень про вразливість виходу з контейнера, що зачіпає Kubernetes з 1.33 по 1.34.3. Продакшен працює на 1.34.1, а бюлетень каже, що виправлення є в 1.34.4 та 1.35.0. Що ви порекомендуєте під час короткого заморожування змін? Порекомендуйте аварійний патч у межах тієї самої мінорної версії до 1.34.4, якщо організація може його затвердити, бо він досягає виправленої версії з меншою поведінковою зміною, ніж мінорне оновлення. Заморожування змін не слід трактувати як абсолютне, коли бюлетень описує досяжний вихід із контейнера. Проміжні пом'якшення, як-от обмежений Pod Security Admission, seccomp, AppArmor, посилений RBAC та вимкнення привілейованих робочих навантажень, можуть зменшити вразливість, але вони не замінюють пропатченого бінарного файлу. Стрибок на 1.35.0 може бути розумним пізніше, але найменша безпечна ціль — це виправлений патч 1.34.
Питання 2: Після оновлення `kubectl get nodes` показує API-сервер на 1.35, а один kubelet робочого вузла все ще на 1.33. Кластер виглядає здоровим. Що ви перевіряєте, перш ніж вважати оновлення завершеним? Спершу перевірте політику розбіжності версій Kubernetes, щоб підтвердити, чи перебуває цей kubelet ще в межах підтримуваного зв'язку з API-сервером. Навіть якщо розбіжність технічно дозволена, пропущений робочий вузол усе одно може не мати виправлень безпеки, включених до цільового оновлення, тож вам слід оглянути бюлетень та план оновлення, перш ніж приймати цей стан. Перевірте стан пакетів пулу нод, образ ноди, оновлення середовища виконання та розміщення робочих навантажень на цій ноді. Оновлення не завершене, поки кожна намічена версія kubelet не врахована, а мета безпеки не задоволена.
Питання 3: Колега хоче негайно запустити `kubeadm upgrade apply v1.35.0`, бо `kubeadm upgrade plan` показує цю версію як доступну. Яких критичних для безпеки кроків бракує? Бракує свідчень, що роблять оновлення захищеним: зіставлення бюлетеня з ціллю, резервної копії etcd, перегляду застарілих API, плану розбіжності версій та валідації після оновлення. `kubeadm upgrade plan` доводить, що kubeadm може бачити шлях оновлення, але не доводить, що ціль виправляє CVE, яка спричинила зміну. Команді також потрібно запланувати оновлення пакетів kubelet та kubectl, бо оновлення лише площини управління може залишити вразливі ноди позаду. Після кроку apply перевірки RBAC, admission, NetworkPolicy та бенчмарку мають довести, що кластер усе ще примусово виконує засоби контролю безпеки.
Питання 4: Розробка працює на 1.33, тоді як staging і продакшен — на 1.34. Організація цілиться далі на 1.35, а розробники доводять, що непідтримуваний кластер розробки є прийнятним. Як ви оцінюєте цей ризик? Непідтримуваний кластер розробки усе одно є проблемою безпеки, якщо він під'єднаний до реєстрів, систем CI, хмарних акаунтів, провайдерів ідентичності або даних, подібних до робочих. Атакувальники часто виграють від слабших суміжних середовищ, бо ці середовища містять облікові дані та шляхи розгортання. Краща стратегія — оновити розробку першою, використати її як середовище для репетиції, потім перемістити staging та продакшен із засвоєними уроками. Трактування розробки як одноразової безпечне лише тоді, коли вона справді ізольована, а більшість реальних кластерів розробки — ні.
Питання 5: Після переходу з 1.34 на 1.35 kube-bench повідомляє про три нові провалені перевірки, але жоден маніфест не змінився. Як ви діагностуєте результат? Порівняйте версію бенчмарку, цільовий профіль бенчмарку та цільову версію Kubernetes, перш ніж припускати, що оновлення спричинило регресію. Нова провалена перевірка може відображати нову рекомендацію або суворішу інтерпретацію, а не змінений прапорець площини управління. Потім огляньте фактичний засіб контролю, на який посилається кожен висновок, як-от прапорці API-сервера, конфігурацію kubelet чи права доступу до файлів. Виправте справжні регресії, задокументуйте прийняті винятки та уникайте відкату, якщо висновок не зіставляється із серйозним операційним чи безпековим збоєм.
Питання 6: Ваш провайдер керованого кластера пропатчив розміщену площину управління, але пули нод лишаються на попередній мінорній версії, а додаток CNI відстає. Яке ваше рішення про завершення? Не вважайте оновлення безпеки завершеним лише тому, що розміщена площина управління перемістилася. Керовані служби розділяють відповідальність, тож провайдер може володіти API-сервером, тоді як ви все ще володієте пулами нод, додатками, політикою робочих навантажень та валідацією. Перевірте політику версій провайдера, заплануйте оновлення пулів нод, перегляньте сумісність додатків та запустіть ті самі перевірки RBAC, admission, NetworkPolicy та робочих навантажень, які ви запустили б на самокерованому кластері. Рішення про завершення має ґрунтуватися на повній поверхні атаки, а не на одному рядку статусу провайдера.

Сценарій вправи: ви готуєте репетицію оновлення Kubernetes із фокусом на безпеці в лабораторному кластері. Мета — не виконати реальне оновлення площини управління з цієї сторінки, бо лабораторні середовища різняться. Мета — потренувати збір свідчень, перевірки сумісності та валідацію після оновлення, які роблять реальне оновлення достатньо безпечним для виконання під тиском.

Почніть зі створення ізольованого простору імен, щоб репетиція не заважала наявним робочим навантаженням. Ви розгорнете невелике робоче навантаження з явними налаштуваннями контексту безпеки, зафіксуєте його стан, огляньте версії кластера й нод, перевірите підказки про застарілі API, а потім запустите ті самі проби безпеки, які запустили б після реального оновлення. Тримайте виводи разом, бо цінність вправи — у порівнянні наміру до зміни з поведінкою після неї.

  • Оцініть змодельований CVE-бюлетень та оберіть виправлену патч-ціль 1.35 для нотаток репетиції.
  • Перевірте ноди кластера, образи площини управління, версії kubelet та свідчення API робочих навантажень перед зміною.
  • Впровадьте передзапусковий запис у стилі kubeadm із резервною копією, цільовою версією та припущеннями про розбіжність версій.
  • Діагностуйте свідчення RBAC, admission, NetworkPolicy та бенчмарку щодо регресій після оновлення.
  • Спроєктуйте коротку нотатку про завершення для керованого Kubernetes, що відокремлює роботу провайдера від роботи власника кластера.
Настанова з розв'язання для завдання 1 Напишіть одне речення, що називає уражену версію, виправлену версію та терміновість. Хороша відповідь виглядає так: «Кластер 1.34.1 уражений змодельованим бюлетенем, виправлені 1.34.4 та 1.35.0, а репетиція цілитиметься на найменшу виправлену версію, якщо вікно підтримки не вимагатиме переходу на 1.35». Важлива частина в тому, що ціль походить із бюлетеня, а не з вгадування найновішого видимого пакета.

Спершу створіть ізольований простір імен для репетиції. Простір імен дає кожній наступній команді невелику, оборотну ціль, що робить вправу безпечною для повторення.

Terminal window
kubectl create namespace upgrade-test

Далі розгорніть тестове робоче навантаження, налаштоване зі строгими контекстами безпеки. Цей Под дозволяє вам перевірити, що налаштування на кшталт runAsNonRoot та readOnlyRootFilesystem лишаються присутніми й видимими після оновлення чи змодельованого проходу валідації.

Terminal window
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: security-test
namespace: upgrade-test
labels:
app: security-test
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: busybox
command: ["sleep", "3600"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
EOF

Перш ніж розпочинати будь-яке оновлення, зафіксуйте поточний стан робочого навантаження. Якщо пізніший крок валідації зазнає невдачі, цей файл дає вам конкретну точку порівняння замість покладання на пам’ять.

Terminal window
echo "=== Pre-Upgrade State Capture ==="
kubectl get all -n upgrade-test -o yaml > /tmp/pre-upgrade-backup.yaml
echo "Backup saved to /tmp/pre-upgrade-backup.yaml"

Перевірте поточні версії компонентів вашого кластера. Вам потрібно точно знати, які версії працюють, щоб визначити, чи вразливі вони до відомих CVE та чи допустимий цільовий шлях оновлення.

Terminal window
echo "=== Current Versions ==="
kubectl version
echo "=== Node Versions ==="
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}: {.status.nodeInfo.kubeletVersion}{"\n"}{end}'

Застарілі API — це головне джерело невдалих оновлень. Перевірте свої маніфести та запущені ресурси, щоб підтвердити, що об’єкти в цій невеликій репетиції використовують версії API, які лишаються дійсними для цільового релізу.

Terminal window
echo "=== Checking Deprecated APIs ==="
# Look for deprecated API versions in our resources
kubectl get pod security-test -n upgrade-test -o yaml | grep "apiVersion"

Зробіть паузу й вирішіть: якщо ви знаходите застарілий API у використанні під час репетиції, виправте його перед оновленням продакшену, а не трактуйте попередження як пункт прибирання після оновлення. Попередження означає, що майбутній API-сервер може відхилити об’єкт, а обслуговування продакшену — невдалий час для вивчення замінної схеми.

Після оновлення або змодельованої точки валідації переконайтеся, що рольовий контроль доступу (RBAC) усе ще поводиться так, як очікувалося. Оновлення ніколи не повинне мовчки розширювати права, і воно не повинне несподівано прибирати права, потрібні звичайним робочим навантаженням.

Terminal window
echo "=== RBAC Verification ==="
kubectl create serviceaccount probe-sa -n upgrade-test --dry-run=client -o yaml | kubectl apply -f -
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-lister
namespace: upgrade-test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-lister-binding
namespace: upgrade-test
subjects:
- kind: ServiceAccount
name: probe-sa
namespace: upgrade-test
roleRef:
kind: Role
name: pod-lister
apiGroup: rbac.authorization.k8s.io
EOF
kubectl auth can-i list pods -n upgrade-test --as=system:serviceaccount:upgrade-test:probe-sa
# Expect: yes
kubectl auth can-i create pods -n upgrade-test --as=system:serviceaccount:upgrade-test:probe-sa
# Expect: no

Підтвердьте, що контексти безпеки, застосовані до вашого робочого навантаження, усе ще присутні. Це не доводить, що кожен засіб контролю середовища виконання примусово виконується, але це ловить випадковий дрейф маніфесту й дає вам відправну точку для перевірок admission та політики середовища виконання.

Terminal window
echo "=== Security Context Verification ==="
kubectl get pod security-test -n upgrade-test -o jsonpath='{.spec.securityContext}' && echo ""
kubectl get pod security-test -n upgrade-test -o jsonpath='{.spec.containers[0].securityContext}' && echo ""

Переконайтеся, що Под лишається в робочому стані й не був заблокований новим контролером admission, політикою образів чи проблемою планування на ноді. Якщо цей простий Под не може запуститися, дослідіть це, перш ніж валідувати складніші робочі навантаження.

Terminal window
echo "=== Pod Status ==="
kubectl get pod security-test -n upgrade-test

У реальному сценарії ви запустили б інструмент бенчмаркінгу безпеки на кшталт kube-bench проти ваших нод, щоб переконатися, що нові компоненти налаштовані безпечно. Ця лабораторія тримає команду як явне нагадування, бо виконання бенчмарку залежить від лабораторного середовища.

Terminal window
echo "=== Security Benchmark Check ==="
echo "On control plane, would run: ./kube-bench run --targets=master"
echo "On worker nodes, would run: ./kube-bench run --targets=node"

Переконайтеся, що ресурси NetworkPolicy усе ще приймаються API-сервером та обирають Под репетиції. Пам’ятайте, що прийняття на рівні API — це не те саме, що примусове виконання, тож реальна валідація в продакшені має також тестувати поведінку трафіку через CNI.

Terminal window
echo "=== Testing NetworkPolicy Support ==="
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-policy
namespace: upgrade-test
spec:
podSelector:
matchLabels:
app: security-test
policyTypes:
- Ingress
- Egress
EOF
kubectl get networkpolicy test-policy -n upgrade-test -o jsonpath='{.spec.podSelector.matchLabels.app}{"\n"}'
# Expect: security-test (policy selects the rehearsal pod)

Нарешті, приберіть тестове середовище. Прибирання має видалити і об’єкти кластера, і локальні файли свідчень, які більше не потрібні.

Terminal window
echo "=== Cleanup ==="
kubectl delete namespace upgrade-test
rm -f /tmp/pre-upgrade-backup.yaml
echo ""
echo "=== Exercise Complete ==="
echo "Key upgrade security checks performed:"
echo "1. Backed up cluster state"
echo "2. Checked versions for consistency"
echo "3. Verified no deprecated APIs in use"
echo "4. Confirmed RBAC working"
echo "5. Validated security contexts"
echo "6. Verified NetworkPolicy support"
Настанова з розв'язання для завдань 2–5 Для завдання аудиту збережіть вивід `kubectl version`, версії kubelet нод, версії образів площини управління та перевірку застарілих API. Для завдання передзапуску запишіть в одній короткій нотатці цільову версію, розташування резервної копії, очікувану тимчасову розбіжність та тригер відкату. Для завдання діагностики порівняйте RBAC, контекст безпеки, статус Пода, прийняття NetworkPolicy та висновки бенчмарку з очікуваним результатом. Для завдання керованого кластера вкажіть, якими пунктами володіє провайдер, яку роботу з нодами й додатками володієте ви та які перевірки доводять, що весь кластер справді пропатчений.

Критерії успіху:

  • Простір імен та Под репетиції створено успішно.
  • Резервну копію робочого навантаження до оновлення записано в /tmp/pre-upgrade-backup.yaml.
  • Версії кластера й нод зафіксовано та переглянуто проти змодельованої цілі.
  • Свідчення про застарілі API перевірено перед рішенням про оновлення.
  • Перевірки RBAC, контексту безпеки, статусу Пода, заповнювача бенчмарку та NetworkPolicy завершено.
  • Простір імен та тимчасовий файл резервної копії прибрано.

Модуль 2.5: Обмеження доступу до API — мережеві та автентифікаційні обмеження для API-сервера.