Кластер Kubernetes складається з панелі управління та набору робочих машин, які називаються вузлами, що запускають контейнеризовані застосунки. Кожен кластер потребує принаймні одного робочого вузла для запуску Podʼів.
Робочі вузли розміщують Podʼи, які є компонентами робочого навантаження застосунку. Панель управління керує робочими вузлами та Podʼами в кластері. У промислових середовищах панель управління зазвичай працює на кількох компʼютерах, а кластер зазвичай має кілька вузлів, забезпечуючи відмовостійкість та високу доступність.
Цей документ описує різні компоненти, які вам потрібні для повноцінного та працездатного кластера Kubernetes.
Схема 1. Компоненти кластера Kubernetes.
Про цю архітектуру
На схемі 1 представлено приклад еталонної архітектури кластера Kubernetes. Фактичний розподіл компонентів може змінюватися залежно від конкретних налаштувань кластера та вимог.
На схемі на кожному вузлі запущено компонент kube-proxy. Вам потрібен компонент мережевого проксі на кожному вузлі, щоб гарантувати, що Service API та повʼязана з ним поведінка доступні у вашій кластерній мережі. Втім, деякі мережеві втулки надають власну, сторонню реалізацію проксі-сервера. Коли ви використовуєте такий мережевий втулок, вузлу не потрібно запускати kube-proxy.
Компоненти панелі управління
Компоненти панелі управління приймають глобальні рішення щодо кластера (наприклад, планування), а також виявляють та реагують на події в кластері (наприклад, запуск нового Podʼа, коли умова поля replicas в Deployment не виконується).
Компоненти панелі управління можуть запускатися на будь-якій машині у кластері. Однак для спрощення скрипти налаштування зазвичай запускають всі компоненти панелі управління на одній машині та не запускають контейнерів користувача на цій машині. Див. Створення кластерів з високою доступністю за допомогою kubeadm для прикладу налаштування панелі управління, яка працює на кількох машинах.
kube-apiserver
API-сервер є компонентом панелі управління Kubernetes, який надає доступ до API Kubernetes. API-сервер є фронтендом для панелі управління Kubernetes.
Основна реалізація API-сервера Kubernetes — kube-apiserver. kube-apiserver спроєктований для горизонтального масштабування, тобто масштабується за допомогою розгортання додаткових екземплярів. Ви можете запустити кілька екземплярів kube-apiserver та балансувати трафік між ними.
etcd
Узгоджене та високодоступне сховище ключ-значення, яке використовується як сховище Kubernetes для всіх даних кластера.
Якщо ваш кластер Kubernetes використовує etcd як основне сховище, переконайтеся, що у вас є план резервного копіювання даних.
Ви можете знайти докладну інформацію про etcd в офіційній документації.
kube-scheduler
Компонент панелі управління, що відстежує щойно створені Podʼи, які ще не розподілені по вузлах, і обирає вузол, на якому вони працюватимуть.
Під час вибору вузла враховуються такі фактори: індивідуальна і колективна потреба в ресурсах, обмеження за апаратним/програмним забезпеченням і політиками, характеристики affinity та anti-affinity, локальність даних, взаємний вплив робочих навантажень і граничні терміни виконання.
kube-controller-manager
Компонент панелі управління, який запускає процеси контролерів.
За логікою, кожен контролер є окремим процесом. Однак для спрощення їх збирають в один бінарний файл і запускають як єдиний процес.
Існує багато різних типів контролерів. Деякі приклади:
Контролер вузлів: відповідає за виявлення та реагування, коли вузли виходять з ладу.
Контролер Job: відстежує обʼєкти Job, що представляють одноразові завдання, а потім створює Podʼи для виконання цих завдань до завершення.
Контролер EndpointSlice: заповнює обʼєкти EndpointSlice (для забезпечення звʼязку між Services та Podʼами).
Контролер ServiceAccount: створює стандартні ServiceAccounts для нових просторів імен.
Наведений вище список не є вичерпним.
cloud-controller-manager
Компонент панелі управління Kubernetes, що вбудовує логіку управління, специфічну для хмари. Cloud controller manager дозволяє звʼязувати ваш кластер з API хмарного провайдера та відокремлює компоненти, що взаємодіють із хмарною платформою, від компонентів, які взаємодіють тільки з вашим кластером.
cloud-controller-manager запускає лише ті контролери, які специфічні для вашого хмарного провайдера. Якщо ви використовуєте Kubernetes у себе на власних потужностях або в навчальному середовищі всередині вашого ПК, кластер не матиме cloud-controller-manager.
Як і kube-controller-manager, cloud-controller-manager обʼєднує кілька логічно незалежних циклів управління в один бінарний файл, який ви запускаєте як один процес. Ви можете масштабувати його горизонтально (запускати більше однієї копії) для покращення продуктивності або для підвищення стійкості до збоїв.
Такі контролери можуть мати залежності від хмарного провайдера:
Контролер вузлів: перевіряє у хмарного провайдера, чи було видалено вузол у хмарі після того, як він перестав відповідати.
Контролер маршрутів: налаштовує маршрути в основній хмарній інфраструктурі.
Контролер Service: створює, оновлює та видаляє балансувальники навантаження хмарного провайдера.
Компоненти вузлів
Компоненти вузлів працюють на кожному вузлі, підтримуючи роботу Podʼів та забезпечуючи середовище виконання Kubernetes.
kubelet
Агент, запущений на кожному вузлі кластера. Забезпечує запуск і роботу контейнерів в Podʼах.
kubelet використовує специфікації PodSpecs, які надаються за допомогою різних механізмів, і забезпечує працездатність і справність усіх контейнерів, що описані у PodSpecs. kubelet керує лише тими контейнерами, що були створені Kubernetes.
kube-proxy (опційно)
kube-proxy є мережевим проксі, що запущений на кожному вузлі кластера і реалізує частину концепції Kubernetes Service.
kube-proxy підтримує мережеві правила на вузлах. Ці правила дозволяють мережеву взаємодію з вашими Podʼами з мережевих сеансів усередині чи поза межами кластера.
kube-proxy використовує шар фільтрації пакетів операційної системи, за його наявності. В іншому випадку kube-proxy скеровує трафік самостійно.
Якщо ви використовуєте мережевий втулок, який самостійно реалізує пересилання пакетів для Services та надає еквівалентну поведінку kube-proxy, то вам не потрібно запускати kube-proxy на вузлах вашого кластера.
Середовище виконання контейнерів
Основний компонент, який дозволяє Kubernetes ефективно запускати контейнери. Він відповідає за керування виконанням і життєвим циклом контейнерів у середовищі Kubernetes.
Надбудови використовують ресурси Kubernetes (DaemonSet, Deployment тощо) для реалізації функцій кластера. Оскільки вони надають функції на рівні кластера, ресурси, що належать надбудовам, розміщуються в просторі імен kube-system.
Вибрані надбудови описані нижче; для розширеного списку доступних надбудов дивіться Надбудови.
DNS
Хоча інші надбудови не є строго необхідними, всі кластери Kubernetes повинні мати кластерний DNS, оскільки багато прикладів залежать від нього.
Кластерний DNS — це DNS-сервер, який доповнює інші DNS-сервери у вашому середовищі та обслуговує DNS-записи для сервісів Kubernetes.
Контейнери, запущені за допомогою Kubernetes, автоматично включають цей DNS-сервер до своїх DNS-пошуків.
Вебінтерфейс (Dashboard)
Dashboard — це універсальний вебінтерфейс для кластерів Kubernetes. Він дозволяє користувачам керувати застосунками, що працюють у кластері, та усувати проблеми з ними, а також із самим кластером.
Моніторинг ресурсів контейнерів
Моніторинг ресурсів контейнерів записує загальні метрики часових рядів для контейнерів у центральну базу даних та надає інтерфейс для перегляду цих даних.
Логування на рівні кластера
Механізм логування на рівні кластера відповідає за збереження логів контейнерів в центральному сховищі логів з інтерфейсом пошуку та перегляду.
Мережеві втулки
Мережеві втулки — це програмні компоненти, які реалізують специфікацію інтерфейсу мережі контейнерів (CNI). Вони відповідають за виділення IP-адрес Podʼам та забезпечення їх звʼязку між собою у кластері.
Варіації архітектури
Хоча основні компоненти Kubernetes залишаються незмінними, способи їх розгортання та управління можуть відрізнятися. Розуміння цих варіацій є ключовим для проєктування та підтримки кластерів Kubernetes, що відповідають специфічним операційним потребам.
Варіанти розгортання панелі управління
Компоненти панелі управління можна розгортати кількома способами:
Традиційне розгортання
Компоненти панелі управління працюють безпосередньо на виділених машинах або віртуальних машинах, часто керованих як служби systemd.
Статичні Podʼи
Компоненти панелі управління розгортаються як статичні Podʼи, керовані kubelet на певних вузлах. Це поширений підхід, який використовують такі інструменти, як kubeadm.
Самостійне розміщення
Панель управління працює як Podʼи у самому кластері Kubernetes, якими керують Deployments та StatefulSets або інші примітиви Kubernetes.
Керовані сервіси Kubernetes
Хмарні провайдери часто абстрагують панель управління, керуючи її компонентами як частиною послуги, яку вони надають.
Розміщення робочих навантажень
Розміщення робочих навантажень, включаючи компоненти панелі управління, може варіюватися залежно від розміру кластера, вимог до продуктивності та операційних політик:
У менших або розробницьких кластерах компоненти панелі управління та робочі навантаження користувачів можуть працювати на тих самих вузлах.
Великі промислові кластери часто виділяють певні вузли для компонентів панелі управління, відокремлюючи їх від робочих навантажень користувачів.
Деякі організації запускають критично важливі надбудови або інструменти моніторингу на вузлах панелі управління.
Інструменти управління кластером
Такі інструменти, як kubeadm, kops та Kubespray, пропонують різні підходи до розгортання та управління кластерами, кожен з яких має свій метод розташування та управління компонентами.
Налаштування та розширюваність
Архітектура Kubernetes дозволяє значне налаштування:
Власні планувальники можна розгортати паралельно зі стандартним планувальником Kubernetes або замінювати його повністю.
API-сервери можна розширювати за допомогою CustomResourceDefinitions та API Aggregation.
Хмарні провайдери можуть глибоко інтегруватися з Kubernetes за допомогою cloud-controller-manager.
Гнучкість архітектури Kubernetes дозволяє організаціям налаштовувати свої кластери відповідно до специфічних потреб, балансуючи фактори, такі як операційна складність, продуктивність та управлінські витрати.
Kubernetes виконує ваше робоче навантаження шляхом розміщення контейнерів у Podʼах для запуску на вузлах. Вузол може бути віртуальною або фізичною машиною, залежно від кластера. Кожен вузол керується панеллю управління і містить необхідні служби для запуску Podʼів.
Зазвичай в кластері є кілька вузлів; в умовах навчання чи обмежених ресурсів може бути всього один вузол.
Є два основних способи додавання вузлів до API-сервера:
kubelet на вузлі самостійно реєструється в панелі управління.
Ви (або інший користувач) вручну додаєте обʼєкт Node.
Після створення обʼєкта Node або якщо kubelet на вузлі самостійно реєструється, панель управління перевіряє, чи новий обʼєкт Node є дійсним. Наприклад, якщо ви спробуєте створити вузол із таким JSON-маніфестом:
Kubernetes внутрішньо створює обʼєкт Node (його представлення). Kubernetes перевіряє, чи kubelet, що відповідає полю metadata.name обʼєкта Node, зареєструвався в API-сервері. Якщо вузол є справним (тобто всі необхідні служби працюють), то він може запускати Podʼи. В іншому випадку цей вузол ігнорується для будь-якої діяльності кластера, доки він не стане справним.
Примітка:
Kubernetes зберігає обʼєкт для недійсного вузла та продовжує перевіряти, чи він стає справним.
Ви або контролер маєте явно видалити обʼєкт Node, щоб припинити цю перевірку його справності.
Назва ідентифікує Node. Два вузли не можуть мати однакову назву одночасно. Kubernetes також припускає, що ресурс із такою самою назвою — це той самий обʼєкт. У випадку вузла припускається неявно, що екземпляр, який використовує ту саму назву, матиме той самий стан (наприклад, мережеві налаштування, вміст кореневого диска) та атрибути, такі як мітки вузла. Це може призвести до невідповідностей, якщо екземпляр був змінений без зміни його назви. Якщо вузол потрібно замінити або значно оновити, наявний обʼєкт Node потрібно спочатку видалити з API-сервера, а після оновлення додати знову.
Самореєстрація вузлів
Коли прапорець kubelet --register-node є true (типово), kubelet спробує зареєструвати себе в API-сервері. Це бажаний підхід, який використовується більшістю дистрибутивів.
Для самореєстрації kubelet запускається з такими параметрами:
--kubeconfig — Шлях до облікових даних для автентифікації на API-сервері.
--cloud-provider — Як взаємодіяти з хмарним провайдером для отримання метаданих про себе.
--register-node — Автоматична реєстрація в API-сервері.
Нічого не відбувається, якщо register-node є false.
--node-ip — Необовʼязковий розділений комами список IP-адрес вузла. Можна вказати лише одну адресу для кожного сімейства адрес. Наприклад, у кластері з одним стеком IPv4 ви встановлюєте це значення як IPv4-адресу, яку повинен використовувати kubelet для вузла. Див. Налаштування подвійного стека IPv4/IPv6 для отримання відомостей про запуск кластера з подвійним стеком.
Якщо ви не вказали цей аргумент, kubelet використовує стандартну IPv4-адресу вузла, якщо є; якщо у вузла немає адреси IPv4, тоді kubelet використовує стандартну IPv6-адресу вузла.
Як зазначено в розділі Унікальність назв вузлів, коли потрібно оновити конфігурацію вузла, доброю практикою є повторна реєстрація вузла в API-сервері. Наприклад, якщо kubelet перезапускається з новим набором --node-labels, але використовується та сама назва Node, зміна не набуде чинності, оскільки мітки встановлюються (або змінюються) лише під час реєстрації вузла в API-сервері.
Podʼи, вже заплановані на Node, можуть погано поводитися або викликати проблеми, якщо конфігурація Node буде змінена при перезапуску kubelet. Наприклад, вже запущений Pod може виявитися несумісним із новими мітками, призначеними вузлу, тоді як інші Podʼи, несумісні з цим Podʼом, будуть заплановані на основі цієї нової мітки. Перереєстрація вузла гарантує, що вузол буде очищено від усіх Podʼів і їх буде належним чином переплановано.
Ручне адміністрування вузлів
Ви можете створювати та змінювати обʼєкти Node за допомогою kubectl.
Коли ви хочете створювати обʼєкти Node вручну, встановіть прапорець kubelet --register-node=false.
Ви можете змінювати обʼєкти Node незалежно від налаштувань --register-node. Наприклад, ви можете встановлювати мітки на наявному вузлі або позначати його як непридатний для планування.
Ви можете встановити необовʼязкові ролі для вузлів, додавши одну або кілька міток node-role.kubernetes.io/<role>: <role> до вузла, де символи <role> обмежуються правилами синтаксису для міток.
Kubernetes ігнорує значення мітки для ролей вузлів; за домовленістю, ви можете задати для неї той самий рядок, який ви використовували для ролі вузла у ключі мітки.
Ви можете використовувати мітки на вузлах разом із селекторами вузлів на Podʼах для управління плануванням. Наприклад, ви можете дозволити Podʼу запускатися лише на підмножині доступних вузлів.
Позначення вузла як непридатного для планування перешкоджає планувальнику розміщувати нові Podʼи на цьому вузлі, але не впливає на наявні Podʼи на вузлі. Це корисно як підготовчий крок перед перезавантаженням вузла чи іншим обслуговуванням.
Щоб позначити вузол як непридатний для планування, виконайте:
Podʼи, які є частиною DaemonSet, толерують запуск на вузлі, непридатному для планування. Зазвичай DaemonSets надають служби, локальні для вузла, які мають працювати на ньому, навіть якщо він очищується від робочих навантажень.
Обʼєкти Lease у просторі іменkube-node-lease. Кожен вузол має асоційований обʼєкт Lease.
Контролер вузлів
Контролер вузлів — це компонент панелі управління Kubernetes, який керує різними аспектами роботи вузлів.
У контролера вузлів є кілька ролей у житті вузла. По-перше, він призначає блок CIDR вузлу при його реєстрації (якщо призначення CIDR увімкнено).
По-друге, він підтримує актуальність внутрішнього списку вузлів контролера зі списком доступних машин хмарного провайдера. Під час роботи в хмарному середовищі, коли вузол несправний, контролер вузлів запитує в хмарного провайдера, чи ще доступна віртуальна машина (VM) для цього вузла. Якщо ні, контролер вузлів видаляє вузол зі свого списку вузлів.
По-третє, він відстежує справність вузлів. Контролер вузлів відповідає за:
У випадку, якщо вузол стає недоступним, оновлення умови Ready у полі .status вузла. У цьому випадку контролер вузлів встановлює умову Ready в Unknown.
Якщо вузол залишається недоступним: запуск виселення, ініційоване API для всіх Podʼів на недосяжному вузлі. Типово контролер вузлів чекає 5 хвилин між позначенням вузла як Unknown та поданням першого запиту на виселення.
Стандартно контролер вузлів перевіряє стан кожного вузла кожні 5 секунд. Цей період можна налаштувати за допомогою прапорця --node-monitor-period у компоненті kube-controller-manager.
Обмеження швидкості виселення
У більшості випадків контролер вузлів обмежує швидкість виселення до --node-eviction-rate (типово 0,1) за секунду, тобто він не виселятиме Podʼи більш ніж з 1 вузла за 10 секунд.
Поведінка виселення змінюється, коли вузол у певній зоні доступності стає несправним. Контролер вузлів перевіряє, яка частина вузлів в зоні є несправною (умова Ready — Unknown або False) у той самий час:
Якщо частка несправних вузлів становить принаймні --unhealthy-zone-threshold (типово 0,55), тоді швидкість виселення зменшується.
Якщо кластер малий (тобто має не більше ніж --large-cluster-size-threshold вузлів — типово 50), тоді виселення припиняється.
В іншому випадку швидкість виселення зменшується до --secondary-node-eviction-rate (типово 0,01) в секунду.
Причина того, що ці політики реалізовані окремо для кожної зони доступності, полягає в тому, що одна зона може втратити зʼєднання з панеллю управління, тоді як інші залишаються підключеними. Якщо ваш кластер не охоплює кілька зон доступності хмарного провайдера, тоді механізм виселення не враховує недоступність окремих зон.
Однією з ключових причин розподілу вузлів за зонами доступності є можливість переміщення навантаження в справні зони, коли одна ціла зона виходить з ладу. Таким чином, якщо всі вузли в зоні несправні, контролер вузлів виселяє Podʼи зі звичайною швидкістю --node-eviction-rate. Крайній випадок — коли всі зони повністю несправні (жоден вузол в кластері не є справним). У такому випадку контролер вузлів припускає, що існує якась проблема зі зʼєднанням між панеллю управління та вузлами, і не виконує жодних виселень. (Якщо стався збій і деякі вузли відновились, контролер вузлів виселяє Podʼи з решти вузлів, які є несправними або недосяжними).
Контролер вузлів також відповідає за виселення Podʼів, що працюють на вузлах із taints NoExecute, якщо ці Podʼи не толерують цей taint. Контролер вузлів також додає taints, відповідні проблемам вузла, таким як недосяжність вузла або неготовність вузла. Це означає, що планувальник не розміщуватиме Podʼи на несправних вузлах.
Відстеження місткості ресурсів
Обʼєкти Node відстежують інформацію про ресурсну місткість вузла: наприклад, кількість доступної памʼяті та кількість процесорів. Вузли, які реєструються самостійно, повідомляють про свою місткість під час реєстрації. Якщо ви додаєте вузол вручну, то вам потрібно встановити інформацію про місткість вузла при його додаванні.
Планувальник Kubernetes забезпечує, що на вузлі є достатньо ресурсів для всіх Podʼів. Планувальник перевіряє, що сума запитів контейнерів на вузлі не перевищує місткості вузла. Ця сума запитів включає всі контейнери, керовані kubelet, але не включає жодні контейнери, запущені безпосередньо середовищем виконання контейнерів, а також виключає будь-які процеси, які працюють поза контролем kubelet.
This is a stable feature in Kubernetes, and has been since the 1.27 release. You can no longer toggle this feature (the associated feature gate has been removed).
Якщо ви увімкнули функціональну можливість TopologyManager, то kubelet може використовувати підказки топології при прийнятті рішень щодо призначення ресурсів. Див. Керування політиками топології на вузлі для отримання додаткової інформації.
Цей документ описує шляхи звʼязку між API-сервером та кластером Kubernetes. Мета — надати користувачам можливість налаштувати своє встановлення та посилити конфігурацію мережі так, щоб кластер можна було запускати в ненадійній мережі (або на повністю публічних IP-адресах у хмарному середовищі).
Звʼязок вузла з панеллю управління
У Kubernetes існує шаблон API "hub-and-spoke". Усе використання API з боку вузлів (або Podʼів, які на них працюють) завершується на API-сервері. Інші компоненти панелі управління не призначені для надання віддалених сервісів. API-сервер налаштований для прослуховування віддалених підключень на захищеному порту HTTPS (зазвичай 443) з однією або кількома увімкненими формами автентифікації клієнта. Рекомендується увімкнути одну чи кілька форм авторизації, особливо якщо анонімні запити або токени службового облікового запису дозволені.
Вузли повинні бути забезпечені публічним кореневим сертифікатом для кластера, щоб вони могли безпечно підключатися до API-сервера разом з дійсними обліковими даними клієнта. Добрий підхід — надавати kubelet облікові дані клієнта у формі клієнтського сертифіката. Див. завантаження TLS kubelet для автоматичного надання клієнтських сертифікатів kubelet.
Podʼи, які бажають підʼєднатися до API-сервера, можуть це зробити безпечно, використовуючи службовий обліковий запис (service account), так що Kubernetes автоматично вставлятиме публічний кореневий сертифікат та дійсний токен на предʼявника у Pod під час його створення. Service kubernetes (у просторі імен default) налаштована з віртуальною IP-адресою, яка перенаправляється (через kube-proxy) на точку доступу HTTPS на API-сервері.
Компоненти панелі управління також взаємодіють з API-сервером через захищений порт.
У результаті типовий режим роботи для зʼєднань від вузлів та Podʼів, що працюють на вузлах, до панелі управління є захищеним і може працювати через ненадійні та/або публічні мережі.
Звʼязок панелі управління з вузлом
Існують два основних шляхи звʼязку панелі управління (API-сервера) з вузлами. Перший — від API-сервера до процесу kubelet, який працює на кожному вузлі в кластері. Другий — від API-сервера до будь-якого вузла, Podʼа чи Service через проксі API-сервера.
Звʼязок API-сервера з kubelet
Зʼєднання від API-сервера до kubelet використовуються для:
Отримання логів для Podʼів.
Приєднання (зазвичай через kubectl) до запущених Podʼів.
Забезпечення функціональності перенаправлення портів kubelet.
Ці зʼєднання завершуються на точці доступу HTTPS kubelet. Стандартно API-сервер не перевіряє сертифікат обслуговування kubelet, що робить зʼєднання вразливим до атаки "людина посередині" і небезпечним для використання через ненадійні та/або публічні мережі.
Щоб перевірити це зʼєднання, використовуйте прапорець --kubelet-certificate-authority, щоб надати API-серверу пакет кореневих сертифікатів для перевірки сертифіката обслуговування kubelet.
Якщо це неможливо, скористайтеся тунелюванням SSH між API-сервером та kubelet, якщо необхідно, щоб уникнути підключення через ненадійну або публічну мережу.
Зʼєднання від API-сервера до вузла, Podʼа чи Service типово використовують прості HTTP-зʼєднання і, отже, не автентифікуються й не шифруються. Їх можна використовувати через захищене зʼєднання HTTPS, підставивши https: перед назвою вузла, Podʼа чи Service в URL API, але вони не будуть перевіряти сертифікат, наданий точкою доступу HTTPS, та не надаватимуть облікові дані клієнта. Таким чином, хоча зʼєднання буде зашифрованим, воно не гарантує цілісності. Ці зʼєднання поки не є безпечними для використання через ненадійні або публічні мережі.
Тунелі SSH
Kubernetes підтримує тунелі SSH, щоб захистити канали звʼязку від панелі управління до вузлів. У цій конфігурації API-сервер ініціює тунель SSH до кожного вузла в кластері (підключаючись до SSH-сервера, який прослуховує порт 22) і передає весь трафік, призначений для kubelet, вузла, Podʼа чи Service, через тунель. Цей тунель гарантує, що трафік не виходить за межі мережі, в якій працюють вузли.
Примітка:
Тунелі SSH наразі застарілі, тому не варто їх використовувати, якщо ви не знаєте, що робите. Служба Konnectivity — це заміна для цього каналу звʼязку.
Служба Konnectivity
СТАН ФУНКЦІОНАЛУ:Beta since Kubernetes v1.18
Як заміна тунелям SSH, служба Konnectivity надає проксі на рівні TCP для звʼязку панелі управління з кластером. Служба Konnectivity складається з двох частин: сервера Konnectivity в мережі панелі управління та агентів Konnectivity в мережі вузлів. Агенти Konnectivity ініціюють зʼєднання з сервером Konnectivity та підтримують мережеві підключення. Після ввімкнення служби Konnectivity весь трафік від панелі управління до вузлів проходить через ці зʼєднання.
Для налаштування служби Konnectivity у своєму кластері скористайтеся завданням служби Konnectivity.
У робототехніці та автоматизації control loop (цикл управління) — це нескінченний цикл, який регулює стан системи.
Ось один приклад циклу управління — термостат у кімнаті.
Коли ви встановлюєте температуру, це означає, що ви повідомляєте термостату про бажаний стан. Фактична температура в кімнаті — це поточний стан. Термостат діє так, щоб наблизити поточний стан до бажаного стану, вмикаючи чи вимикаючи відповідне обладнання.
У Kubernetes контролери — це цикли управління, які спостерігають за станом вашого кластера, а потім вносять або запитують зміни там, де це необхідно. Кожен контролер намагається наблизити поточний стан кластера до бажаного.
Шаблон контролера
Контролер відстежує принаймні один тип ресурсу Kubernetes. Ці обʼєкти мають поле spec, яке представляє бажаний стан. Контролер(и) для цього ресурсу відповідають за наближення поточного стану до цього бажаного стану.
Контролер може виконати дію самостійно; частіше в Kubernetes контролер надсилає повідомлення API-серверу, які мають корисні побічні ефекти. Нижче ви побачите приклади цього.
Управління через API-сервер
Контролер Job — це приклад вбудованого контролера Kubernetes. Вбудовані контролери управляють станом, взаємодіючи з API-сервером кластера.
Job — це ресурс Kubernetes, який запускає Pod або, можливо, кілька Podʼів, щоб виконати завдання і потім зупинитися.
(Після процесу планування, обʼєкти Pod стають частиною бажаного стану для kubelet).
Коли контролер Job бачить нове завдання, він переконується, що десь у вашому кластері kubeletʼи на наборі вузлів виконують потрібну кількість Podʼів, щоб виконати роботу. Контролер Job не запускає жодних Podʼів або контейнерів самостійно. Замість цього контролер Job вказує API-серверу створити або видалити Podʼи. Інші компоненти панелі управління реагують на нову інформацію (є нові Podʼи для планування та запуску), і зрештою робота виконується.
Після того, як ви створите нове завдання, бажаний стан полягає в тому, щоб це завдання було завершене. Контролер Job наближає поточний стан цього завдання до бажаного: створює Podʼи, які виконують потрібну вам роботу, щоб завдання було ближчим до завершення.
Контролери також оновлюють обʼєкти, які їх конфігурують. Наприклад, коли роботу для завдання виконано, контролер Job оновлює обʼєкт Job, щоб позначити його як Finished.
(Це трошки схоже на те, як деякі термостати вимикають світловий індикатор, щоб сповістити, що ваша кімната тепер має температуру, яку ви встановили).
Безпосереднє управління
На відміну від Job, деякі контролери повинні вносити зміни за межами вашого кластера.
Наприклад, якщо ви використовуєте цикл управління, щоб переконатися, що у вашому кластері є достатньо вузлів, то цей контролер потребує чогось поза поточним кластером, щоб налаштовувати нові вузли за потреби.
Контролери, які взаємодіють із зовнішнім станом, отримують свій бажаний стан від API-сервера, а потім безпосередньо взаємодіють із зовнішньою системою для наближення поточного стану до бажаного.
(Фактично є контролер, що горизонтально масштабує вузли у вашому кластері).
Важливим тут є те, що контролер вносить певні зміни, щоб досягти вашого бажаного стану, а потім повідомляє поточний стан назад на API-сервер вашого кластера. Інші цикли управління можуть спостерігати за цими даними та виконувати свої дії.
У прикладі з термостатом, якщо в кімнаті дуже холодно, то інший контролер може також увімкнути обігрівач для захисту від морозу. У кластерах Kubernetes панель управління опосередковано працює з інструментами управління IP-адресами, сервісами сховища, API хмарних провайдерів та іншими сервісами, розширюючи Kubernetes для цього.
Бажаний стан порівняно з поточним
Kubernetes дивиться на системи з погляду cloud-native і здатний обробляти постійні зміни.
Ваш кластер може змінюватися в будь-який момент під час роботи, а цикли управління автоматично виправляють збої. Це означає, що, потенційно, ваш кластер ніколи не досягає стабільного стану.
Поки контролери вашого кластера працюють і можуть робити корисні зміни, не має значення, чи є загальний стан сталим, чи ні.
Дизайн
Як принцип дизайну, Kubernetes використовує багато контролерів, кожен з яких керує певним аспектом стану кластера. Найчастіше певний цикл управління (контролер) використовує один вид ресурсу як свій бажаний стан і має інший вид ресурсу, яким він управляє, щоб досягти цього бажаного стану. Наприклад, контролер для ресурсу Job відстежує обʼєкти Job (для виявлення нової роботи) та обʼєкти Pod (для запуску обʼєктів Job і подальшого визначення, коли робота закінчена). У цьому випадку щось інше створює обʼєкти Job, тоді як контролер Job створює Podʼи.
Корисно мати прості контролери, а не один великий набір взаємозалежних циклів управління. Контролери можуть виходити з ладу, тому Kubernetes спроєктовано з урахуванням цього.
Примітка:
Може існувати кілька контролерів, які створюють або оновлюють один і той самий вид обʼєктів. За лаштунками контролери Kubernetes переконуються, що вони звертають увагу лише на ресурси, повʼязані з ресурсом, який ними керує.
Наприклад, ви можете мати ресурси Deployments і Jobs; обидва ці ресурси створюють Podʼи. Контролер Job не видаляє Podʼи, які створив ваш Deployment, оскільки є інформація (мітки), яку контролери можуть використовувати для розрізнення цих Podʼів.
Способи запуску контролерів
Kubernetes постачається з набором вбудованих контролерів, які працюють всередині kube-controller-manager. Ці вбудовані контролери забезпечують важливі основні функції.
Контролер Deployment та контролер Job — це приклади контролерів, які постачаються разом з Kubernetes (контролери, вбудовані в систему). Kubernetes дозволяє вам запускати стійку панель управління, так що, якщо будь-який з вбудованих контролерів не зможе виконувати завдання, інша частина панелі управління візьме на себе його обовʼязки.
Ви можете знайти контролери, які працюють поза панеллю управління, для розширення Kubernetes. Або, якщо ви хочете, ви можете написати новий контролер самостійно. Ви можете запустити свій власний контролер як набір Podʼів, або поза межами Kubernetes. Те, що найкраще підходить, буде залежати від того, що саме робить цей контролер.
Часто в розподілених системах є потреба в лізингу, який забезпечує механізм блокування спільних ресурсів та координації дій між членами групи. У Kubernetes концепцію лізингу представлено обʼєктами Lease в групі APIcoordination.k8s.io, які використовуються для критичних для системи можливостей, таких як пульс вузлів (heartbeats) та вибір лідера на рівні компонентів.
Пульс вузлів
Kubernetes використовує API Lease для передачі пульсу (heartbeats) kubelet вузла на API-сервер Kubernetes. Для кожного Node існує обʼєкт Lease з відповідною назвою в просторі імен kube-node-lease. Під капотом кожен сигнал пульсу kubelet — це запит на оновлення цього обʼєкта Lease, який оновлює поле spec.renewTime для обʼєкта Lease. Панель управління Kubernetes використовує відмітку часу цього поля для визначення доступності цього вузла.
Kubernetes також використовує лізинги, щоб у будь-який момент часу працював лише один екземпляр компонента. Це використовується компонентами панелі управління, такими як kube-controller-manager та kube-scheduler в конфігураціях з високою доступністю, де лише один екземпляр компонента має активно працювати, тоді як інші екземпляри перебувають в режимі очікування.
Прочитайте координовані вибори лідера, щоб дізнатися про те, як Kubernetes використовує Lease API для вибору екземпляра компонента, який буде виконувати роль лідера.
Звільнення блокування вибору лідера kube controller manager під час виходу
СТАН ФУНКЦІОНАЛУ:Alpha since Kubernetes v1.36; (стандартно вимкнено)
Коли функціональна можливість ControllerManagerReleaseLeaderElectionLockOnExit увімкнена, kube-controller-manager активно звільняє блокування вибору лідера під час переходу лідерства, замість того, щоб чекати закінчення терміну дії блокування. Це дозволяє швидше обрати нового лідера, зменшуючи затримку переходу лідерства.
Ідентичність API-сервера
СТАН ФУНКЦІОНАЛУ:Beta since Kubernetes v1.26; (стандартно увімкнено)
Починаючи з Kubernetes v1.26, кожен kube-apiserver використовує API Lease для публікації своєї ідентичності для решти системи. Хоча це само по собі не є особливо корисним, це забезпечує механізм для клієнтів для визначення кількості екземплярів kube-apiserver, які керують панеллю управління Kubernetes. Наявність лізингів kube-apiserver уможливлює майбутні функції, які можуть потребувати координації між усіма kube-apiserver.
Ви можете перевірити лізинги, якими володіє кожен kube-apiserver, перевіривши обʼєкти лізингу в просторі імен kube-system з назвою apiserver-<sha256-hash>. Або ви можете використовувати селектор міток apiserver.kubernetes.io/identity=kube-apiserver:
kubectl -n kube-system get lease -l apiserver.kubernetes.io/identity=kube-apiserver
NAME HOLDER AGE
apiserver-07a5ea9b9b072c4a5f3d1c3702 apiserver-07a5ea9b9b072c4a5f3d1c3702_0c8914f7-0f35-440e-8676-7844977d3a05 5m33s
apiserver-7be9e061c59d368b3ddaf1376e apiserver-7be9e061c59d368b3ddaf1376e_84f2a85d-37c1-4b14-b6b9-603e62e4896f 4m23s
apiserver-1dfef752bcb36637d2763d1868 apiserver-1dfef752bcb36637d2763d1868_c5ffa286-8a9a-45d4-91e7-61118ed58d2e 4m43s
Хеш SHA256, який використовується в назвах лізингу, базується на імені хоста операційної системи, яке бачить цей API-сервер. Кожен kube-apiserver повинен бути налаштований на використання імені хоста, унікального в межах кластера. Нові екземпляри kube-apiserver, які використовують те саме імʼя хоста, перехоплюють наявні лізинги за допомогою нового ідентифікатора власника, замість того щоб створювати нові обʼєкти лізингу. Ви можете перевірити імʼя хоста, яке використовує kube-apiserver, перевіривши значення мітки kubernetes.io/hostname:
kubectl -n kube-system get lease apiserver-07a5ea9b9b072c4a5f3d1c3702 -o yaml
Прострочені лізинги від kube-apiserver, які вже не існують, прибираються новими kube-apiserver через 1 годину.
Ви можете вимкнути лізинги ідентичності API-сервера, вимкнувши функціональну можливістьAPIServerIdentity.
Робочі навантаження
Ваші власні робочі навантаження можуть визначити своє власне використання лізингів. Наприклад, ви можете запускати власний контролер, де основний член чи лідер виконує операції, яких не виконують інші члени групи. Ви визначаєте лізинг так, щоб репліки контролера могли вибирати чи обирати лідера, використовуючи API Kubernetes для координації. Якщо ви використовуєте лізинг, гарною практикою є визначати назву лізингу, яка очевидно повʼязана з продуктом чи компонентом. Наприклад, якщо у вас є компонент з назвою Example Foo, використовуйте лізинг з назвою example-foo.
Якщо оператор кластера чи інший кінцевий користувач може розгортати кілька екземплярів компонента, виберіть префікс назви та механізм (такий як хеш від назви Deployment), щоб уникнути конфліктів назв лізингів.
Ви можете використовувати інший підхід, якщо він досягає того самого результату: відсутність конфліктів між різними програмними продуктами.
5 - Cloud Controller Manager
СТАН ФУНКЦІОНАЛУ:Beta since Kubernetes v1.11
Технології хмарної інфраструктури дозволяють вам запускати Kubernetes в публічних, приватних та гібридних хмарах. Kubernetes вірить в автоматизовану інфраструктуру, що працює за допомогою API без тісного звʼязку між компонентами.
Cloud-controller-manager — це компонент панелі управління Kubernetes, що вбудовує логіку управління, специфічну для хмари. Cloud controller manager дозволяє звʼязувати ваш кластер з API хмарного провайдера та відокремлює компоненти, що взаємодіють із хмарною платформою, від компонентів, які взаємодіють тільки з вашим кластером.
Відокремлюючи логіку сумісності між Kubernetes і базовою хмарною інфраструктурою, компонент cloud-controller-manager дає змогу хмарним провайдерам випускати функції з іншою швидкістю порівняно з основним проєктом Kubernetes.
Cloud-controller-manager структурується за допомогою механізму втулків, який дозволяє різним хмарним провайдерам інтегрувати свої платформи з Kubernetes.
Дизайн
Cloud-controller-manager працює в панелі управління як реплікований набір процесів (зазвичай це контейнери в Podʼах). Кожен cloud-controller-manager реалізує кілька контролерів в одному процесі.
Примітка:
Ви також можете запускати cloud-controller-manager як надбудову Kubernetes, а не як частину панелі управління.
Функції cloud-controller-manager
Контролери всередині cloud-controller-manager включають:
Контролер вузлів
Контролер вузлів відповідає за оновлення обʼєктів Node при створенні нових серверів у вашій хмарній інфраструктурі. Контролер вузлів отримує інформацію про хости, які працюють у вашому обліковому записі у хмарному провайдері. Контролер вузлів виконує такі функції:
Оновлення обʼєкта Node відповідним унікальним ідентифікатором сервера, отриманим з API хмарного провайдера.
Додавання до обʼєкта Node анотацій та міток з інформацією, специфічною для хмари, такою як регіон, в якому розгорнуто вузол, та доступні йому ресурси (CPU, памʼять тощо).
Отримання імені хоста та мережевих адрес.
Перевірка стану вузла. Якщо вузол перестає відповідати, цей контролер перевіряє за допомогою API вашого хмарного провайдера, чи сервер був деактивований / видалений / завершений. Якщо вузол був видалений з хмари, контролер видаляє обʼєкт Node з вашого кластера Kubernetes.
Деякі реалізації від хмарних провайдерів розділяють це на контролер вузлів та окремий контролер життєвого циклу вузла.
Контролер маршрутів
Контролер маршрутів відповідає за налаштування маршрутів у хмарі відповідним чином, щоб контейнери на різних вузлах вашого кластера Kubernetes могли взаємодіяти один з одним.
Залежно від хмарного провайдера контролер маршрутів може також виділяти блоки IP-адрес для мережі Podʼів.
Контролер Service
Services інтегруються з компонентами хмарної інфраструктури, такими як керовані балансувальники навантаження, IP-адреси, мережеве фільтрування пакетів та перевірка стану цільового обʼєкта. Контролер Service взаємодіє з API вашого хмарного провайдера для налаштування балансувальників навантаження та інших компонентів інфраструктури, коли ви оголошуєте ресурс Service, який їх потребує.
Авторизація
У цьому розділі розглядаються доступи, яких потребує cloud-controller-manager для різних обʼєктів API для виконання своїх операцій.
Контролер вузлів
Контролер вузлів працює тільки з обʼєктами Node. Він вимагає повного доступу для читання та модифікації обʼєктів Node.
v1/Node:
get
list
create
update
patch
watch
delete
Контролер маршрутів
Контролер маршрутів відстежує створення обʼєктів Node та налаштовує маршрути відповідним чином. Він вимагає доступу Get до обʼєктів Node.
v1/Node:
get
Контролер Service
Контролер Service відстежує події create, update та delete обʼєктів Service, а потім відповідним чином налаштовує балансувальники навантаження для цих Services.
Для доступу до Service потрібні доступи list та watch. Для оновлення Service потрібен доступ patch та update до підресурсу status.
v1/Service:
list
get
watch
patch
update
Інші
Реалізація ядра cloud-controller-manager потребує доступу до створення Event, а для забезпечення безпечної роботи — доступу до створення ServiceAccounts.
v1/Event:
create
patch
update
v1/ServiceAccount:
create
RBAC ClusterRole для cloud-controller-manager виглядає так:
Хочете знати, як реалізувати свій власний cloud-controller-manager або розширити наявний проєкт?
Cloud-controller-manager використовує інтерфейси Go, зокрема, інтерфейс CloudProvider, визначений у cloud.go з kubernetes/cloud-provider, щоб дозволити підключати реалізації для будь-якої хмари.
Реалізація загальних контролерів, виділених у цьому документі (Node, Route та Service), а також допоміжний каркас разом із загальним інтерфейсом хмарного провайдера є частиною ядра Kubernetes. Реалізації, специфічні для хмарних провайдерів, знаходяться поза ядром Kubernetes і реалізують інтерфейс CloudProvider.
У Linux контрольні групи обмежують ресурси, які виділяються процесам.
kubelet та середовище виконання контейнерів повинні співпрацювати з cgroups для забезпечення управління ресурсами для Podʼів та контейнерів, що включає запити та обмеження CPU/памʼяті для контейнеризованих робочих навантажень.
Є дві версії cgroups у Linux: cgroup v1 і cgroup v2. cgroup v2 — це нове покоління API cgroup в Linux.
Що таке cgroup v2?
СТАН ФУНКЦІОНАЛУ:GA since Kubernetes v1.25
cgroup v2 — це наступне покоління API Linux cgroup. cgroup v2 надає єдину систему управління з розширеними можливостями управління ресурсами.
cgroup v2 пропонує кілька поліпшень порівняно з cgroup v1, таких як:
Розширене управління розподілом ресурсів та ізоляція між різними ресурсами
Обʼєднаний облік різних типів виділення памʼяті (мережева памʼять, памʼять ядра і т. д.)
Облік відкладених змін ресурсів, таких як запис кешу сторінок
Деякі можливості Kubernetes використовують виключно cgroup v2 для поліпшення управління ресурсами та ізоляцією. Наприклад, можливість MemoryQoS покращує якість обслуговування памʼяті та покладається на примітиви cgroup v2.
Використання cgroup v2
Рекомендованим способом використання cgroup v2 є використання дистрибутиву Linux, який стандартно вмикає та використовує cgroup v2.
kubelet та середовище виконання контейнерів налаштовані на використання cgroup-драйвера systemd
Підтримка cgroup v2 дистрибутивами Linux
Для ознайомлення зі списком дистрибутивів Linux, які використовують cgroup v2, див. документацію cgroup v2
Container Optimized OS (з версії M97)
Ubuntu (з версії 21.10, рекомендовано 22.04+)
Debian GNU/Linux (з Debian 11 bullseye)
Fedora (з версії 31)
Arch Linux (з квітня 2021)
RHEL та схожі дистрибутиви (з версії 9)
Щоб перевірити, чи ваш дистрибутив використовує cgroup v2, див. документацію вашого дистрибутиву або скористайтеся інструкціями в Визначенні версії cgroup на вузлах Linux.
Також можна увімкнути cgroup v2 вручну у вашому дистрибутиві Linux, змінивши аргументи завантаження ядра. Якщо ваш дистрибутив використовує GRUB, systemd.unified_cgroup_hierarchy=1 повинно бути додано в GRUB_CMDLINE_LINUX в /etc/default/grub, а потім виконайте sudo update-grub. Однак рекомендованим підходом є використання дистрибутиву, який вже стандартно вмикає cgroup v2.
Міграція на cgroup v2
Щоб перейти на cgroup v2, переконайтеся, що ваша система відповідає вимогам, а потім оновіть її до версії ядра, яка стандартно вмикає cgroup v2.
Kubelet автоматично виявляє, що ОС працює з cgroup v2 і діє відповідно без додаткової конфігурації.
При переході на cgroup v2 не повинно бути помітної різниці в використанні, якщо користувачі не звертаються безпосередньо до файлової системи cgroup чи на вузлі, чи зсередини контейнерів.
cgroup v2 використовує інший API, ніж cgroup v1, тому, якщо є застосунки, які безпосередньо отримують доступ до файлової системи cgroup, вони повинні бути оновлені до новіших версій, які підтримують cgroup v2. Наприклад:
Деякі сторонні агенти моніторингу та безпеки можуть залежати від файлової системи cgroup. Оновіть ці агенти до версій, які підтримують cgroup v2.
Якщо ви використовуєте cAdvisor як окремий DaemonSet для моніторингу Podʼів та контейнерів, оновіть його до v0.43.0 чи новіше.
Якщо ви розгортаєте Java-застосунки, віддайте перевагу використанню версій, які повністю підтримують cgroup v2:
Якщо ви використовуєте пакунок uber-go/automaxprocs, переконайтеся, що ви використовуєте версію v1.5.1 чи вище.
Якщо ви розгортаєте застосунки на Node.js, віддавайте перевагу версіям, які виявляють обмеження памʼяті cgroup v2. Node.js читає обмеження памʼяті cgroup v2 (через libuv) починаючи з Node.js v20.3.0. Лінія випуску v18 ненадійно виявляє обмеження памʼяті cgroup v2. Версії без цієї підтримки можуть читати загальну памʼять хоста замість обмеження, застосованого до Podʼа, що може призвести до неправильного розміру heap і завершення роботи через нестачу памʼяті (OOM). У версіях, яких це стосується, встановіть розмір heap явно, наприклад за допомогою прапорця --max-old-space-size.
Визначення версії cgroup на вузлах Linux
Версія cgroup залежить від використаного дистрибутиву Linux та версії cgroup, налаштованої в ОС. Щоб перевірити, яка версія cgroup використовується вашим дистрибутивом, виконайте команду stat -fc %T /sys/fs/cgroup/ на вузлі:
stat -fc %T /sys/fs/cgroup/
Для cgroup v2 вивід — cgroup2fs.
Для cgroup v1 вивід — tmpfs.
Визнання застарілим cgroup v1
СТАН ФУНКЦІОНАЛУ:Deprecated since Kubernetes v1.35
Kubelet більше стандартно не буде запускатися на вузлі cgroup v1. Щоб вимкнути це налаштування, адміністратор кластера повинен встановити failCgroupV1 на false у файлі конфігурації kubelet.
Kubernetes розроблено з можливостями самозцілення, які допомагають підтримувати працездатність і доступність робочих навантажень. Він автоматично замінює збійні контейнери, переплановує робочі навантаження, коли вузли стають недоступними, і забезпечує підтримку бажаного стану системи.
Можливості самозцілення
Перезапуски на рівні контейнера: Якщо контейнер всередині Podʼа виходить з ладу, Kubernetes перезапускає його відповідно до restartPolicy.
Заміна реплік: Якщо Pod у Deployment або StatefulSet виходить з ладу, Kubernetes створює Pod на заміну, щоб підтримувати вказану кількість реплік. Якщо Pod, який є частиною DaemonSet, виходить з ладу, панель управління створює Pod на заміну для запуску на тому самому вузлі.
Відновлення постійного сховища: Якщо на вузлі працює Pod з підключеним PersistentVolume (PV), і вузол виходить з ладу, Kubernetes може повторно приєднати том до нового Podʼа на іншому вузлі.
Балансування навантаження для Services: Якщо Pod, що перебуває за Service, виходить з ладу, Kubernetes автоматично видаляє його з точок доступу Service, щоб направляти трафік лише до справних Podʼів.
Ось деякі з ключових компонентів, які забезпечують самозцілення Kubernetes:
kubelet: Забезпечує роботу контейнерів і перезапускає ті, які вийшли з ладу.
Контролери Deployment (через ReplicaSet), ReplicaSet, StatefulSet і DaemonSet: Підтримують бажану кількість реплік Podʼа.
Контролер PersistentVolume: Керує приєднанням і відʼєднанням томів для робочих навантажень зі збереженням стану.
Візьміть до уваги
Збої в сховищі: Якщо постійний том стає недоступним, можуть знадобитися кроки відновлення.
Помилки застосунків: Kubernetes може перезапускати контейнери, але проблеми в самому застосунку необхідно вирішувати окремо.
Читайте про автомасштабування вузлів. Автомасштабування вузлів також забезпечує автоматичне відновлення, якщо вузли виходять з ладу у вашому кластері.
8 - Збір сміття
Збір сміття — це загальний термін для різних механізмів, які Kubernetes використовує для очищення ресурсів кластера. Це дозволяє очищати ресурси, такі як:
Багато обʼєктів в Kubernetes повʼязані один з одним через посилання на власника. Посилання на власника повідомляють панелі управління, які обʼєкти залежать від інших. Kubernetes використовує посилання на власника для того, щоб дати панелі управління та іншим клієнтам API можливість очищати повʼязані ресурси перед видаленням обʼєкта. У більшості випадків Kubernetes автоматично керує посиланнями на власника.
Власність відрізняється від механізму міток та селекторів, які також використовують деякі ресурси. Наприклад, розгляньте Service, який створює обʼєкти EndpointSlice. Service використовує мітки, щоб дозволити панелі управління визначити, які обʼєкти EndpointSlice використовуються для цього Service. Окрім міток, кожен обʼєкт EndpointSlice, керований від імені Service, має посилання на власника. Посилання на власника допомагають різним частинам Kubernetes уникати втручання в обʼєкти, якими вони не керують.
Примітка:
Посилання на власника з іншого простору імен заборонені за задумом. Залежні обʼєкти в межах простору імен можуть вказувати власників рівня кластера або рівня простору імен. Власник рівня простору імен повинен існувати в тому самому просторі імен, що й залежний обʼєкт. Якщо це не так, таке посилання вважається відсутнім, і залежний обʼєкт підлягає видаленню після перевірки відсутності всіх власників.
Залежні обʼєкти рівня кластера можуть вказувати тільки власників рівня кластера. У v1.20+, якщо залежний обʼєкт рівня кластера вказує як власника тип у межах простору імен, вважається, що він має нерозвʼязне посилання на власника, і його не можна прибрати збором сміття.
У v1.20+, якщо збирач сміття виявляє недійсний ownerReference між просторами імен або залежний обʼєкт рівня кластера з ownerReference, що посилається на тип у межах простору імен, повідомляється про попереджувальну подію з причиною OwnerRefInvalidNamespace та involvedObject недійсного залежного елемента. Ви можете перевірити наявність такого роду подій, запустивши kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace.
Каскадне видалення
Kubernetes перевіряє та видаляє обʼєкти, які більше не мають посилань на власника, наприклад, Podʼи, які залишилися після видалення ReplicaSet. Коли ви видаляєте обʼєкт, ви можете контролювати, чи автоматично видаляє Kubernetes залежні обʼєкти, у процесі, що називається каскадним видаленням. Існують два типи каскадного видалення:
Каскадне видалення на передньому плані
Каскадне видалення у фоні
Ви також можете контролювати те, як і коли збір сміття видаляє ресурси, які мають посилання на власника, використовуючи завершувачі Kubernetes.
Каскадне видалення на передньому плані
У каскадному видаленні на передньому плані обʼєкт власника, який видаляється, спочатку потрапляє в стан deletion in progress. У цьому стані з обʼєктом власника відбувається таке:
API-сервер Kubernetes встановлює поле metadata.deletionTimestamp обʼєкта на час, коли обʼєкт був позначений на видалення.
API-сервер Kubernetes також встановлює поле metadata.finalizers в foregroundDeletion.
Обʼєкт залишається видимим через API Kubernetes, поки не буде завершений процес видалення.
Після того як обʼєкт власника потрапляє в стан deletion in progress, контролер видаляє відомі йому залежні обʼєкти. Після видалення всіх відомих залежних обʼєктів контролер видаляє обʼєкт власника. На цьому етапі обʼєкт більше не є видимим в API Kubernetes.
Під час каскадного видалення на передньому плані єдиними залежними обʼєктами, які блокують видалення власника, є ті, що мають поле ownerReference.blockOwnerDeletion=true і перебувають у кеші контролера збору сміття. Кеш контролера збору сміття може не містити обʼєкти, тип ресурсу яких не вдається успішно перелічити / відстежувати, або обʼєкти, які створюються одночасно з видаленням обʼєкта-власника. Дивіться Використання каскадного видалення на передньому плані, щоб дізнатися більше.
Каскадне видалення у фоні
Під час фонового каскадного видалення API-сервер Kubernetes негайно видаляє обʼєкт-власник, а контролер збирача сміття (ваш власний або стандартний) очищає залежні обʼєкти у фоновому режимі. Якщо існує завершувач, він гарантує, що обʼєкти не будуть видалені, доки не будуть виконані всі необхідні завдання з очищення. Типово Kubernetes використовує каскадне видалення у фоні, якщо ви не використовуєте видалення вручну на передньому плані або не вибираєте залишити залежні обʼєкти.
Коли Kubernetes видаляє обʼєкт власника, залишені залежні обʼєкти називаються залишеними обʼєктами. Типово Kubernetes видаляє залежні обʼєкти. Щоб дізнатися, як перевизначити цю поведінку, дивіться Видалення власників та залишені залежності.
Збір сміття невикористаних контейнерів та образів
kubelet виконує збір сміття невикористаних образів кожні пʼять хвилин та невикористаних контейнерів кожну хвилину. Ви повинні уникати використання зовнішніх інструментів для збору сміття, оскільки вони можуть порушити поведінку kubelet та видаляти контейнери, які повинні існувати.
Щоб налаштувати параметри для збору сміття невикористаних контейнерів та образів, налаштуйте kubelet за допомогою файлу конфігурації та змініть параметри, повʼязані зі збором сміття, використовуючи ресурс типу KubeletConfiguration.
Життєвий цикл образу контейнера
Kubernetes керує життєвим циклом всіх образів через свій менеджер образів, який є частиною kubelet, співпрацюючи з cadvisor. Kubelet враховує такі обмеження щодо використання дискового простору під час прийняття рішень про збір сміття:
HighThresholdPercent
LowThresholdPercent
Використання дискового простору вище встановленого значення HighThresholdPercent викликає збір сміття, який видаляє образи в порядку їх останнього використання, починаючи з найстаріших. Kubelet видаляє образи до тих пір, поки використання дискового простору не досягне значення LowThresholdPercent.
Збір сміття для невикористаних контейнерних образів
Ви можете вказати максимальний час, протягом якого локальний образ може бути невикористаний, незалежно від використання дискового простору. Це налаштування kubelet, яке ви вказуєте для кожного вузла.
Щоб налаштувати параметр, встановіть значення поля imageMaximumGCAge у файлі конфігурації kubelet.
Значення вказується як тривалість. Дивіться визначення тривалості в глосарії для отримання докладних відомостей.
Наприклад, ви можете встановити значення поля конфігурації 12h45m, що означає 12 годин 45 хвилин.
Примітка:
Ця функція не відстежує використання образів між перезапусками kubelet. Якщо kubelet перезапускається, вік відстежуваного образу скидається, що призводить до того, що kubelet очікує повний проміжок часу imageMaximumGCAge перш ніж вважати образ придатним для збору сміття на основі його віку.
Збір сміття контейнерів
Kubelet збирає сміття невикористаних контейнерів на основі таких змінних, які ви можете визначити:
MinAge: мінімальний вік, за якого kubelet може видаляти контейнер. Щоб вимкнути, встановіть значення 0.
MaxPerPodContainer: максимальна кількість мертвих контейнерів, які може мати кожен Pod. Щоб вимкнути, встановіть значення менше 0.
MaxContainers: максимальна кількість мертвих контейнерів у кластері. Щоб вимкнути, встановіть значення менше 0.
Крім цих змінних, kubelet збирає сміття невизначених та видалених контейнерів, як правило, починаючи з найстарших.
MaxPerPodContainer та MaxContainers можуть потенційно конфліктувати одне з одним в ситуаціях, де збереження максимальної кількості контейнерів на кожен Pod (MaxPerPodContainer) перевищить допустиму загальну кількість глобальних мертвих контейнерів (MaxContainers). У цій ситуації kubelet коригує MaxPerPodContainer для вирішення конфлікту. У найгіршому випадку може бути знижений MaxPerPodContainer до 1 та виселені найдавніші контейнери. Крім того, контейнери, які належать Podʼам, які були видалені, видаляються, коли стають старшими за MinAge.
Примітка:
Kubelet збирає сміття лише для контейнерів, якими він керує.
Налаштування збору сміття
Ви можете налаштовувати збір сміття ресурсів, налаштовуючи параметри, специфічні для контролерів, що керують цими ресурсами. На наступних сторінках показано, як налаштовувати збір сміття:
Дізнайтеся про контролер TTL, який очищає завершені завдання.
9 - Проксі змішаних версій
СТАН ФУНКЦІОНАЛУ:Beta since Kubernetes v1.36; (стандартно увімкнено)
У Kubernetes 1.37 включено бета-функцію, яка дозволяє API-серверу проксіювати запити ресурсів до інших рівноправних API-серверів. Це також дозволяє клієнтам отримати цілісне уявлення про ресурси, що обслуговуються в усьому кластері, за допомогою виявлення. Це корисно, коли існують кілька API-серверів, що працюють на різних версіях Kubernetes в одному кластері (наприклад, під час тривалого впровадження нового релізу Kubernetes).
Це дозволяє адміністраторам кластерів налаштовувати високодоступні кластери, які можна оновлювати безпечніше:
гарантуючи, що контролери, які покладаються на виявлення для показу повного списку ресурсів для важливих завдань, завжди отримують повний огляд усіх ресурсів. Ми називаємо це повним виявленням у масштабі кластера — Peer-aggregated discovery.
направляючи запити на ресурси (зроблені під час оновлення) на відповідний kube-apiserver. Це проксіювання запобігає появі у користувачів несподіваних помилок 404 Not Found, спричинених процесом оновлення. Цей механізм називається Mixed Version Proxy.
Активація Peer-aggregated Discovery та Mixed Version Proxy
kube-apiserver \
--feature-gates=UnknownVersionInteroperabilityProxy=true\
# обовʼязкові аргументи командного рядка для цієї функції--peer-ca-file=<шлях до сертифіката CA kube-apiserver>
--proxy-client-cert-file=<шлях до сертифіката агрегатора проксі>,
--proxy-client-key-file=<шлях до ключа агрегатора проксі>,
--requestheader-client-ca-file=<шлях до сертифіката CA агрегатора>,
# requestheader-allowed-names може бути встановлено як порожнє значення, щоб дозволити будь-яке Common Name--requestheader-allowed-names=<дійсні значення Common Name для перевірки сертифіката клієнта проксі>,
# необовʼязкові прапорці для цієї функції--peer-advertise-ip=`IP цього kube-apiserver, який повинні використовувати рівноправні сервери для проксіювання запитів`--peer-advertise-port=`порт цього kube-apiserver, який повинні використовувати рівноправні сервери для проксіювання запитів`# …і інші прапорці як зазвичай
Транспорт та автентифікація проксі між API-серверами
Вихідний kube-apiserver повторно використовує
наявні прапорці автентифікації клієнта API-сервера--proxy-client-cert-file та --proxy-client-key-file для представлення своєї ідентичності, яку перевіряє рівноправний сервер (цільовий kube-apiserver). Цільовий API-сервер перевіряє це підключення на основі конфігурації, яку ви вказуєте за допомогою аргументу командного рядка --requestheader-client-ca-file.
Для автентифікації сертифікатів цільового сервера вам слід налаштувати пакет сертифікатів центру сертифікації, вказавши аргумент командного рядка --peer-ca-fileвихідному API-серверу.
Налаштування для зʼєднання з рівноправним API-сервером
Для встановлення мережевого розташування kube-apiserver, яке рівноправні сервери будуть використовувати для проксіювання запитів, використовуйте аргументи командного рядка --peer-advertise-ip та --peer-advertise-port для kube-apiserver або вказуйте ці поля в конфігураційному файлі API-сервера. Якщо ці прапорці не вказані, рівноправні сервери будуть використовувати значення з аргументів командного рядка --advertise-address або --bind-address для kube-apiserver. Якщо ці прапорці теж не встановлені, використовується типовий інтерфейс хоста.
Peer-aggregated discovery
Коли ви вмикаєте цю функцію, запити на виявлення автоматично вмикаються для надання комплексного документа виявлення (з переліком усіх ресурсів, що обслуговуються будь-яким apiserver у кластері) стандартно.
Якщо ви хочете запросити документ non peer-aggregated discovery, ви можете вказати це, додавши до запиту на виявлення такий заголовок Accept:
Коли ви вмикаєте проксіювання змішаних версій, шар агрегації завантажує спеціальний фільтр, який виконує такі дії:
Коли запит ресурсу надходить до API-сервера, який не може обслуговувати цей API (чи то тому, що його версія старіша за появу цього API, чи тому, що API вимкнено на API-сервері), API-сервер намагається надіслати запит до рівноправного API-сервера, який може обслуговувати затребуваний API. Це відбувається шляхом ідентифікації груп API / версій / ресурсів, які локальний сервер не розпізнає, і спроби проксіювати ці запити до рівноправного API-сервера, який може обробити запит.
Якщо рівноправний API-сервер не відповідає, то вихідний API-сервер відповідає помилкою 503 ("Service Unavailable").
Як це працює під капотом
Коли API-сервер отримує запит ресурсу, він спочатку перевіряє, які API-сервери можуть обслуговувати затребуваний ресурс. Ця перевірка відбувається за допомогою документа non peer-aggregated discovery.
Якщо ресурс є в документі non peer-aggregated discovery, отриманому від API-сервера, що отримав запит (наприклад, GET /api/v1/pods/some-pod), запит обробляється локально.
Якщо ресурс у запиті (наприклад, GET /apis/resource.k8s.io/v1beta1/resourceclaims) не знайдено в документі non peer-aggregated discovery, отриманому з API-сервера, який намагається обробити запит (API-сервер обробки), ймовірно, через те, що API resource.k8s.io/v1beta1 був введений в новій версії Kubernetes, а API-сервер обробки працює на старій версії, яка його не підтримує, тоді API-сервер обробки знаходить рівноправні API-сервери, які обслуговують відповідну групу API / версію / ресурс (у цьому випадку resource.k8s.io/v1beta1/resourceclaims) перевіряючи документи non peer-aggregated discovery усіх рівноправних API-серверів. Потім API-сервер обробки проксіює запит до одного з відповідних рівноправних kube-apiserver, які знають про запитуваний ресурс.
Якщо для цієї групи API / версії / ресурсу немає відомого рівноправного сервера, API-сервер обробки передає запит до власного ланцюжка обробників, який повинен зрештою повернути відповідь 404 ("Not Found").
Якщо API-сервер обробки визначив і вибрав рівноправний API-сервер, але той не відповідає (через проблеми з підключенням до мережі або стан гонитви між отриманням запиту та реєстрацією контролером інформації про рівноправний сервер у панелі управління), API-сервер обробки відповідає помилкою 503 ("Service Unavailable").