Kubernetes дозволяє визначати проби для безперервного моніторингу стану контейнерів у Podʼі. Проба — це діагностична перевірка контейнера, яку періодично виконує kubelet. Для виконання діагностики kubelet або виконує код всередині контейнера, або робить мережевий запит.
На основі результатів проб Kubernetes може перезапускати несправні контейнери або припиняти надсилання трафіку до контейнерів, які не готові.
Kubelet може за потреби виконувати три види проб у запущених контейнерах і реагувати на їхні результати; кожна з них має власне призначення:
Проби запуску перевіряють, чи застосунок у контейнері запущено. Якщо проба запуску налаштована, Kubernetes не виконує проби життєздатності або готовності, поки проба запуску не буде успішною, що дозволяє застосунку завершити ініціалізацію.
Цей тип проб виконується лише під час запуску, на відміну від проб життєздатності та готовності, які виконуються періодично. Якщо проба запуску завершується невдало, kubelet завершує контейнер, і до нього застосовується його політика перезапуску.
Проби життєздатності (Liveness) визначають, коли слід перезапустити контейнер. Наприклад, проби життєздатності можуть виявити ситуацію взаємного блокування, коли застосунок працює, але не може просуватися далі. Перезапуск контейнера в такому стані допомагає забезпечити більшу доступність застосунку, незважаючи на наявність помилок.
Якщо контейнеру не вдається пройти пробу життєздатності більше разів, ніж передбачено налаштованим порогом, kubelet перезапускає контейнер. Проби життєздатності не чекають, поки проби готовності будуть успішними. Якщо ви хочете почекати перед виконанням проби життєздатності, ви можете визначити initialDelaySeconds або використовувати пробу запуску.
Проби життєздатності можуть бути ефективним засобом відновлення після збоїв у роботі застосунків, проте їх слід застосовувати з обережністю. Проби життєздатності необхідно ретельно налаштовувати, щоб гарантувати, що вони дійсно вказують на незворотний збій у роботі застосунку, наприклад, на взаємне блокування.
Неправильна реалізація проб життєздатності може призвести до каскадних збоїв. Це призводить до перезапуску контейнера під високим навантаженням; невдалих запитів клієнтів, оскільки ваш застосунок стає менш масштабованим; та збільшення навантаження на решту Podʼів через кілька несправних Podʼів. Потрібно розуміти різницю між пробами життєздатності та пробами готовності, а також коли їх застосовувати для вашого застосунку.
Проби готовності визначають, коли контейнер готовий приймати трафік. Вони корисні, коли застосунок очікує на виконання трудомістких початкових завдань, таких як встановлення мережевих зʼєднань, завантаження файлів і наповнення кешу. Проби готовності також можуть бути корисними на більш пізніх етапах життєвого циклу контейнера, наприклад, під час відновлення після тимчасових збоїв або перевантажень.
Якщо проба готовності повертає неуспішний стан, контролер EndpointSlice видаляє IP-адресу Podʼа з EndpointSlices усіх Services, що відповідають цьому 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. Див. terminationGracePeriodSeconds на рівні проби для детальнішої інформації.terminationGracePeriodSeconds на рівні пробиУ версіях 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.protocol: Протокол для використання в запиті проби. Стандартно HTTP1. Встановіть HTTP2, щоб виконувати пробу через HTTP/2 без шифрування (h2c). Вимагає увімкнення функціональної можливості H2CContainerProbe.Для 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.37, де 1.37 — це версія 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: ""
To use this feature, you (or a cluster administrator) will need to enable the H2CContainerProbe feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Ви можете налаштувати HTTP-пробу для використання HTTP/2 без шифрування (h2c), встановивши поле protocol на HTTP2. Коли protocol встановлено на HTTP2, kubelet використовує h2c (HTTP/2 через звичайний TCP) замість HTTP/1.1. Типове значення protocol — HTTP1. Встановлення protocol: HTTP2 вимагає scheme: HTTP (типове значення); API-сервер відхиляє комбінацію protocol: HTTP2 з scheme: HTTPS. Для отримання додаткових відомостей див. Використання HTTP/2 без шифрування (h2c) з HTTP-пробами.
Коли 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 не може її розвʼязати.
Якщо ваш застосунок реалізує Протокол перевірки стану 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 Health Checking так, щоб вона відповідала на цей запит інакше, ніж коли service має значення readiness. Це дозволяє використовувати ту саму точку доступу для різних видів перевірки стану контейнера, замість того щоб слухати на двох різних портах. Якщо ви хочете вказати власну назву сервісу та також вказати тип проби, проєкт Kubernetes рекомендує використовувати назву, яка обʼєднує ці значення. Наприклад: myservice-liveness (використовуючи - як роздільник).
Проблеми конфігурації (наприклад: неправильний порт або сервіс, не реалізований протокол перевірки стану) вважаються невдачею проби, подібно до HTTP та TCP-проб.
To use this feature, you (or a cluster administrator) will need to enable the GRPCContainerProbeTLS feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Ви можете налаштувати gRPC-пробу для підключення через TLS, встановивши поле mode на TLS. Коли mode встановлено на TLS, kubelet використовує TLS з InsecureSkipVerify (він не перевіряє сертифікат сервера). Типове значення mode — Plaintext. Для отримання додаткових відомостей див. Використання TLS з gRPC-пробами.