Podʼи — найменші придатні для розгортання обчислювальні одиниці, які ви можете створювати в Kubernetes і якими можете керувати.
Pod (ім. чол. рід; як у випадку з групою китів або гороховим стручком) — це група з одного або кількох контейнерів, які мають спільні ресурси зберігання та мережі, а також специфікацію щодо того, як запускати контейнери. Вміст Podʼа завжди розміщується та планується разом і працює в спільному контексті. Pod моделює «логічний хост» конкретного застосунку: він містить один або кілька контейнерів застосунку, які відносно тісно повʼязані між собою. Поза хмарним середовищем застосунки, що виконуються на одній фізичній або віртуальній машині, аналогічні хмарним застосункам, що виконуються на одному логічному хості.
Окрім контейнерів застосунків, Pod може містити init-контейнери, які запускаються під час старту Podʼа. Ви також можете впровадити ефемерні контейнери для налагодження запущеного Podʼа.
Спільний контекст Podʼа — це набір просторів імен Linux, cgroups та, можливо, інших аспектів ізоляції — тих самих речей, що забезпечують ізоляцію контейнера. В межах контексту Podʼа окремі застосунки можуть мати додаткові рівні ізоляції.
Pod схожий на набір контейнерів зі спільними просторами імен та спільними томами файлової системи.
Podʼи в кластері Kubernetes використовуються двома основними способами:
Групування в одному Podʼі кількох контейнерів, які розміщені разом і керуються спільно, — відносно складний сценарій використання. Використовуйте цей підхід лише в тих конкретних випадках, коли ваші контейнери тісно повʼязані.
Для забезпечення реплікації (з метою підвищення відмовостійкості або розширення потужності) не потрібно запускати кілька контейнерів; якщо вам потрібно кілька реплік, дивіться Керування навантаженням.
Нижче наведено приклад Podʼа, який складається з контейнера, що запускає образ nginx:1.14.2.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Для створення Podʼа, показаного вище, виконайте таку команду:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Зазвичай Podʼи не створюють напряму, а створюють за допомогою ресурсів робочих навантажень. Дивіться Робота з Podʼами, щоб дізнатися більше про те, як Podʼи використовуються разом з ресурсами робочих навантажень.
Зазвичай вам не потрібно створювати Podʼи напряму, навіть одиничні Podʼи. Натомість створюйте їх за допомогою ресурсів робочих навантажень, таких як Deployment або Job. Якщо ваші Podʼи потребують відстеження стану, розгляньте використання ресурсу StatefulSet.
Кожен Pod призначений для запуску одного екземпляра певного застосунку. Якщо ви хочете масштабувати свій застосунок горизонтально (щоб надати більше ресурсів загалом, запустивши більше екземплярів), вам слід використовувати кілька Podʼів, по одному для кожного екземпляра. У Kubernetes це зазвичай називається реплікацією. Репліковані Podʼи зазвичай створюються ресурсом робочого навантаження та його контролером, які й керують ними як групою.
Ознайомтесь з розділом Podʼи та контролери для отримання додаткової інформації про те, як Kubernetes використовує ресурси робочих навантажень та їх контролери для реалізації масштабування та автоматичного відновлення роботи застосунку.
Podʼи мають вбудовану підтримку двох видів спільних ресурсів для контейнерів, що входять до їх складу: мережі та зберігання.
Ви навряд чи створюватимете окремі Podʼи напряму в Kubernetes, навіть одиничні Podʼи. Це тому, що Podʼи спроєктовано як відносно ефемерні, одноразові сутності. Коли Pod створено (безпосередньо вами або опосередковано контролером), новий Pod планується до запуску на вузлі вашого кластера. Pod залишається на цьому вузлі, доки не завершить виконання, доки обʼєкт Pod не буде видалено, доки Pod не буде виселено через брак ресурсів або доки вузол не зазнає збою.
Назва Podʼа має бути дійсним DNS-піддоменом, але це може призвести до неочікуваних результатів для імені хоста Podʼа. Для найкращої сумісності назва має відповідати суворішим правилам для DNS-мітки.
Ви маєте встановити значення поля .spec.os.name як windows або linux, щоб визначити операційну систему, яку потребують контейнери в цьому Podʼі. Наразі це єдині операційні системи, які підтримує Kubernetes. У майбутньому цей список може бути розширено.
kubelet відмовляється запускати Pod, якщо значення .spec.os.name не збігається з операційною системою вузла. Однак у Kubernetes v1.37 значення .spec.os.name не впливає на те, як kube-scheduler обирає вузол для запуску Podʼа. У будь-якому кластері, де вузли працюють під керуванням більш ніж однієї операційної системи, слід правильно встановити мітку kubernetes.io/os на кожному вузлі та визначати Podʼи з nodeSelector на основі мітки операційної системи. Якщо ви не вкажете nodeSelector на основі ОС, kube-scheduler може призначити Pod на вузол, ОС якого не підходить для його контейнерів. Стандарти безпеки Podʼів також використовують поле .spec.os.name, щоб уникнути застосування політик, які не стосуються цієї операційної системи.
Ви можете використовувати ресурси робочих навантажень, щоб створювати кілька Podʼів і керувати ними. Контролер ресурсу опікується реплікацією, розгортанням та автоматичним відновленням у разі збою Podʼа. Наприклад, якщо вузол зазнає збою, контролер помічає, що Podʼи на цьому вузлі перестали працювати, і створює Pod-замінник. Планувальник розміщує Pod-замінник на справному вузлі.
Ось кілька прикладів ресурсів робочих навантажень, які керують одним чи більше Podʼами:
To use this feature, you (or a cluster administrator) will need to enable the GenericWorkload feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Стандартно Kubernetes планує кожний Pod окремо. Однак деякі тісно повʼязані застосунки потребують одночасного планування групи Podʼів для коректної роботи.
Ви можете повʼязати Pod з PodGroup за допомогою поля групи планування (spec.schedulingGroup). Це повідомляє kube-scheduler, що Pod належить до певної групи, і дає йому змогу застосовувати скоординовані рішення щодо розміщення на рівні групи одразу для всієї групи.
Контролери ресурсів робочих навантажень створюють Podʼи із шаблону Podʼа (pod template) та керують цими Podʼами від вашого імені.
PodTemplate — це специфікації для створення Podʼів, які входять до складу ресурсів робочих навантажень, таких як Deployments, Jobs та DaemonSets.
Кожен контролер ресурсу робочого навантаження використовує PodTemplate всередині обʼєкта робочого навантаження для створення фактичних Podʼів. PodTemplate є частиною бажаного стану будь-якого ресурсу робочого навантаження, який ви використовуєте для запуску вашого застосунку.
Коли ви створюєте Pod, ви можете додати змінні середовища до шаблону Podʼа для контейнерів, які запускаються в Podʼі.
Нижче наведено маніфест простого Job із template, який запускає один контейнер. Контейнер в цьому Podʼі виводить повідомлення, а потім призупиняється.
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# Це шаблон Podʼа
spec:
containers:
- name: hello
image: busybox:1.28
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# Кінець шаблону Podʼа
Зміна шаблону Podʼа або перемикання на новий шаблон не має прямого впливу на Podʼи, які вже існують. Якщо ви змінюєте шаблон Podʼа для ресурсу робочого навантаження, цей ресурс має створити Podʼи-замінники, які використовують оновлений шаблон.
Наприклад, контролер StatefulSet переконується, що запущені Podʼи відповідають поточному шаблону Podʼа для кожного обʼєкта StatefulSet. Якщо ви редагуєте StatefulSet, щоб змінити його шаблон Podʼа, StatefulSet починає створювати нові Podʼи на основі оновленого шаблону. Зрештою всі старі Podʼи замінюються новими, і оновлення завершується.
Кожен ресурс робочого навантаження реалізує власні правила для обробки змін у шаблоні Podʼа. Якщо ви хочете дізнатися більше саме про StatefulSet, прочитайте розділ Стратегія оновлення у навчальному матеріалі «Основи StatefulSet».
На вузлах kubelet безпосередньо не спостерігає за жодними деталями шаблонів Podʼів та оновлень і не керує ними; ці деталі абстраговані. Ця абстракція та розділення відповідальностей спрощує семантику системи та робить можливим розширення поведінки кластера без зміни наявного коду.
Як зазначено в попередньому розділі, коли шаблон Podʼа для ресурсу робочого навантаження змінюється, контролер створює нові Podʼи на основі оновленого шаблону замість оновлення наявних Podʼів або застосування до них патчів.
Kubernetes не забороняє вам керувати Podʼами напряму. Ви можете оновлювати деякі поля запущеного Podʼа на місці. Однак операції оновлення Podʼа, такі як patch та replace, мають деякі обмеження:
namespace, name, uid або creationTimestamp.metadata.deletionTimestamp встановлено, новий запис не може бути доданий до списку metadata.finalizers.spec.containers[*].image, spec.initContainers[*].image, spec.activeDeadlineSeconds, spec.terminationGracePeriodSeconds, spec.tolerations або spec.schedulingGates. Для spec.tolerations ви можете додавати лише нові записи.spec.activeDeadlineSeconds дозволені два типи оновлень:Наведені вище правила оновлення застосовуються до звичайних оновлень Podʼів, але інші поля Podʼа можна оновлювати через субресурси.
resize дозволяє оновлювати ресурси контейнерів (spec.containers[*].resources). Дивіться Зміна розміру ресурсів контейнера для більш детальної інформації.ephemeralContainers дозволяє додавати ефемерні контейнери до Podʼа. Дивіться Ефемерні контейнери для більш детальної інформації.status дозволяє оновлювати статус Podʼа. Зазвичай його використовують лише kubelet та інші системні контролери.binding дозволяє встановити spec.nodeName Podʼа за допомогою запиту Binding. Зазвичай його використовує лише планувальник.metadata.generation є унікальним. Воно автоматично встановлюється системою таким чином, що нові Podʼи мають значення metadata.generation, рівне 1, і кожне оновлення змінюваних полів у специфікації Podʼа збільшуватиме значення metadata.generation на 1.This is a stable feature in Kubernetes, and has been since version v1.35. It was first available in the v1.33 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate PodObservedGenerationTracking, Kubernetes ignores it but does not report any error.
observedGeneration — це поле, яке фіксується в розділі status обʼєкта Pod. kubelet встановлює status.observedGeneration, щоб повʼязати стан Podʼа з його поточним статусом. Поле status.observedGeneration Podʼа відображатиме metadata.generation Podʼа в момент, коли повідомляється про статус Podʼа.status.observedGeneration керує kubelet, і зовнішні контролери не повинні його змінювати.Різні поля статусу можуть бути повʼязані або з metadata.generation поточного циклу синхронізації, або з metadata.generation попереднього циклу синхронізації. Ключова відмінність полягає в тому, чи зміна в spec відображається безпосередньо в status, чи є опосередкованим результатом запущеного процесу.
Для полів статусу, у яких безпосередньо відображається виділена специфікація, observedGeneration буде повʼязано з поточним metadata.generation (покоління N).
Ця поведінка застосовується до:
Waiting.Для полів статусу, які є опосередкованим результатом виконання специфікації, observedGeneration буде повʼязано з metadata.generation попереднього циклу синхронізації (покоління N-1).
Ця поведінка застосовується до:
ContainerStatus.ImageID показує образ з попереднього покоління, поки новий образ не буде завантажено, а контейнер не буде оновлено.Podʼи дають змогу контейнерам, що входять до їх складу, спільно використовувати дані та взаємодіяти між собою.
Pod може визначати набір спільних томів. Всі контейнери в Podʼі можуть отримати доступ до спільних томів, що дозволяє цим контейнерам спільно використовувати дані. Також томи дають змогу постійним даним у Podʼі зберегтися, якщо один із його контейнерів доведеться перезапустити. Дивіться розділ Зберігання для отримання додаткової інформації про те, як Kubernetes реалізує спільне зберігання та робить його доступним для Podʼів.
Кожному Podʼу присвоюється унікальна IP-адреса для кожного сімейства адрес. Кожен контейнер у Podʼі використовує спільний мережевий простір імен, що включає IP-адресу та мережеві порти. Всередині Podʼа (і тільки там) контейнери, що належать до Podʼа, можуть спілкуватися один з одним за допомогою localhost. Коли контейнери в Podʼі спілкуються із сутностями поза межами Podʼа, вони повинні координувати використання спільних мережевих ресурсів (таких як порти). Всередині Podʼа контейнери використовують спільну IP-адресу та простір портів і можуть знаходити один одного через localhost. Контейнери в Podʼі також можуть спілкуватися між собою, використовуючи стандартні засоби міжпроцесної комунікації, такі як семафори SystemV або спільну памʼять POSIX. Контейнери в різних Podʼах мають різні IP-адреси і не можуть спілкуватися за допомогою IPC на рівні ОС без спеціальної конфігурації. Контейнери, які хочуть взаємодіяти з контейнером, що працює в іншому Podʼі, можуть використовувати IP-мережу для спілкування.
Контейнери в межах Podʼа сприймають імʼя хоста системи як імʼя, що збігається з налаштованим name для Podʼа. Більше інформації про це можна знайти в розділі Мережа в кластері.
Щоб встановити обмеження безпеки для Podʼів і контейнерів, використовуйте поле securityContext у специфікації Podʼа. Це поле дає вам можливість детально контролювати, що може робити Pod або окремі контейнери. Докладнішу інформацію див. у розділі Розширена конфігурація Podʼів.
Для базової конфігурації безпеки слід дотримуватися стандарту безпеки Podʼів Baseline та запускати контейнери з правами, відмінними від root. Ви можете налаштувати прості контексти безпеки:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: sec-ctx-demo
image: busybox
command: ["sh", "-c", "sleep 1h"]
Щоб дізнатися про розширені налаштування контексту безпеки, зокрема про можливості (capabilities), профілі seccomp та детальні параметри безпеки, перейдіть до розділу Концепції безпеки.
Коли ви визначаєте Pod, ви можете за бажанням вказати, скільки кожного ресурсу потрібно контейнеру. Найчастіше вказують CPU та памʼять (RAM).
Коли ви вказуєте запит ресурсу (request) для контейнерів у Podʼі, kube-scheduler використовує цю інформацію щоб визначити, на якому вузлі розмістити Pod. Коли ви вказуєте обмеження ресурсу (limit) для контейнера, kubelet забезпечує дотримання цих обмежень, щоб запущений контейнер не міг використовувати більше цього ресурсу, ніж встановлене вами обмеження.
Обмеження CPU застосовуються через тротлінг CPU. Коли контейнер наближається до свого обмеження CPU, ядро обмежує його доступ до CPU. Обмеження памʼяті застосовуються ядром через завершення процесів за нестачі памʼяті (OOM kills), коли контейнер перевищує своє обмеження.
Детальнішу інформацію про одиниці ресурсів, механізми застосування обмежень та приклади конфігурації дивіться у розділі Керування ресурсами Podʼів та контейнерів.
Статичні Podʼи керуються безпосередньо демоном kubelet на конкретному вузлі, без спостереження за ними з боку API-сервера. У той час як більшістю Podʼів керує панель управління (наприклад, Deployment), для статичних Podʼів kubelet безпосередньо наглядає за кожним статичним Podʼом (та перезапускає його, якщо він зазнає збою).
Статичні Podʼи завжди привʼязані до одного kubelet на конкретному вузлі. Основне призначення статичних Podʼів — запуск самостійно розміщеної панелі управління: іншими словами, використання kubelet для нагляду за окремими компонентами панелі управління.
За докладнішою інформацією звертайтесь до розділу Статичні Podʼи.
Podʼи спроєктовано для підтримки кількох взаємодіючих процесів (у вигляді контейнерів), які утворюють єдину цілісну одиницю сервісу. Контейнери в Podʼі автоматично розміщуються та плануються разом на одній фізичній або віртуальній машині в кластері. Контейнери можуть спільно використовувати ресурси та залежності, взаємодіяти між собою та координувати, коли та як вони завершують роботу.
Podʼи в кластері Kubernetes використовуються двома основними способами:
Наприклад, у вас може бути контейнер, який виконує функції вебсервера для файлів у спільному томі, та окремий sidecar-контейнер, який оновлює ці файли з віддаленого джерела, як показано на цій діаграмі:
Деякі Podʼи мають init-контейнери та контейнери застосунку. Стандартно init-контейнери запускаються та завершують роботу до запуску контейнерів застосунку.
У вас також можуть бути sidecar-контейнери, які надають допоміжні сервіси основному Podʼу застосунку (наприклад, service mesh).
This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.28 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate SidecarContainers, Kubernetes ignores it but does not report any error.
Стандартно увімкнена функціональна можливість SidecarContainers дозволяє вказати restartPolicy: Always для init-контейнерів. Встановлення політики перезапуску Always гарантує, що контейнери, для яких ви її встановили, вважатимуться sidecar-контейнерами, що працюють протягом усього життєвого циклу Podʼа. Контейнери, які ви явно визначаєте як sidecar-контейнери, запускаються перед основним Podʼом застосунку та працюють, доки Pod не завершить роботу.
Проба — це діагностика, яку kubelet періодично виконує для контейнера. Для виконання діагностики kubelet може використовувати різні дії:
ExecAction (виконується за допомогою середовища виконання контейнерів)TCPSocketAction (перевіряється безпосередньо kubelet)HTTPGetAction (перевіряється безпосередньо kubelet)Ви можете дізнатися більше про проби в документації про життєвий цикл Podʼа.
Для розуміння контексту того, чому Kubernetes обгортає загальний API Pod іншими ресурсами (такими як StatefulSets або Deployments), ви можете ознайомитися з попередніми розробками, зокрема: