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

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

Контейнери

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

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

Слово контейнер є дуже перевантаженим терміном. Щоразу, коли ви використовуєте це слово, перевіряйте, чи ваша аудиторія використовує те саме визначення.

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

Контейнери відокремлюють застосунки від базової інфраструктури хоста. Це полегшує розгортання в різних хмарних або ОС-середовищах.

Кожен вузол в кластері Kubernetes запускає контейнери, які формують Podʼи, призначені цьому вузлу. Контейнери в Podʼі розташовуються та плануються разом, щоб запускатися на тому самому вузлі.

Образи контейнерів

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

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

Середовище виконання контейнерів

Основний компонент, який дозволяє Kubernetes ефективно запускати контейнери. Він відповідає за керування виконанням і життєвим циклом контейнерів у середовищі Kubernetes.

Kubernetes підтримує середовища виконання контейнерів, такі як containerd, CRI-O, та будь-яку іншу реалізацію Kubernetes CRI (інтерфейс виконання контейнерів).

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

Ви також можете використовувати RuntimeClass для запуску різних Podʼів з однаковим середовищем виконання контейнерів, але з різними налаштуваннями.

1 - Середовище контейнера

Ця сторінка описує ресурси, доступні контейнерам в середовищі контейнера.

Середовище контейнера

Середовище контейнера Kubernetes надає кілька важливих ресурсів контейнерам:

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

Інформація про контейнер

hostname контейнера — це назва Podʼа, в якому він працює. Вона доступна через команду hostname або виклик функції gethostname у бібліотеці libc.

Назва та простір імен Podʼа доступні як змінні середовища через downward API.

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

Інформація про кластер

Список всіх сервісів, які були активні під час створення контейнера, доступний цьому контейнеру як змінні середовища. Цей список обмежений сервісами в межах того ж простору імен, що й новий Pod контейнера, та сервісами панелі управління Kubernetes.

Для сервісу з назвою foo, який експонує набір Podʼів, кожен з яких виконує контейнер із назвою bar, визначаються такі змінні:

FOO_SERVICE_HOST=<хост, на якому працює сервіс>
FOO_SERVICE_PORT=<порт, на якому працює сервіс>

Сервіси мають виділені IP-адреси, які доступні для контейнера через DNS, якщо увімкнено надбудову DNS.

Що далі

2 - Хуки життєвого циклу контейнера

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

Огляд

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

Хуки контейнера

Контейнерам доступні два хуки:

PostStart

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

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

Примітка:

Хоча хук працює одночасно з процесом контейнера, він може затримувати оновлення статусу контейнера; контейнер може не переходити в стан Running до завершення роботи хука.

PreStop

Цей хук викликається негайно перед тим, як контейнер буде завершено через запит API або подію управління, таку як невдача проби на живучість/запуску, витіснення, конкуренція за ресурси та інші. Виклик хука PreStop не вдасться, якщо контейнер вже перебуває у стані terminated або completed, і хук повинен завершити виконання до того, як може бути відправлений сигнал TERM для зупинки контейнера. Відлік пільгового періоду припинення Podʼа починається до виконання хука PreStop, тому, незалежно від результату обробника, контейнер врешті-решт завершиться протягом пільгового періоду припинення Podʼа. Жодні параметри не передаються обробнику.

Докладний опис поведінки припинення роботи Podʼів можна знайти в Припинення роботи Podʼа.

StopSignal

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

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

Реалізації обробника хуків

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

  • Exec — Виконує конкретну команду, таку як pre-stop.sh, всередині cgroups та namespaces контейнера. Ресурси, спожиті командою, зараховуються на рахунок контейнера.
  • HTTP — Виконує HTTP-запит до конкретного endpoint в контейнері.
  • Sleep — Призупиняє контейнер на вказаний час.

Виконання обробника хука

Коли викликається хук управління життєвим циклом контейнера, система управління Kubernetes виконує обробник відповідно до дії хука: httpGet, tcpSocket (застаріло) та sleep виконуються процесом kubelet, а exec виконується в контейнері.

Виклик обробника хука PostStart ініціюється при створенні контейнера, тобто точка входу контейнера ENTRYPOINT і хук PostStart спрацьовують одночасно. (Це означає, що, як правило, не має сенсу використовувати HTTP-хук для PostStart, оскільки немає гарантії, що процес контейнера буде повністю запущений, коли хук запуститься.) Якщо хук PostStart виконується занадто довго або зависає, це може завадити контейнеру перейти у стан running.

Хуки PreStop не викликаються асинхронно від сигналу зупинки контейнера; хук повинен завершити своє виконання до того, як може бути відправлений сигнал TERM. Якщо хук PreStop зависає під час виконання, фаза Podʼа буде Terminating і залишиться такою, поки Pod не буде вбито після закінчення його terminationGracePeriodSeconds. Цей період припинення роботи застосовується до загального часу, необхідного як для виконання хука PreStop, так і для зупинки контейнера. Якщо, наприклад, terminationGracePeriodSeconds дорівнює 60, і хук займає 55 секунд для завершення, а контейнер зупиняється нормально через 10 секунд після отримання сигналу, то контейнер буде вбитий перш, ніж він зможе завершити роботу, оскільки terminationGracePeriodSeconds менше, ніж загальний час (55+10), необхідний для цих двох подій.

Якщо хук PostStart або PreStop завершується збоєм, контейнер буде вбито.

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

Гарантії доставки хуків

Доставка хука має відбуватися щонайменше один раз, що означає, що хук може бути викликано кілька разів для будь-якої події, такої як для PostStart чи PreStop. Реалізація хука повинна правильно це обробляти.

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

Налагодження обробників хуків

Логи обробника хука не відображаються в подіях Podʼа. Якщо обробник зазнає збою з будь-якої причини, він розсилає подію. Для PostStart це подія FailedPostStartHook, а для PreStop це подія FailedPreStopHook. Щоб самостійно згенерувати подію FailedPostStartHook, змініть файл lifecycle-events.yaml, замінивши команду postStart на "badcommand", і застосуйте його. Ось приклад виводу події, який ви побачите після виконання kubectl describe pod lifecycle-demo:

Events:
  Type     Reason               Age              From               Message
  ----     ------               ----             ----               -------
  Normal   Scheduled            7s               default-scheduler  Successfully assigned default/lifecycle-demo to ip-XXX-XXX-XX-XX.us-east-2...
  Normal   Pulled               6s               kubelet            Successfully pulled image "nginx" in 229.604315ms
  Normal   Pulling              4s (x2 over 6s)  kubelet            Pulling image "nginx"
  Normal   Created              4s (x2 over 5s)  kubelet            Created container lifecycle-demo-container
  Normal   Started              4s (x2 over 5s)  kubelet            Started container lifecycle-demo-container
  Warning  FailedPostStartHook  4s (x2 over 5s)  kubelet            Exec lifecycle hook ([badcommand]) for Container "lifecycle-demo-container" in Pod "lifecycle-demo_default(30229739-9651-4e5a-9a32-a8f1688862db)" failed - error: command 'badcommand' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: \"badcommand\": executable file not found in $PATH: unknown\r\n"
  Normal   Killing              4s (x2 over 5s)  kubelet            FailedPostStartHook
  Normal   Pulled               4s               kubelet            Successfully pulled image "nginx" in 215.66395ms
  Warning  BackOff              2s (x2 over 3s)  kubelet            Back-off restarting failed container

Що далі