Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.

Повернутися до звичайного перегляду сторінки.

Обʼєкти в Kubernetes

Обʼєкти Kubernetes є постійними сутностями в системі Kubernetes. Kubernetes використовує ці сутності для подання стану вашого кластера. Дізнайтеся про модель обʼєктів Kubernetes та про те, як працювати з цими обʼєктами.

Ця сторінка пояснює, як обʼєкти Kubernetes подаються в API Kubernetes, та як ви можете описати їх у форматі .yaml.

Розуміння обʼєктів Kubernetes

Обʼєкти Kubernetes є постійними сутностями в системі Kubernetes. Kubernetes використовує ці сутності для подання стану вашого кластера. Зокрема, вони можуть описувати:

  • Які контейнеризовані застосунки працюють (і на яких вузлах)
  • Ресурси, доступні для цих застосунків
  • Політики щодо того, як ці застосунки поводяться, такі як політики перезапуску, оновлення та стійкості до відмов

Обʼєкт Kubernetes є "записом про наміри" — після створення обʼєкта система Kubernetes постійно працюватиме, щоб переконатися, що обʼєкт існує. Створюючи обʼєкт, ви фактично повідомляєте системі Kubernetes ваші побажання щодо того, як має виглядати робоче навантаження вашого кластера; це бажаний стан вашого кластера.

Для роботи з обʼєктами Kubernetes — чи то для створення, зміни чи видалення — вам потрібно використовувати API Kubernetes. Наприклад, коли ви використовуєте інтерфейс командного рядка kubectl, CLI виконує необхідні виклики API Kubernetes за вас. Ви також можете використовувати API Kubernetes безпосередньо у ваших власних програмах за допомогою однієї з клієнтських бібліотек.

Специфікація та стан обʼєкта

Майже кожен обʼєкт Kubernetes містить два вкладених поля обʼєкта, які керують конфігурацією обʼєкта: spec та status обʼєкта. Для обʼєктів, які мають spec, вам потрібно встановити його під час створення обʼєкта, надаючи опис характеристик, які ви хочете, щоб ресурс мав: його бажаний стан.

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

Наприклад: у Kubernetes Deployment є обʼєктом, який може представляти застосунок, який працює на вашому кластері. При створенні Deployment ви можете встановити spec Deployment, щоб вказати, що ви хочете, щоб працювало три репліки застосунку. Система Kubernetes читає spec Deployment та запускає три екземпляри вашого застосунку, оновлюючи status відповідно до вашого spec. Якщо один із цих екземплярів зазнає збою (зміна стану), система Kubernetes реагує на відмінність між spec та status, вносячи виправлення: у цьому випадку запускаючи екземпляр на заміну.

З докладнішою інформацією про spec, status та metadata обʼєктів Kubernetes звертайтесь до Kubernetes API Conventions.

Опис обʼєктів Kubernetes

Коли ви створюєте обʼєкт Kubernetes, ви повинні визначити spec обʼєкта, який описує бажаний стан обʼєкта, а також деякі основні відомості про обʼєкт, наприклад його назву (name). Коли ви використовуєте API Kubernetes для створення обʼєкта, чи безпосередньо, чи за допомогою kubectl, цей запит до API має містити ці відомості у вигляді JSON в тілі запиту. Найчастіше інформація про обʼєкт подається kubectl у вигляді файлу, який називається маніфестом. За домовленістю, маніфести обʼєктів Kubernetes подаються у форматі YAML (ви також можете використовувати JSON). Інструменти, такі як kubectl, перетворюють інформацію з маніфесту у JSON або інший підтримуваний формат серіалізації, надсилаючи HTTP-запити до API.

Ось приклад маніфесту, який містить обовʼязкові поля обʼєкта та його spec для Kubernetes Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Один зі способів створення Deployment за допомогою маніфесту, подібного до показаного вище, — використання команди kubectl apply в інтерфейсі командного рядка kubectl, передаючи файл .yaml як аргумент. Ось приклад:

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

Вивід буде схожий на цей:

deployment.apps/nginx-deployment created

Обовʼязкові поля

В маніфесті (файл YAML або JSON) обʼєкта Kubernetes, який ви хочете створити, ви повинні вказати значення для таких полів:

  • apiVersion — версія API Kubernetes, яку ви використовуєте для створення обʼєкта
  • kind — тип обʼєкта, який ви хочете створити
  • metadata — дані, які допомагають унікально ідентифікувати обʼєкт, включаючи рядок name, UID та, необовʼязково, namespace
  • spec — опис бажаного стану обʼєкта

Точний формат spec обʼєкта є різним для кожного типу обʼєкта в Kubernetes та містить вкладені поля, що притаманні конкретному типу обʼєкта. Довідник API Kubernetes може допомогти знайти формат spec для всіх типів обʼєктів, які ви можете створити за допомогою Kubernetes.

Наприклад, подивіться на поле spec для обʼєкта Pod. Для кожного Podʼа поле .spec описує Pod та його бажаний стан (наприклад, назву образу контейнера для кожного контейнера всередині цього Podʼа). Інший приклад специфікації обʼєкта — поле spec для обʼєкта StatefulSet. Для StatefulSet поле .spec описує StatefulSet та його бажаний стан. У .spec StatefulSet є шаблон для обʼєктів Pod. Цей шаблон описує Podʼи, які контролер StatefulSet створить, щоб задовольнити специфікацію StatefulSet. Різні типи обʼєктів Kubernetes можуть мати різні .status; дивіться довідник API Kubernetes для отримання відомостей про структуру поля .status та його вміст для кожного типу обʼєкта.

Додаткову інформацію про написання конфігураційних файлів YAML дивіться в Рекомендаціях щодо конфігурації Kubernetes.

Перевірка полів на стороні сервера

Починаючи з Kubernetes v1.25, API-сервер надає перевірку полів на стороні сервера, яка виявляє невідомі та дубльовані поля в обʼєкті. Це надає всю функціональність kubectl --validate на стороні сервера.

kubectl використовує прапорець --validate для встановлення рівня перевірки полів маніфесту. Його значенням може бути ignore, warn та strict, також можна вказати true (еквівалент strict) та false (еквівалент ignore). Типове значення перевірки для kubectl — --validate=true.

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

Якщо kubectl не може підʼєднатися до API-сервера, який підтримує перевірку полів, він використовує перевірку на стороні клієнта. Kubernetes v1.27 та пізніші версії завжди пропонуватимуть перевірку полів; версії до v1.27, скоріш за все — ні. Якщо версія Kubernetes на вашому кластері старіша за v1.27, звіртесь з документацією до вашої версії Kubernetes.

