Kubernetes дозволяє визначати проби для безперервного моніторингу стану контейнерів у Podʼі. Проба — це діагностична перевірка контейнера, яку періодично виконує kubelet. Для виконання діагностики kubelet або виконує код всередині контейнера, або робить мережевий запит.
На основі результатів проб Kubernetes може перезапускати нездорові контейнери або припиняти надсилання трафіку до контейнерів, які не готові.
Kubelet може виконувати та реагувати на три види проб у працюючих контейнерах, кожна з яких виконує різну функцію, це:
Проби запуску перевіряють, чи застосунок у контейнері запущено. Якщо проба запуску налаштована, Kubernetes не виконує проби життєздатності або готовності, поки проба запуску не буде успішною, що дозволяє застосунку завершити ініціалізацію.
Цей тип проб виконується лише під час запуску, на відміну від проб життєздатності та готовності, які виконуються періодично. Якщо проба запуску завершується невдало, kubelet припиняє роботу контейнера, і до нього застосовується відповідна політика перезапуску.
Проби життєздатності (Liveness) визначають, коли слід перезапустити контейнер. Наприклад, проби життєздатності можуть виявити ситуацію взаємного блокування, коли програма працює, але не може продовжувати роботу. Перезапуск контейнера в такому стані допомагає забезпечити більшу доступність застосунку, незважаючи на наявність помилок.
Якщо контейнеру не вдається пройти пробу життєздатності більше разів, ніж передбачено налаштованим порогом, kubelet перезапускає контейнер. Проби життєздатності не чекають, поки проби готовності будуть успішними. Якщо ви хочете почекати перед виконанням проби життєздатності, ви можете визначити initialDelaySeconds або використовувати пробу запуску.
Проби життєздатності можуть бути ефективним засобом відновлення після збоїв у роботі застосунків, проте їх слід застосовувати з обережністю. Проби життєздатності необхідно ретельно налаштовувати, щоб гарантувати, що вони дійсно вказують на незворотний збій у роботі застосунку, наприклад, на взаємне блокування.
Неправильна реалізація проб життєздатності може призвести до каскадних збоїв. Це призводить до перезапуску контейнера під високим навантаженням; відхилення запитів клієнтів, оскільки ваш застосунок стає менш масштабованим; та збільшення навантаження на решту подів через деякі несправні поди. Потрібно розуміти різницю між пробами життєздатності та пробами готовності, а також коли їх застосовувати для вашого застосунку.
Проби готовності визначають, коли контейнер готовий приймати трафік. Вони корисні, коли застосунок очікує на виконання трудомістких початкових завдань встановлення мережевих зʼєднань, завантаження файлів і наповнення кешу. Проби готовності також можуть бути корисними на більш пізніх етапах життєвого циклу контейнера, наприклад, при відновленні після тимчасових збоїв або перевантажень.
Якщо проба готовності повертає неуспішний стан, контролер EndpointSlice видаляє IP-адресу Podʼа з EndpointSlices усіх Сервісів, які мають збіг з Podʼом.
Проби готовності виконуються в контейнері протягом всього його життєвого циклу.
Проби запуску корисні для Podʼів, які мають контейнери, що довго запускаються. Замість того, щоб встановлювати довгий інтервал життєздатності, ви можете налаштувати окрему конфігурацію для перевірки контейнера під час його запуску, дозволяючи час довший, ніж дозволяє інтервал життєздатності.
Якщо ваш контейнер зазвичай запускається більше ніж \( initialDelaySeconds + failureThreshold \times periodSeconds \), слід вказати пробу запуску, яка перевіряє ту саму точку доступу, що й проба життєздатності. Стандартне значення для periodSeconds становить 10 секунд. Потім слід встановити failureThreshold достатньо високим, щоб дозволити контейнеру запуститися, не змінюючи стандартне значення для проби життєздатності. Це допомагає захиститися від блокувань.
Якщо процес у вашому контейнері може самостійно завершуватися при виникненні проблем або погіршенні стану, вам не обов’язково потрібна проба життєздатності; kubelet автоматично виконає правильну дію відповідно до restartPolicy Podʼа.
Якщо ви хочете, щоб ваш контейнер був завершений і перезапущений у разі невдачі проби, тоді використовуйте пробу життєздатності та встановіть restartPolicy на Always або OnFailure.
Поширеним підходом для проб життєздатності є використання того самого низьковитратної точки доступу HTTP, що й для проб готовності, але з вищим failureThreshold. Це забезпечує, що Pod буде вважатися неготовим протягом певного часу перед примусовим завершенням його існування.
Щоб почати надсилати трафік до Podʼа лише після успішного проходження проби, вкажіть пробу готовності. Проба готовності може бути такою ж, як і проба життєздатності, але наявність проби готовності в специфікації означає, що Pod почне працювати без отримання трафіку і почне отримувати трафік лише після того, як проба почне успішно проходити.
Ви також можете використовувати пробу готовності, щоб дозволити контейнеру самостійно зупинятися для обслуговування, перевіряючи точку доступу, специфічну для проби готовності, яка відрізняється від проби життєздатності.
Коли ваш застосунок має строгі залежності від бекенд-сервісів, ви можете реалізувати як пробу життєздатності, так і пробу готовності. Проба життєздатності проходить, коли сам застосунок є справним, але проба готовності додатково перевіряє, чи доступний кожен необхідний бекенд-сервіс. Це допомагає уникнути направлення трафіку до Podʼів, які можуть відповідати лише повідомленнями про помилки.
Для контейнерів, яким потрібно працювати з великими обсягами даних, конфігураційними файлами або міграціями під час запуску, розгляньте можливість використання проби запуску. Однак, якщо ви хочете визначити різницю між застосунком, який зазнав невдачі, і застосунком, який все ще обробляє свої стартові дані, можливо, вам більше підійде проба готовності.
Існує чотири різні способи перевірки контейнера за допомогою проб. Кожна проба повинна визначати точно один із цих чотирьох механізмів:
execgrpcstatus відповіді дорівнює SERVING. Для отримання додаткової інформації див. gRPC-проби.httpGetGET запит до IP-адреси Podʼа на вказаному порту та шляху. Діагностика вважається успішною, якщо відповідь має код стану від 200 до 399 включно. Для отримання додаткової інформації див. HTTP-проби.tcpSocketexec проби передбачає створення/відгалуження кількох процесів щоразу при виконанні. В результаті, у випадку кластерів з високою щільністю Podʼів, меншими інтервалами initialDelaySeconds, periodSeconds, налаштування будь-якої проби з механізмом exec може призвести до збільшення навантаження на CPU вузла. У таких сценаріях розгляньте можливість використання альтернативних механізмів проб, щоб уникнути перенавантаження.Kubelet оцінює результат виконання кожної проби та діє відповідно. Кожна проба має один із трьох результатів:
SuccessFailureUnknownЯкщо контейнер не надає певну пробу, 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
initialDelaySecondsperiodSecondsperiodSeconds. Це робиться для того, щоб Pod став готовим швидше.timeoutSecondssuccessThresholdfailureThresholdfailureThreshold разів поспіль, Kubernetes вважає, що загальна перевірка не вдалася: контейнер не готовий/справний/живий. Стандартне значення — 3. Мінімальне значення — 1. У випадку проби запуску або життєздатності, якщо принаймні failureThreshold проб не вдалося, Kubernetes вважає контейнер несправним і запускає перезапуск для цього конкретного контейнера. Kubelet дотримується налаштування terminationGracePeriodSeconds для цього контейнера. Для невдалої проби готовності kubelet продовжує запускати контейнер, який не пройшов перевірку, і також продовжує виконувати інші проби; оскільки перевірка не вдалася, kubelet встановлює стан Ready для Podʼа у значення false.terminationGracePeriodSecondsterminationGracePeriodSeconds (30 секунд, якщо не вказано), а мінімальне значення — 1. Див. probe-level terminationGracePeriodSeconds для детальнішої інформації.terminationGracePeriodSeconds на рівні пробKubernetes v1.28 [stable]У версіях 1.25 і вище користувачі можуть вказати terminationGracePeriodSeconds на рівні проби як частину специфікації проби. Коли встановлені обидва значення terminationGracePeriodSeconds на рівні Podʼа і проби, kubelet використовує значення на рівні проби.
При встановленні terminationGracePeriodSeconds зверніть увагу на наступне:
terminationGracePeriodSeconds на рівні проби, якщо воно присутнє в 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-проби мають додаткові поля, які можна встановити в 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.36, де 1.36 — це версія 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-проби kubelet встановлює зʼєднання до вузла, а не до Podʼа, що означає, що ви не можете використовувати імʼя сервісу в параметрі host, оскільки kubelet не може його розпізнати.
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-проб.