Проби життєздатності, готовності та запуску
Kubernetes дозволяє визначати проби для безперервного моніторингу стану контейнерів у Podʼі. Проба — це діагностична перевірка контейнера, яку періодично виконує kubelet. Для виконання діагностики kubelet або виконує код всередині контейнера, або робить мережевий запит.
На основі результатів проб Kubernetes може перезапускати нездорові контейнери або припиняти надсилання трафіку до контейнерів, які не готові.
Типи проб
Kubelet може виконувати та реагувати на три види проб у працюючих контейнерах, кожна з яких виконує різну функцію, це:
Проба запуску
Проби запуску перевіряють, чи застосунок у контейнері запущено. Якщо проба запуску налаштована, Kubernetes не виконує проби життєздатності або готовності, поки проба запуску не буде успішною, що дозволяє застосунку завершити ініціалізацію.
Цей тип проб виконується лише під час запуску, на відміну від проб життєздатності та готовності, які виконуються періодично. Якщо проба запуску завершується невдало, kubelet припиняє роботу контейнера, і до нього застосовується відповідна політика перезапуску.
- Докладніше про Налаштування проб життєздатності, готовності та запуску.
Проба життєздатності
Проби життєздатності (Liveness) визначають, коли слід перезапустити контейнер. Наприклад, проби життєздатності можуть виявити ситуацію взаємного блокування, коли програма працює, але не може продовжувати роботу. Перезапуск контейнера в такому стані допомагає забезпечити більшу доступність застосунку, незважаючи на наявність помилок.
Якщо контейнеру не вдається пройти пробу життєздатності більше разів, ніж передбачено налаштованим порогом, kubelet перезапускає контейнер. Проби життєздатності не чекають, поки проби готовності будуть успішними. Якщо ви хочете почекати перед виконанням проби життєздатності, ви можете визначити initialDelaySeconds або використовувати пробу запуску.
Увага:
Проби життєздатності можуть бути ефективним засобом відновлення після збоїв у роботі застосунків, проте їх слід застосовувати з обережністю. Проби життєздатності необхідно ретельно налаштовувати, щоб гарантувати, що вони дійсно вказують на незворотний збій у роботі застосунку, наприклад, на взаємне блокування.
Неправильна реалізація проб життєздатності може призвести до каскадних збоїв. Це призводить до перезапуску контейнера під високим навантаженням; відхилення запитів клієнтів, оскільки ваш застосунок стає менш масштабованим; та збільшення навантаження на решту подів через деякі несправні поди. Потрібно розуміти різницю між пробами життєздатності та пробами готовності, а також коли їх застосовувати для вашого застосунку.
Проба готовності
Проби готовності визначають, коли контейнер готовий приймати трафік. Вони корисні, коли застосунок очікує на виконання трудомістких початкових завдань встановлення мережевих зʼєднань, завантаження файлів і наповнення кешу. Проби готовності також можуть бути корисними на більш пізніх етапах життєвого циклу контейнера, наприклад, при відновленні після тимчасових збоїв або перевантажень.
Якщо проба готовності повертає неуспішний стан, контролер EndpointSlice видаляє IP-адресу Podʼа з EndpointSlices усіх Сервісів, які мають збіг з Podʼом.
Проби готовності виконуються в контейнері протягом всього його життєвого циклу.
Примітка:
Якщо ви хочете мати можливість скидати запити під час видалення Podʼа, вам не обов’язково потрібена проба готовності; коли Pod видаляється, відповідна точка доступу в EndpointSlice оновить свої стани: стан готовності точки доступу буде встановлено на false, тому балансувальники навантаження не використовуватимуть Pod для звичайного трафіку. Дивіться Припинення роботи Podʼа для отримання додаткової інформації про те, як kubelet обробляє видалення Podʼа.Коли використовувати кожну пробу
Коли слід використовувати пробу запуску?
Проби запуску корисні для Podʼів, які мають контейнери, що довго запускаються. Замість того, щоб встановлювати довгий інтервал життєздатності, ви можете налаштувати окрему конфігурацію для перевірки контейнера під час його запуску, дозволяючи час довший, ніж дозволяє інтервал життєздатності.
Якщо ваш контейнер зазвичай запускається більше ніж \( initialDelaySeconds + failureThreshold \times periodSeconds \), слід вказати пробу запуску, яка перевіряє ту саму точку доступу, що й проба життєздатності. Стандартне значення для periodSeconds становить 10 секунд. Потім слід встановити failureThreshold достатньо високим, щоб дозволити контейнеру запуститися, не змінюючи стандартне значення для проби життєздатності. Це допомагає захиститися від блокувань.
Коли слід використовувати пробу життєздатності?
Якщо процес у вашому контейнері може самостійно завершуватися при виникненні проблем або погіршенні стану, вам не обов’язково потрібна проба життєздатності; kubelet автоматично виконає правильну дію відповідно до restartPolicy Podʼа.
Якщо ви хочете, щоб ваш контейнер був завершений і перезапущений у разі невдачі проби, тоді використовуйте пробу життєздатності та встановіть restartPolicy на Always або OnFailure.
Поширеним підходом для проб життєздатності є використання того самого низьковитратної точки доступу HTTP, що й для проб готовності, але з вищим failureThreshold. Це забезпечує, що Pod буде вважатися неготовим протягом певного часу перед примусовим завершенням його існування.
Коли слід використовувати пробу готовності?
Щоб почати надсилати трафік до Podʼа лише після успішного проходження проби, вкажіть пробу готовності. Проба готовності може бути такою ж, як і проба життєздатності, але наявність проби готовності в специфікації означає, що Pod почне працювати без отримання трафіку і почне отримувати трафік лише після того, як проба почне успішно проходити.
Ви також можете використовувати пробу готовності, щоб дозволити контейнеру самостійно зупинятися для обслуговування, перевіряючи точку доступу, специфічну для проби готовності, яка відрізняється від проби життєздатності.
Коли ваш застосунок має строгі залежності від бекенд-сервісів, ви можете реалізувати як пробу життєздатності, так і пробу готовності. Проба життєздатності проходить, коли сам застосунок є справним, але проба готовності додатково перевіряє, чи доступний кожен необхідний бекенд-сервіс. Це допомагає уникнути направлення трафіку до Podʼів, які можуть відповідати лише повідомленнями про помилки.
Для контейнерів, яким потрібно працювати з великими обсягами даних, конфігураційними файлами або міграціями під час запуску, розгляньте можливість використання проби запуску. Однак, якщо ви хочете визначити різницю між застосунком, який зазнав невдачі, і застосунком, який все ще обробляє свої стартові дані, можливо, вам більше підійде проба готовності.
Механізми перевірки
Існує чотири різні способи перевірки контейнера за допомогою проб. Кожна проба повинна визначати точно один із цих чотирьох механізмів:
exec- Виконує вказану команду всередині контейнера. Діагностика вважається успішною, якщо команда завершується з кодом стану 0.
grpc- Виконує віддалений виклик процедури за допомогою gRPC. Цільовий обʼєкт повинен реалізовувати gRPC health checks. Діагностика вважається успішною, якщо
statusвідповіді дорівнюєSERVING. Для отримання додаткової інформації див. gRPC-проби. httpGet- Виконує HTTP
GETзапит до IP-адреси Podʼа на вказаному порту та шляху. Діагностика вважається успішною, якщо відповідь має код стану від 200 до 399 включно. Для отримання додаткової інформації див. HTTP-проби. tcpSocket- Виконує перевірку TCP на IP-адресу Podʼа на вказаному порту. Діагностика вважається успішною, якщо порт відкритий. Якщо віддалена система (контейнер) закриває зʼєднання відразу після його відкриття, це також вважається здоровим. Для отримання додаткової інформації див. TCP-проби.
Увага:
На відміну від інших механізмів, реалізаціяexec проби передбачає створення/відгалуження кількох процесів щоразу при виконанні. В результаті, у випадку кластерів з високою щільністю Podʼів, меншими інтервалами initialDelaySeconds, periodSeconds, налаштування будь-якої проби з механізмом exec може призвести до збільшення навантаження на CPU вузла. У таких сценаріях розгляньте можливість використання альтернативних механізмів проб, щоб уникнути перенавантаження.Результати проб
Kubelet оцінює результат виконання кожної проби та діє відповідно. Кожна проба має один із трьох результатів:
Success- Контейнер пройшов діагностику.
Failure- Контейнер не пройшов діагностику. Для проб життєздатності та запуску kubelet kubelet припиняє роботу контейнера, і до нього застосовується відповідна політика перезапуску. Для проб готовності kubelet позначає контейнер як неготовий, і Pod перестає отримувати трафік від відповідних сервісів.
Unknown- Діагностика не вдалася (жодних дій не слід виконувати, kubelet здійснить подальші перевірки).
Якщо контейнер не надає певну пробу, kubelet завжди вважає результат як Success. Для проб готовності, зокрема, результат вважається Failure до закінчення початкової затримки.
Поля конфігурації
Проби мають ряд полів, які можна використовувати для більш точного контролю поведінки перевірок запуску, життєздатності та готовності. Наприклад:
apiVersion: v1
kind: Pod
metadata:
name: probe-example
spec:
containers:
- name: app
image: registry.k8s.io/e2e-test-images/agnhost:2.40
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
initialDelaySeconds- Кількість секунд після запуску контейнера, перш ніж будуть ініційовані проби запуску, життєздатності або готовності. Якщо визначена проба запуску, затримки проб життєздатності та готовності не починаються, поки проба запуску не буде успішною. У деяких старих версіях Kubernetes initialDelaySeconds може ігноруватися, якщо periodSeconds було встановлено на значення більше, ніж initialDelaySeconds. Однак у поточних версіях initialDelaySeconds завжди враховується, і проба не почнеться до закінчення цієї початкової затримки. Стандартне значення — 0 секунд. Мінімальне значення — 0.
periodSeconds- Як часто (у секундах) виконувати пробу. Стандартно — 10 секунд. Мінімальне значення — 1. Поки контейнер не готовий, проба готовності може виконуватися в інший час, ніж налаштований інтервал
periodSeconds. Це робиться для того, щоб Pod став готовим швидше. timeoutSeconds- Кількість секунд, після яких проба вважається такою, що перевищила час очікування. Стандартне значення — 1 секунда. Мінімальне значення — 1.
successThreshold- Мінімальна кількість послідовних успішних спроб, щоб проба вважалася успішною після невдачі. Стандартне значення — 1. Для проб життєздатності та запуску має бути 1. Мінімальне значення — 1.
failureThreshold- Після того, як проба не вдалася
failureThresholdразів поспіль, Kubernetes вважає, що загальна перевірка не вдалася: контейнер не готовий/справний/живий. Стандартне значення — 3. Мінімальне значення — 1. У випадку проби запуску або життєздатності, якщо принаймніfailureThresholdпроб не вдалося, Kubernetes вважає контейнер несправним і запускає перезапуск для цього конкретного контейнера. Kubelet дотримується налаштуванняterminationGracePeriodSecondsдля цього контейнера. Для невдалої проби готовності kubelet продовжує запускати контейнер, який не пройшов перевірку, і також продовжує виконувати інші проби; оскільки перевірка не вдалася, kubelet встановлює станReadyдля Podʼа у значенняfalse. terminationGracePeriodSeconds- Налаштуйте період очікування для kubelet між ініціюванням завершення роботи несправного контейнера та примусовим зупиненням цього контейнера середовищем виконання контейнера. Зазвичай успадковується значення на рівні Podʼа для
terminationGracePeriodSeconds(30 секунд, якщо не вказано), а мінімальне значення — 1. Див. probe-levelterminationGracePeriodSecondsдля детальнішої інформації.
Увага:
Неправильна реалізація проб готовності може призвести до постійного зростання кількості процесів у контейнері та вичерпання ресурсів, якщо це залишити без контролю.Значення terminationGracePeriodSeconds на рівні проб
Kubernetes v1.28 [stable]У версіях 1.25 і вище користувачі можуть вказати terminationGracePeriodSeconds на рівні проби як частину специфікації проби. Коли встановлені обидва значення terminationGracePeriodSeconds на рівні Podʼа і проби, kubelet використовує значення на рівні проби.
При встановленні terminationGracePeriodSeconds зверніть увагу на наступне:
- Kubelet завжди враховує поле
terminationGracePeriodSecondsна рівні проби, якщо воно присутнє в Podʼі. - Якщо у вас є в наявності Podʼи, де встановлено поле
terminationGracePeriodSeconds, і ви більше не бажаєте використовувати періоди очікування завершення роботи на рівні проби, вам потрібно видалити ці Podʼи.
Наприклад:
spec:
terminationGracePeriodSeconds: 3600 # рівень Podʼа
containers:
- name: test
image: ...
ports:
- name: liveness-port
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 60
# Перевизначення значення terminationGracePeriodSeconds на рівні Podʼа
terminationGracePeriodSeconds: 60
Значення terminationGracePeriodSeconds на рівні проби не може бути встановлено для проб готовності. Воно буде відхилено сервером API.
Деталі механізму проб
HTTP-проби
HTTP-проби мають додаткові поля, які можна встановити в httpGet:
host: Імʼя хосту для підключення, зазвичай використовується IP-адреса Podʼа. Ймовірно, ви захочете встановити "Host" уhttpHeadersзамість цього.scheme: Схема для підключення до хоста (HTTP або HTTPS). Зазвичай "HTTP".path: Шлях для доступу до HTTP-сервера. Зазвичай "/".httpHeaders: Власні заголовки для встановлення в запиті. HTTP дозволяє повторювані заголовки.port: Імʼя або номер порту для доступу до контейнера. Номер повинен бути в діапазоні від 1 до 65535.
Для HTTP-проби kubelet надсилає HTTP-запит на вказаний порт і шлях для виконання перевірки. Kubelet надсилає пробу на IP-адресу Podʼа, якщо адреса не перевизначена за допомогою необовʼязкового поля host у httpGet. Якщо поле scheme встановлено в HTTPS, kubelet надсилає HTTPS-запит, пропускаючи перевірку сертифіката. У більшості сценаріїв ви не захочете встановлювати поле host. Ось один сценарій, де ви б його встановили. Припустимо, контейнер слухає на 127.0.0.1, а поле hostNetwork Podʼа встановлено в true. Тоді host у httpGet слід встановити на 127.0.0.1. Якщо ваш pod покладається на віртуальні хости, що, ймовірно, є більш поширеним випадком, ви не повинні використовувати host, а натомість встановити заголовок Host у httpHeaders.
Для HTTP-проби kubelet надсилає два заголовки запиту на додачу до обовʼязкового заголовка Host:
User-Agent, який зазвичай встановлено вkube-probe/1.35, де1.35— це версія kubelet.Accept, який зазвичай встановлено в*/*.
Ви можете перевизначити ці заголовки, визначивши httpHeaders для проби. Наприклад:
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
startupProbe:
httpGet:
httpHeaders:
- name: User-Agent
value: MyUserAgent
Ви також можете видалити ці два заголовки, визначивши їх з порожнім значенням.
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: ""
startupProbe:
httpGet:
httpHeaders:
- name: User-Agent
value: ""
Обробка перенаправлень
Коли kubelet перевіряє контейнер за допомогою HTTP, він слідує за перенаправленнями лише у випадку, якщо перенаправлення відбувається на той самий хост. Це включає перенаправлення, які змінюють протокол з HTTP на HTTPS, навіть якщо проба налаштована з scheme: HTTP.
Якщо перенаправлення відбувається на інший хост, kubelet не слідує за ним. Замість цього kubelet вважає пробу успішною і записує подію ProbeWarning.
Якщо kubelet слідує за перенаправленням і отримує 11 або більше перенаправлень загалом, проба вважається успішною і записується подія ProbeWarning. Наприклад:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 29m default-scheduler Successfully assigned default/httpbin-7b8bc9cb85-bjzwn to daocloud
Normal Pulling 29m kubelet Pulling image "docker.io/kennethreitz/httpbin"
Normal Pulled 24m kubelet Successfully pulled image "docker.io/kennethreitz/httpbin" in 5m12.402735213s
Normal Created 24m kubelet Created container httpbin
Normal Started 24m kubelet Started container httpbin
Warning ProbeWarning 4m11s (x1197 over 24m) kubelet Readiness probe warning: Probe terminated redirects
Увага:
Під час обробки проби httpGet kubelet припиняє читання тіла відповіді після 10KiB. Успішність проби визначається виключно кодом стану відповіді, який знаходиться в заголовках відповіді.
Якщо ви перевіряєте точку доступу, що повертає тіло відповіді більше ніж 10KiB, kubelet все одно позначить пробу як успішну на основі коду стану, але закриє зʼєднання після досягнення межі 10KiB. Це раптове закриття може спричинити появу в журналах вашого застосунку помилок connection reset by peer або broken pipe errors, які важко відрізнити від реальних проблем мережі.
Для надійних проб httpGet наполегливо рекомендується використовувати спеціальні точки доступу перевірки стану, які повертають мінімальне тіло відповіді. Якщо ви повинні використовувати наявну точку доступу з великим обсягом даних, розгляньте можливість використання проби exec для виконання запиту HEAD замість цього.
TCP-проби
Для TCP-проби kubelet встановлює зʼєднання до вузла, а не до Podʼа, що означає, що ви не можете використовувати імʼя сервісу в параметрі host, оскільки kubelet не може його розпізнати.
gRPC-проби
Kubernetes v1.27 [stable]Якщо ваш застосунок реалізує Протокол перевірки стану gRPC, ви можете налаштувати Kubernetes для використання його для перевірки запуску, життєздатності або готовності застосунку.
Ось приклад маніфесту:
apiVersion: v1
kind: Pod
metadata:
name: etcd-with-grpc
spec:
containers:
- name: etcd
image: registry.k8s.io/etcd:3.5.1-0
command: [ "/usr/local/bin/etcd", "--data-dir", "/var/lib/etcd", "--listen-client-urls", "http://0.0.0.0:2379", "--advertise-client-urls", "http://127.0.0.1:2379", "--log-level", "debug"]
ports:
- containerPort: 2379
livenessProbe:
grpc:
port: 2379
initialDelaySeconds: 10
Для використання gRPC-проби необхідно налаштувати port. Якщо ви хочете розрізняти проби різних типів і проби для різних функцій, ви можете використовувати поле service. Ви можете встановити service зі значенням liveness і налаштувати вашу gRPC точку доступу для перевірки справності для відповіді на цей запит інакше, ніж коли ви встановлюєте service зі значенням readiness. Це дозволяє використовувати ту саму точку доступу для різних видів перевірки стану контейнера, замість того щоб слухати на двох різних портах. Якщо ви хочете вказати власне імʼя сервісу та також вказати тип проби, проект Kubernetes рекомендує використовувати імʼя, яке обʼєднує ці значення. Наприклад: myservice-liveness (використовуючи - як роздільник).
Примітка:
На відміну від HTTP або TCP-проб, ви не можете вказати порт перевірки стану за іменем, і ви не можете налаштувати власне імʼя хоста.Проблеми конфігурації (наприклад: неправильний порт або сервіс, не реалізований протокол перевірки стану) вважаються невдачею проби, подібно до HTTP та TCP-проб.
Що далі
- Дізнайтесь як налаштувати проби життєздатності, готовності та запуску.
- Для повної специфікації полів, повʼязаних з пробами, дивіться Довідку API: Pod, Контейнер, Проба