Що далі

Якщо ви тільки починаєте свій шлях в Kubernetes, дізнайтесь більше про:

Керування обʼєктами в Kubernetes надає додаткову інформацію про те, як використовувати kubectl для керування обʼєктами. Можливо, вам потрібно буде встановити kubectl, якщо його у вас ще немає.

Щоб дізнатись про API Kubernetes, зверніться до:

Щоб глибше ознайомитися з обʼєктами в Kubernetes, прочитайте інші сторінки цього розділу:

1 - Управління обʼєктами Kubernetes

Інструмент командного рядка kubectl підтримує кілька різних способів створення та управління обʼєктами Kubernetes. Цей документ надає огляд різних підходів. Для отримання деталей щодо управління обʼєктами за допомогою Kubectl читайте Книгу Kubectl.

Техніки управління

Попередження:

Обʼєкт Kubernetes повинен управлятися лише з використанням однієї техніки. Змішування різних технік для того самого обʼєкта призводить до невизначеної поведінки.
Техніка управлінняДіє наРекомендоване середовищеПідтримувані автори змінКрива навчання
Імперативні командиЖиві обʼєктиПроєкти розробки1+Найлегша
Імперативна конфігурація обʼєктівОкремі файлиПромислові проєкти1Середня
Декларативна конфігурація обʼєктівТеки файлівПромислові проєкти1+Найскладніша

Імперативні команди

Під час використання імперативних команд користувач працює безпосередньо з живими обʼєктами в кластері. Користувач надає операції команді kubectl у вигляді аргументів чи прапорців.

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

Приклади

Запустіть екземпляр контейнера nginx, створивши обʼєкт Deployment:

kubectl create deployment nginx --image nginx

Компроміси

Переваги порівняно із конфігуруванням обʼєктів:

  • Команди виражені як одне слово дії.
  • Команди вимагають лише одного кроку для внесення змін до кластера.

Недоліки порівняно із конфігуруванням обʼєктів:

  • Команди не інтегруються з процесами перегляду змін.
  • Команди не надають журналу аудиту, повʼязаного зі змінами.
  • Команди не надають джерела записів, окрім самих живих обʼєктів.
  • Команди не надають шаблону для створення нових обʼєктів.

Імперативне конфігурування обʼєктів

В імперативній конфігурації обʼєктів команда kubectl вказує операцію (create, replace тощо), необовʼязкові прапорці та принаймні одне імʼя файлу. Зазначений файл повинен містити повне визначення обʼєкта у форматі YAML або JSON.

Див. API-довідник для отримання докладніших відомостей щодо визначення обʼєктів.

Попередження:

Імперативна команда replace замінює поточну специфікацію на нову, відкидаючи всі зміни обʼєкта, яких немає у файлі конфігурації. Цей підхід не повинен використовуватися із типами ресурсів, специфікації яких оновлюються незалежно від файлу конфігурації. Наприклад, у Services типу LoadBalancer поле externalIPs оновлюється кластером незалежно від файлу конфігурації.

Приклади

Створити обʼєкти, визначені у файлі конфігурації:

kubectl create -f nginx.yaml

Видалити обʼєкти, визначені у двох файлах конфігурації:

kubectl delete -f nginx.yaml -f redis.yaml

Оновити обʼєкти, визначені у файлі конфігурації, перезаписавши живу конфігурацію:

kubectl replace -f nginx.yaml

Компроміси

Переваги порівняно з імперативними командами:

  • Конфігурація обʼєктів може зберігатися у системі контролю версій, такій як Git.
  • Конфігурація обʼєктів може інтегруватися з процесами, такими як перегляд змін перед надсиланням (push) та журнали аудиту.
  • Конфігурація обʼєктів надає шаблон для створення нових обʼєктів.

Недоліки порівняно з імперативними командами:

  • Конфігурація обʼєктів потребує базового розуміння схеми обʼєкта.
  • Конфігурація обʼєктів потребує додаткового кроку у вигляді написання файлу YAML.

Переваги порівняно із декларативною конфігурацією обʼєктів:

  • Поведінка імперативної конфігурації обʼєктів простіша та її легше зрозуміти.
  • Станом на версію Kubernetes 1.5 імперативна конфігурація обʼєктів є більш зрілою.

Недоліки порівняно із декларативною конфігурацією обʼєктів:

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

Декларативна конфігурація обʼєктів

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

Примітка:

Декларативна конфігурація обʼєктів зберігає зміни, внесені іншими авторами, навіть якщо зміни не зливаються назад у файл конфігурації обʼєкта. Це можливо за допомогою використання операції API patch для запису тільки виявлених відмінностей, замість використання операції API replace для заміни всього файлу конфігурації обʼєкта.

Приклади

Обробити всі файли конфігурації обʼєктів у теці configs та створити або внести патчі до живих обʼєктів. Спочатку ви можете використовувати diff, щоб побачити, які зміни будуть внесені, а потім застосувати їх:

kubectl diff -f configs/
kubectl apply -f configs/

Рекурсивно обробити теки:

kubectl diff -R -f configs/
kubectl apply -R -f configs/

Компроміси

Переваги порівняно з імперативною конфігурацією обʼєктів:

  • Зміни, внесені безпосередньо в живі обʼєкти, зберігаються, навіть якщо вони не зливаються назад у файли конфігурації.
  • Декларативна конфігурація обʼєктів краще підтримує роботу з теками та автоматично визначає типи операцій (створення, патч, видалення) для кожного обʼєкта.

Недоліки порівняно з імперативною конфігурацією обʼєктів:

  • Декларативну конфігурацію обʼєктів важче налагоджувати, а її результати важче зрозуміти, коли вони неочікувані.
  • Часткові оновлення за допомогою diffs створюють складні операції злиття та накладання патчів.

Що далі

2 - Назви та ідентифікатори обʼєктів

Кожен обʼєкт у вашому кластері має Назву, яка є унікальною для цього типу ресурсу. Кожен обʼєкт Kubernetes також має UID, який є унікальним в усьому вашому кластері.

Наприклад, ви можете мати лише один обʼєкт Pod із назвою myapp-1234 в одному й тому самому просторі імен, а також ви можете мати один обʼєкт Pod та один Deployment із назвами myapp-1234 кожен.

Для неунікальних атрибутів, наданих користувачем, Kubernetes надає мітки (labels) та анотації (annotations).

Назви

Наданий клієнтом рядок, який посилається на обʼєкт в URL ресурсу, наприклад /api/v1/pods/some-name.

Водночас лише один обʼєкт певного виду (kind) може мати певну назву. Проте якщо ви видалите обʼєкт, ви можете створити новий обʼєкт з такою самою назвою.

Назви повинні бути унікальними між усіма версіями API того самого ресурсу.

Kubernetes унікально ідентифікує обʼєкти за допомогою комбінації чотирьох атрибутів:

  • Група API (наприклад, apps)
  • Тип ресурсу (наприклад, deployments)
  • Простір імен (для ресурсів із просторами імен)
  • Назва

Хоча ви можете отримати доступ до ресурсу через різні версії API (наприклад, v1 або v1beta1), версія є просто іншим представленням того самого базового обʼєкта. Оскільки версія не є частиною унікальної ідентифікації, ви не можете створити два обʼєкти з однаковою назвою та типом ресурсу в одному просторі імен, використовуючи різні версії API.

Примітка:

У випадках, коли обʼєкти представляють фізичний обʼєкт, наприклад, Node, що представляє фізичний хост, коли хост створюється заново з тією самою назвою без видалення та повторного створення Node, Kubernetes розглядає новий хост як старий, що може призвести до неузгодженостей.

Сервер може згенерувати назву, якщо в запиті на створення ресурсу замість name вказати generateName. Коли використовується generateName, надане значення використовується як префікс назви, до якого сервер додає згенерований суфікс. Навіть якщо назву згенеровано, вона може конфліктувати з наявними назвами, що призведе до відповіді HTTP 409. Це стало набагато менш імовірним в Kubernetes v1.31 і пізніших версіях, оскільки сервер зробить до 8 спроб згенерувати унікальну назву перед тим, як повернути відповідь HTTP 409.

Нижче наведено чотири типи обмежень на назви ресурсів, які часто використовуються.

Назви DNS-піддоменів

Більшість типів ресурсів потребують назви, яку можна використовувати як DNS-піддомен згідно з RFC 1123. Це означає, що назва повинна:

  • містити не більше 253 символів
  • містити лише буквено-цифрові символи, '-' чи '.' в нижньому регістрі
  • починатися буквено-цифровим символом
  • закінчуватися буквено-цифровим символом

Назви міток RFC 1123

Деякі типи ресурсів вимагають, щоб їх назви відповідали стандарту міток DNS, як визначено в RFC 1123. Це означає, що назва повинна:

  • містити не більше 63 символів
  • містити лише буквено-цифрові символи чи '-' в нижньому регістрі
  • починатися алфавітним символом
  • закінчуватися буквено-цифровим символом

Примітка:

Коли увімкнено функціональну можливість RelaxedServiceNameValidation, назви обʼєктів Service можуть починатися з цифри.

Назви міток RFC 1035

Деякі типи ресурсів вимагають, щоб їх назви відповідали стандарту міток DNS, як визначено в RFC 1035. Це означає, що назва повинна:

  • містити не більше 63 символів
  • містити лише буквено-цифрові символи чи '-' в нижньому регістрі
  • починатися алфавітним символом
  • закінчуватися буквено-цифровим символом

Примітка:

Хоча RFC 1123 технічно дозволяє міткам починатися з цифри, поточна реалізація Kubernetes вимагає, щоб мітки як RFC 1035, так і RFC 1123 починалися з літери. Винятком є увімкнення функціональної можливості RelaxedServiceNameValidation для обʼєктів Service, що дозволяє назвам Service починатися з цифри.

Назви сегментів шляху

Деякі типи ресурсів вимагають, щоб їх назви можна було безпечно кодувати як сегмент шляху. Іншими словами, назва не може бути "." або "..", і вона не може містити "/" або "%".

Ось приклад маніфесту для Pod із назвою nginx-demo.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Примітка:

Деякі типи ресурсів мають додаткові обмеження на їх назви.

UID

Рядок, створений системами Kubernetes для унікальної ідентифікації обʼєктів.

Кожен обʼєкт, створений протягом усього життя кластера Kubernetes, має унікальний UID. Він призначений для розрізнення історичних екземплярів схожих сутностей.

UID Kubernetes — це універсальні унікальні ідентифікатори (також відомі як UUID). UUID стандартизовані згідно з ISO/IEC 9834-8 та ITU-T X.667.

Що далі

3 - Мітки та селектори

Мітки — це пари ключ/значення, які прикріплені до обʼєктів, таких як Pod. Мітки призначені для вказування ідентифікувальних атрибутів обʼєктів, які мають значення та стосуються користувачів, але безпосередньо не визначають семантику для основної системи. Мітки можуть бути використані для організації та вибору підмножини обʼєктів. Мітки можуть бути прикріплені до обʼєктів під час створення та пізніше додані та змінені в будь-який час. Кожен обʼєкт може мати набір міток ключ/значення. Кожен ключ повинен бути унікальним для даного обʼєкта.

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

Мітки дозволяють ефективно виконувати запити та спостереження та є ідеальними для використання в інтерфейсах користувача та інтерфейсах командного рядка. Неідентифікувальну інформацію слід записувати за допомогою анотацій.

Мотивація

Мітки дозволяють користувачам звʼязувати свої власні організаційні структури з обʼєктами системи слабко повʼязаним способом, не вимагаючи зберігання цих звʼязків в клієнтах.

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

Приклади міток:

  • "release" : "stable", "release" : "canary"
  • "environment" : "dev", "environment" : "qa", "environment" : "production"
  • "tier" : "frontend", "tier" : "backend", "tier" : "cache"
  • "partition" : "customerA", "partition" : "customerB"
  • "track" : "daily", "track" : "weekly"

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

Синтаксис та набір символів

Мітки — це пари ключ/значення. Дійсні ключі міток мають два сегменти: необовʼязковий префікс та назву, розділені скісною рискою (/). Сегмент назви є обовʼязковим і має бути не більше 63 символів, починатися та закінчуватися буквено-цифровим символом ([a-z0-9A-Z]), і може містити дефіси (-), підкреслення (_), крапки (.) та буквено-цифрові символи між ними. Префікс є необовʼязковим. Якщо вказаний, префікс повинен бути піддоменом DNS: серією DNS-міток, розділених крапками (.), не довше 253 символів загалом, за якими слідує скісна риска (/).

Якщо префікс відсутній, ключ мітки вважається приватним для користувача. Автоматизовані компоненти системи (наприклад, kube-scheduler, kube-controller-manager, kube-apiserver, kubectl або інші сторонні засоби автоматизації), які додають мітки до обʼєктів користувача, повинні вказати префікс.

Префікси kubernetes.io/ та k8s.io/ є зарезервованими для основних компонентів Kubernetes.

Дійсне значення мітки:

  • повинно бути не більше 63 символів (може бути порожнім),
  • крім порожнього значення, повинно починатися та закінчуватися буквено-цифровим символом ([a-z0-9A-Z]),
  • може містити дефіси (-), підкреслення (_), крапки (.) та буквено-цифрові символи між ними.

Наприклад, ось маніфест для Pod із двома мітками environment: production та app: nginx:

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Селектори міток

На відміну від назв та UID, мітки не забезпечують унікальності. Загалом, ми очікуємо, що багато обʼєктів матимуть ті самі мітки.

За допомогою селектора міток клієнт або користувач може ідентифікувати набір обʼєктів. Селектор міток є основним примітивом групування в Kubernetes.

На цей момент API підтримує два типи селекторів: на основі рівності та на основі множини. Селектор міток може складатися з кількох вимог, які розділені комами. У випадку кількох вимог всі повинні бути задоволені, таким чином кома виступає логічним оператором AND (&&).

Семантика порожніх або невизначених селекторів залежить від контексту, і типи API, які використовують селектори, повинні документувати їхню чинність та значення.

Примітка:

Для деяких типів API, таких як ReplicaSets, селектори міток двох екземплярів не повинні перетинатися в одному просторі імен, бо контролер може вважати це конфліктними інструкціями та не зможе визначити, скільки реплік повинно бути присутньо.

Увага:

Для умов на основі рівності і на основі множини немає логічного оператора OR (||). Переконайтеся, що ваші вирази фільтрації структуровані відповідно.

Вимоги на основі рівності

Вимоги на основі рівності чи нерівності дозволяють фільтрувати обʼєкти за ключами та значеннями міток. Відповідні обʼєкти повинні задовольняти всі вказані обмеження міток, хоча вони також можуть мати додаткові мітки. Допускаються три види операторів: =, ==, !=. Перший та другий представляють рівність (equality) і є синонімами, тоді як останній представляє нерівність (inequality). Наприклад:

environment = production
tier != frontend

Перший вибирає всі ресурси з ключем environment та значенням production. Другий вибирає всі ресурси з ключем tier та значеннями, відмінними від frontend, а також усі ресурси без міток із ключем tier. Можна відфільтрувати ресурси в production, виключивши frontend, за допомогою оператора коми: environment=production,tier!=frontend.

Один зі сценаріїв використання вимог на основі рівності — вказування критеріїв вибору вузлів для Podʼів. Наприклад, зразок Podʼа нижче вибирає вузли, де мітка accelerator існує і має значення nvidia-tesla-p100.

apiVersion: v1
kind: Pod
metadata:
  name: cuda-test
spec:
  containers:
    - name: cuda-test
      image: "registry.k8s.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100

Вимоги на основі множини

Вимоги на основі множини дозволяють фільтрувати ключі за набором значень. Підтримуються три види операторів: in, notin та exists (тільки ідентифікатор ключа). Наприклад:

environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
  • Перший приклад вибирає всі ресурси з ключем, рівним environment, та значенням, рівним production або qa.
  • Другий приклад вибирає всі ресурси з ключем, рівним tier, та значеннями, іншими ніж frontend та backend, а також усі ресурси без міток із ключем tier.
  • Третій приклад вибирає всі ресурси, які мають мітку з ключем partition; значення не перевіряються.
  • Четвертий приклад вибирає всі ресурси без мітки з ключем partition; значення не перевіряються.

Так само розділювач-кома діє як оператор AND. Таким чином, фільтрування ресурсів із ключем partition (незалежно від значення) та з environment, відмінним від qa, можна досягти за допомогою partition,environment notin (qa). Селектор міток на основі множини є загальною формою рівності, оскільки environment=production еквівалентно environment in (production); так само для != та notin.

Вимоги на основі множини можна комбінувати з вимогами на основі рівності. Наприклад: partition in (customerA, customerB),environment!=qa.

API

Фільтрація LIST та WATCH

Для операцій list і watch ви можете вказати селектори міток для фільтрації наборів обʼєктів, що повертаються; фільтр задається за допомогою параметра запиту. (Щоб дізнатися докладніше про watch у Kubernetes, прочитайте ефективне виявлення змін). Дозволені обидва типи вимог (тут подано так, як вони зʼявляться у рядку URL-запиту):

  • вимоги на основі рівності: ?labelSelector=environment%3Dproduction,tier%3Dfrontend
  • вимоги на основі множини: ?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

Обидва стилі селекторів міток можуть бути використані для отримання переліку ресурсів чи спостереження за ними через клієнта REST. Наприклад, спрямовуючись до apiserver за допомогою kubectl та використовуючи вимогу на основі рівності, можна написати:

kubectl get pods -l environment=production,tier=frontend

чи використовуючи вимогу на основі множини:

kubectl get pods -l 'environment in (production),tier in (frontend)'

Як вже зазначалося, вимоги на основі множини є більш виразними. Наприклад, вони можуть реалізувати оператор OR в значеннях:

kubectl get pods -l 'environment in (production, qa)'

чи обмежувати негативний збіг за допомогою оператора notin:

kubectl get pods -l 'environment,environment notin (frontend)'

Посилання на набори в обʼєктах API

Деякі обʼєкти Kubernetes, такі як services та replicationcontrollers, також використовують селектори міток для вказівки наборів інших ресурсів, таких як Podʼи.

Service та ReplicationController

Набір Podʼів, на який спрямований service, визначається селектором міток. Так само сукупність Podʼів, якою повинен керувати replicationcontroller, також визначається селектором міток.

Селектори міток для обох обʼєктів визначаються у файлах json або yaml за допомогою мап, і підтримуються лише селектори вимог на основі рівності:

"selector": {
    "component" : "redis",
}

або

selector:
  component: redis

Цей селектор (відповідно у форматі json або yaml) еквівалентний component=redis або component in (redis).

Ресурси, які підтримують вимоги на основі множини

Новіші ресурси, такі як Job, Deployment, ReplicaSet та DaemonSet, також підтримують вимоги на основі множини.

selector:
  matchLabels:
    component: redis
  matchExpressions:
    - { key: tier, operator: In, values: [cache] }
    - { key: environment, operator: NotIn, values: [dev] }

matchLabels — це мапа пар {key,value}. Одна пара {key,value} у мапі matchLabels еквівалентна елементу matchExpressions, де поле key — це "key", оператор — "In", а масив values містить лише "value". matchExpressions — це список вимог селектора Podʼів. Допустимі оператори включають In, NotIn, Exists та DoesNotExist. Масив values повинен бути непорожнім у випадку In та NotIn. Усі вимоги, як із matchLabels, так і з matchExpressions, обʼєднуються логічною операцією AND: усі вони повинні бути задоволені для збігу.

Вибір множини вузлів

Одним із варіантів використання вибору за мітками є обмеження множини вузлів, на які може бути заплановано Pod. Дивіться документацію щодо вибору вузла для отримання докладнішої інформації.

Ефективне використання міток

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

Наприклад, різні застосунки можуть використовувати різні значення для мітки app, але багаторівневий застосунок, такий як приклад гостьової книги, додатково повинен відрізняти кожний рівень.

У наступних прикладах мітка app включена для зручності при ручних запитах та простому використанні CLI. Мітка app.kubernetes.io/name відповідає рекомендованим конвенціям Kubernetes щодо міток і краще підходить для інструментів та автоматизації.

Фронтенд може мати такі мітки:

labels:
  app: guestbook
  app.kubernetes.io/name: guestbook
  tier: frontend

тоді як Redis master та replica можуть мати різні мітки tier, і, можливо, навіть додаткову мітку role:

labels:
  app: guestbook
  app.kubernetes.io/name: guestbook
  tier: backend
  role: master

та

labels:
  app: guestbook
  app.kubernetes.io/name: guestbook
  tier: backend
  role: replica

Мітки дозволяють нарізати й групувати ресурси за будь-яким виміром, заданим міткою:

kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY  STATUS    RESTARTS   AGE   APP         TIER       ROLE
guestbook-fe-4nlpb             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-ght6d             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-jpy62             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1    Running   0          1m    guestbook   backend    master
guestbook-redis-replica-2q2yf  1/1    Running   0          1m    guestbook   backend    replica
guestbook-redis-replica-qgazl  1/1    Running   0          1m    guestbook   backend    replica
my-nginx-divi2                 1/1    Running   0          29m   nginx       <none>     <none>
my-nginx-o0ef1                 1/1    Running   0          29m   nginx       <none>     <none>
kubectl get pods -lapp=guestbook,role=replica
NAME                           READY  STATUS   RESTARTS  AGE
guestbook-redis-replica-2q2yf  1/1    Running  0         3m
guestbook-redis-replica-qgazl  1/1    Running  0         3m

Оновлення міток

Іноді вам може знадобитися змінити мітки наявних Podʼів та інших ресурсів перед створенням нових ресурсів. Це можна зробити за допомогою kubectl label. Наприклад, якщо ви хочете позначити всі свої NGINX Podʼи як рівень фронтенду, виконайте:

kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled

Спочатку фільтруються всі Podʼи з міткою "app=nginx", а потім вони позначаються як "tier=fe". Щоб переглянути Podʼи, які ви позначили, виконайте:

kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

Це виводить всі Podʼи "app=nginx", з додатковим стовпчиком міток рівня Podʼів (вказаним за допомогою -L або --label-columns).

Додаткову інформацію див. у kubectl label.

Що далі

4 - Простори імен

У Kubernetes простори імен (namespaces) забезпечують механізм для ізоляції груп ресурсів у межах одного кластера. Назви ресурсів повинні бути унікальними в межах простору імен, але не між просторами імен. Засноване на просторах імен обмеження застосовується лише до обʼєктів, які входять до простору імен (наприклад, Deployments, Services тощо), а не до обʼєктів, що поширюються на весь кластер (наприклад, StorageClass, Nodes, PersistentVolumes тощо).

Коли використовувати кілька просторів імен

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

Простори імен задають область дії для назв. Назви ресурсів повинні бути унікальними в межах простору імен, але не між просторами імен. Простори імен не можуть бути вкладені один в одного, і кожен ресурс Kubernetes може бути лише в одному просторі імен.

Простори імен — це спосіб розділити ресурси кластера між кількома користувачами (за допомогою квот ресурсів).

Не обовʼязково використовувати кілька просторів імен для відокремлення трохи відмінних ресурсів, таких як різні версії того самого програмного забезпечення: використовуйте мітки для розрізнення ресурсів в межах одного простору імен.

Примітка:

Для промислового кластера розгляньте можливість не використовувати простір імен default. Замість цього створюйте і використовуйте інші простори імен.

Початкові простори імен

Після запуску в Kubernetes є чотири початкові простори імен:

default
Kubernetes включає цей простір імен, щоб ви могли почати використовувати новий кластер без попереднього створення простору імен.
kube-node-lease
Цей простір імен містить обʼєкти Lease, повʼязані з кожним вузлом. Лізинги вузлів дозволяють kubelet надсилати пульс, щоб панель управління могла виявити відмову вузла.
kube-public
Цей простір імен може бути прочитаний усіма клієнтами (включаючи тих, які не автентифіковані). Цей простір імен в основному призначений для внутрішнього використання кластером, у випадку, коли деякі ресурси повинні бути видимими та доступними публічно по всьому кластеру. Публічний аспект цього простору імен — це лише домовленість, яка не є обовʼязковою.
kube-system
Простір імен для обʼєктів, створених системою Kubernetes.

Робота з просторами імен

Створення та видалення просторів імен описано в документації з адміністрування просторів імен.

Примітка:

Уникайте створення просторів імен із префіксом kube-, оскільки він зарезервований для системних просторів імен Kubernetes.

Перегляд просторів імен

Ви можете переглянути поточні простори імен у кластері за допомогою:

kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d

Встановлення простору імен для запиту

Щоб встановити простір імен для поточного запиту, використовуйте прапорець --namespace.

Наприклад:

kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>

Встановлення обраного простору імен

Ви можете назавжди зберегти простір імен для всіх подальших команд kubectl у цьому контексті.

kubectl config set-context --current --namespace=<insert-namespace-name-here>
# Перевірте його
kubectl config view --minify | grep namespace:

Простори імен та DNS

Під час створення Service створюється відповідний DNS-запис. Цей запис має форму <service-name>.<namespace-name>.svc.cluster.local, що означає, що якщо контейнер використовує тільки <service-name>, він буде розвʼязаний у сервіс, локальний для простору імен. Це корисно для використання тієї самої конфігурації в кількох просторах імен, таких як Development, Staging та Production. Якщо вам потрібно досягти обʼєкта в іншому просторі імен, вам слід використовувати повне кваліфіковане доменне імʼя (FQDN).

Отже, усі назви просторів імен повинні бути дійсними DNS-мітками згідно з RFC 1123.

Попередження:

Якщо створити простори імен із тими самими назвами, що й публічні домени верхнього рівня (TLD), Services у цих просторах імен можуть мати короткі імена DNS, які перетинаються з публічними записами DNS. Робоче навантаження з будь-якого простору імен, яке виконує DNS-запит без крапки в кінці, буде перенаправлено на ці сервіси, які матимуть пріоритет над публічним DNS.

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

Не всі обʼєкти належать до простору імен

Більшість ресурсів Kubernetes (наприклад, Pods, Services, Deployments та інші) перебувають у певних просторах імен. Однак самі ресурси просторів імен не належать до жодного простору імен. А ресурси низького рівня, такі як Nodes та PersistentVolumes, не перебувають в жодному просторі імен.

Щоб переглянути, які ресурси Kubernetes є в просторі імен, а які — ні:

# В просторі імен
kubectl api-resources --namespaced=true

# Не в просторі імен
kubectl api-resources --namespaced=false

Автоматичне додавання міток

СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.22

Панель управління Kubernetes встановлює незмінну мітку kubernetes.io/metadata.name для всіх просторів імен. Значення мітки — це назва простору імен.

Що далі

5 - Анотації

Ви можете використовувати анотації Kubernetes, щоб додати довільні неідентифікувальні метадані до обʼєктів. Клієнти, такі як інструменти та бібліотеки, можуть отримувати ці метадані.

Додавання метаданих до обʼєктів

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

Анотації, подібно до міток, є парами ключ/значення:

"metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

Примітка:

Ключі та значення в мапі повинні бути рядками. Іншими словами, ви не можете використовувати числові, булеві, спискові або інші типи як для ключів, так і для їх значень.

Ось кілька прикладів інформації, яку можна записати в анотаціях:

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

  • Інформація про збірку, реліз чи образ, така як часові мітки, ідентифікатори релізу, гілка git, номери PR, хеші образу та адреса реєстру.

  • Вказівники на репозиторії логування, моніторингу, аналітики чи аудиту.

  • Інформація про клієнтську бібліотеку чи інструмент, яку можна використовувати для налагодження: наприклад, назва, версія та інформація про збірку.

  • Інформація про походження користувача чи інструменту/системи, така як URL-адреси повʼязаних обʼєктів з інших компонентів екосистеми.

  • Метадані легких інструментів розгортання: наприклад, конфігурація чи контрольні точки.

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

  • Директиви від кінцевого користувача до реалізації щодо зміни поведінки чи використання нестандартних функцій.

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

Синтаксис та набір символів

Анотації — це пари ключ/значення. Допустимі ключі анотацій мають два сегменти: необовʼязковий префікс і назва, розділені скісною рискою (/). Назва є обовʼязковою та має містити не більше 63 символів, починаючись та закінчуючись буквено-цифровим символом ([a-z0-9A-Z]), і може містити дефіси (-), підкреслення (_), крапки (.) та буквено-цифрові символи між ними. Префікс є необовʼязковим. Якщо вказано, префікс повинен бути піддоменом DNS: серією DNS-міток, розділених крапками (.), загальною довжиною не більше 253 символів, за якою слідує скісна риска (/).

Якщо префікс відсутній, ключ анотації вважається приватним для користувача. Автоматизовані компоненти системи (наприклад, kube-scheduler, kube-controller-manager, kube-apiserver, kubectl чи інші автоматизовані засоби від сторонніх розробників), які додають анотації до обʼєктів кінцевого користувача, повинні вказати префікс.

Префікси kubernetes.io/ та k8s.io/ зарезервовані для основних компонентів Kubernetes.

Значення анотацій не мають жодних обмежень щодо набору символів — на відміну від значень міток, значення анотацій можуть містити будь-які рядки, включаючи спеціальні символи, пробіли та структуровані дані, такі як JSON або YAML. Якщо ви плануєте зберігати двійкові дані (наприклад, CBOR), проєкт Kubernetes рекомендує кодувати їх у форматі base64. Однак загальний розмір всіх анотацій на одному обʼєкті (ключі та значення разом) не повинен перевищувати 256 КіБ.

Наприклад, ось маніфест для Pod, який має анотацію imageregistry: https://hub.docker.com/:

apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Що далі

6 - Селектори полів

Селектори полів дозволяють вам вибирати обʼєкти Kubernetes на основі значень одного або кількох полів ресурсу. Ось кілька прикладів запитів для селекторів полів:

  • metadata.name=my-service
  • metadata.namespace!=default
  • status.phase=Pending

Ця команда kubectl вибирає всі Podʼи, для яких значення поля status.phase дорівнює Running:

kubectl get pods --field-selector status.phase=Running

Примітка:

Селектори полів, по суті, є фільтрами ресурсів. Типово селектори/фільтри не застосовуються, а це означає, що вибрані всі ресурси вказаного типу. Це робить запити kubectl get pods та kubectl get pods --field-selector "" еквівалентними.

Підтримувані поля

Підтримувані селектори полів варіюються залежно від типу ресурсу Kubernetes. Усі типи ресурсів підтримують поля metadata.name та metadata.namespace. Використання непідтримуваних селекторів полів призводить до помилки. Наприклад:

kubectl get ingress --field-selector foo.bar=baz
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"

Список підтримуваних полів

ВидПоля
Podspec.nodeName
spec.restartPolicy
spec.schedulerName
spec.serviceAccountName
spec.hostNetwork
status.phase
status.podIP
status.podIPs
status.nominatedNodeName
EventinvolvedObject.kind
involvedObject.namespace
involvedObject.name
involvedObject.uid
involvedObject.apiVersion
involvedObject.resourceVersion
involvedObject.fieldPath
reason
reportingComponent
source
type
Servicespec.clusterIP
spec.type
Secrettype
Namespacestatus.phase
ReplicaSetstatus.replicas
ReplicationControllerstatus.replicas
Jobstatus.successful
Nodespec.unschedulable
CertificateSigningRequestspec.signerName

Поля власних ресурсів

Усі власні типи ресурсів підтримують поля metadata.name та metadata.namespace.

Крім того, поле spec.versions[*].selectableFields у CustomResourceDefinition оголошує, які інші поля власного ресурсу можна використовувати у селекторах полів. Дивіться статтю поля, які можна вибрати для власних ресурсів для отримання додаткових відомостей про те, як використовувати селектори полів з CustomResourceDefinitions.

Підтримувані оператори

Ви можете використовувати оператори =, == та != з селекторами полів (= та == означають те саме). Наприклад, ця команда kubectl вибирає всі Services Kubernetes, які не перебувають у просторі імен default:

kubectl get services  --all-namespaces --field-selector metadata.namespace!=default

Примітка:

Оператори на основі множини (in, notin, exists) не підтримуються для селекторів полів.

Ланцюжки селекторів

Як і селектори міток та інші селектори, селектори полів можна обʼєднувати в ланцюжок у вигляді списку, розділеного комами. Ця команда kubectl вибирає всі Podʼи, для яких значення status.phase не дорівнює Running, а поле spec.restartPolicy дорівнює Always:

kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

Кілька типів ресурсів

Ви можете використовувати селектори полів для кількох типів ресурсів. Ця команда kubectl вибирає всі Statefulsets та Services, які не перебувають у просторі імен default:

kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default

7 - Власники та залежності

У Kubernetes деякі обʼєкти є власниками інших обʼєктів. Наприклад, ReplicaSet є власником групи Podʼів. Ці підлеглі обʼєкти є залежними від свого власника.

Власність відрізняється від механізму міток та селекторів, який також використовують деякі ресурси. Наприклад, розгляньте Service, який створює обʼєкти EndpointSlice. Service використовує мітки, щоб панель управління могла визначити, які обʼєкти EndpointSlice використовуються для цього Service. Крім міток, кожен EndpointSlice, керований від імені Service, має посилання на власника. Посилання на власника допомагають різним частинам Kubernetes уникати втручання в обʼєкти, якими вони не керують.

Посилання на власника в специфікаціях обʼєктів

Залежні обʼєкти мають поле metadata.ownerReferences, яке містить посилання на їх власника. Дійсне посилання на власника складається з назви обʼєкта та UID в межах того ж простору імен, що й залежний обʼєкт. Kubernetes автоматично встановлює значення цього поля для обʼєктів, які є залежностями інших обʼєктів, таких як ReplicaSets, DaemonSets, Deployments, Jobs та CronJobs, та ReplicationControllers. Ви також можете налаштувати ці звʼязки вручну, змінивши значення цього поля. Однак зазвичай цього не потрібно робити, і можна дозволити Kubernetes автоматично керувати цими звʼязками.

Залежні обʼєкти також мають поле ownerReferences.blockOwnerDeletion, яке має булеве значення і контролює, чи можуть певні залежні обʼєкти блокувати збір сміття, що видаляє їх власника. Kubernetes автоматично встановлює це поле в true, якщо контролер (наприклад, контролер Deployment) встановлює значення поля metadata.ownerReferences. Ви також можете встановити значення поля blockOwnerDeletion вручну, щоб контролювати, які залежні обʼєкти блокують збір сміття.

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

Примітка:

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

Залежні обʼєкти рівня кластера можуть вказувати тільки власників рівня кластера. У v1.20+, якщо залежний обʼєкт рівня кластера вказує як власника тип у межах простору імен, вважається, що він має нерозвʼязне посилання на власника, і його не можна прибрати збором сміття.

У v1.20+, якщо збирач сміття виявляє недійсний ownerReference між просторами імен або залежний обʼєкт рівня кластера з ownerReference, що посилається на тип у межах простору імен, повідомляється про попереджувальну подію з причиною OwnerRefInvalidNamespace та involvedObject недійсного залежного елемента. Ви можете перевірити наявність такого роду подій (Event), запустивши kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace.

Власність та завершувачі

Коли ви наказуєте Kubernetes видалити ресурс, API-сервер дозволяє контролеру, що керує ресурсом, обробити будь-які правила завершувача для ресурсу. Завершувачі запобігають випадковому видаленню ресурсів, які вашому кластеру можуть ще бути потрібні для коректної роботи. Наприклад, якщо ви намагаєтеся видалити PersistentVolume, який все ще використовується Podʼом, видалення не відбувається негайно, оскільки PersistentVolume має завершувач kubernetes.io/pv-protection. Замість цього том залишається в стані Terminating до тих пір, поки Kubernetes не очистить завершувач, що відбувається тільки після того, як PersistentVolume більше не привʼязаний до Podʼа.

Kubernetes також додає завершувачі до ресурсу-власника, коли ви використовуєте або каскадне видалення на передньому плані або каскадне видалення сиріт. Під час видалення на передньому плані додається завершувач foreground, так що контролер повинен видалити залежні ресурси, які також мають ownerReferences.blockOwnerDeletion=true, перш ніж він видалить власника. Якщо ви вказуєте політику видалення покинутих ресурсів (сиріт), Kubernetes додає завершувач orphan, так що контролер ігнорує залежні ресурси після того, як він видаляє обʼєкт-власника.

Що далі

8 - Рекомендовані мітки

Ви можете візуалізувати обʼєкти Kubernetes і керувати ними не лише за допомогою kubectl і панелі керування (dashboard), а й за допомогою інших інструментів. Загальний набір міток дозволяє інструментам працювати між собою, описуючи обʼєкти спільним чином, який можуть розуміти всі інструменти.

Крім підтримки інструментів, рекомендовані мітки описують застосунки так, що до них можна робити запити.

Метадані організовані навколо концепції застосунку. Kubernetes не є платформою як сервіс (PaaS) і не має та не навʼязує формального поняття застосунку. Замість цього застосунки є неформальними та описуються метаданими. Визначення того, що включає застосунок, є гнучким.

Примітка:

Це рекомендовані мітки. Вони полегшують управління застосунками, але не обовʼязкові для будь-яких основних інструментів.

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

Мітки

Щоб повною мірою скористатися цими мітками, їх слід застосовувати до кожного обʼєкта ресурсу.

КлючОписПрикладТип
app.kubernetes.io/nameНазва застосункуmysqlрядок
app.kubernetes.io/instanceУнікальна назва, що ідентифікує екземпляр застосункуmysql-abcxyzрядок
app.kubernetes.io/versionПоточна версія застосунку (наприклад, SemVer 1.0, хеш ревізії тощо)5.7.21рядок
app.kubernetes.io/componentКомпонент всередині архітектуриdatabaseрядок
app.kubernetes.io/part-ofНазва застосунку вищого рівня, частиною якого є цей застосунокwordpressрядок
app.kubernetes.io/managed-byІнструмент, який використовується для управління роботою застосункуHelmрядок

Щоб проілюструвати ці мітки в дії, розгляньте такий обʼєкт StatefulSet:

# Це уривок
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxyz
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
    app.kubernetes.io/managed-by: Helm

Застосунки та екземпляри застосунків

Застосунок можна встановити один або декілька разів у кластер Kubernetes і, у деяких випадках, у той самий простір імен. Наприклад, WordPress можна встановити більше одного разу, де різні вебсайти є різними екземплярами WordPress.

Назва застосунку та назва екземпляра записуються окремо. Наприклад, у WordPress є app.kubernetes.io/name — wordpress, тоді як назва екземпляра представлена як app.kubernetes.io/instance зі значенням wordpress-abcxyz. Це дозволяє ідентифікувати застосунок та його екземпляр. Кожен екземпляр застосунку повинен мати унікальну назву.

Приклади

Щоб проілюструвати різні способи використання цих міток, наведено приклади різної складності.

Простий Stateless Service

Розгляньте випадок простого Stateless Service, розгорнутого за допомогою обʼєктів Deployment та Service. Наведені нижче два уривки представляють, як можуть бути використані мітки у їх найпростішій формі.

Deployment використовується для нагляду за Podʼами, які виконують сам застосунок.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxyz
...

Service використовується для відкриття доступу до застосунку.

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxyz
...

Вебзастосунок із базою даних

Розгляньмо трохи складніший застосунок: вебзастосунок (WordPress) із базою даних (MySQL), встановлений за допомогою Helm. Наведені нижче уривки ілюструють початок обʼєктів, які використовуються для розгортання цього застосунку.

Початок цього Deployment використовується для WordPress:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxyz
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress
...

Service використовується для відкриття доступу до WordPress:

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxyz
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress
...

MySQL представлено як StatefulSet з метаданими як для нього, так і для застосунку, до якого він належить:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxyz
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
...

Service використовується для відкриття доступу до MySQL як частини WordPress:

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxyz
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
...

Зверніть увагу, що StatefulSet та Service для MySQL містять інформацію як про MySQL, так і про WordPress, ширший застосунок.

9 - Версії зберігання

API-сервер Kubernetes зберігає обʼєкти, покладаючись на etcd-сумісне сховище (часто це сам etcd). Кожен обʼєкт серіалізується за допомогою певної версії типу API; наприклад, представлення v1 ConfigMap. Kubernetes використовує термін версія зберігання для опису того, як зберігається обʼєкт у вашому кластері.

API Kubernetes також покладається на автоматичне перетворення; наприклад, якщо у вас є HorizontalPodAutoscaler, то ви можете взаємодіяти з цим HorizontalPodAutoscaler, використовуючи будь-яку комбінацію версій v1 та v2 API HorizontalPodAutoscaler. Kubernetes відповідає за перетворення кожного API-запиту, щоб клієнти не бачили, яка версія насправді серіалізується.

Для адміністраторів кластерів версія зберігання обʼєкта є важливим поняттям для розуміння, оскільки саме вона звʼязує представлення обʼєкта у API з фактичним кодуванням у бекенді сховища. Це може бути важливим у разі, коли певне бінарне кодування обʼєкта має значення, наприклад для шифрування в стані спокою або визнання API застарілим.

Той самий API може мати кілька версій зберігання, які API-сервер може перетворювати на схему обʼєкта. Один обʼєкт, що є частиною цього ресурсу, повинен мати лише одну версію зберігання в будь-який момент часу. Це означає, що API-сервер знає бінарне кодування обʼєктів і може виконувати динамічне перетворення між всіма збереженими версіями до представлення обʼєкта у API.

Версія обʼєкта є повністю відокремленою від версії зберігання. Наприклад, API-обʼєкти v1alpha1 та v1beta1 для того самого ресурсу будуть закодовані однаково в сховищі, доки версія зберігання не буде оновлена між двома обʼєктами.

Відповідність версій зберігання ресурсам

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

Зчитування з API-сервера конвертуватиме збережені дані в API-представлення обʼєкта. Це дозволяє старим версіям зберігання зберігатися необмежений час, доки не відбудуться оновлення обʼєкта. З іншого боку, записи конвертуватимуть збережений обʼєкт у нове представлення після оновлення.

Версії зберігання для власних ресурсів

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

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

Наприклад, див. це CustomResourceDefinition для crontabs:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.example.com
spec:
  group: example.com
  # перелік версій, що підтримуються цим CustomResourceDefinition
  versions:
  - name: v1beta1
    # Кожна версія може бути увімкнена/вимкнена за допомогою прапорця Served.
    served: true
    # Одна і тільки одна версія повинна бути позначена як версія зберігання.
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          host:
            type: string
          port:
            type: string
  - name: v1
    served: true
    storage: false
    schema:
      openAPIV3Schema:
        type: object
        properties:
          host:
            type: string
          port:
            type: string
          time:
            type: string
  conversion:
    strategy: None
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct

Визначення API v1beta1 використовується як версія зберігання, тобто будь-які оновлення або створення crontabs зберігатимуться разом зі схемою обʼєкта API v1beta1. У цьому випадку це фактично означатиме, що обʼєкт API v1 ніколи не зможе зберігати поле time, оскільки воно не є частиною визначення сховища. Ця схема використовується на рівні сховища як двійкове кодування самого обʼєкта. Спроба встановити дві версії як версію, що зберігається, одночасно вважається недійсною, оскільки це означатиме, що дві схеми даних вважатимуться дійсними способами зберігання обʼєктів одночасно.

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

Як версії зберігання впливають на шифрування в стані спокою

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

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

Міграція на іншу версію зберігання

Кілька версій зберігання для одного ресурсу можуть створювати проблеми для адміністраторів кластера. Адміністратор кластера не може видаляти старі версії API для CRD, які можуть не підтримуватися, доки не переконається, що всі обʼєкти більше не використовують повʼязану з ним версію зберігання. Через велику кількість обʼєктів та непрозоре уявлення про те, які з них є новими, а які все ще підтримуються старими версіями зберігання, важко визначити, коли версію можна безпечно видалити. Якщо версію видалено передчасно, обʼєкт може взагалі не вдатися прочитати.

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

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