В этом посте хотелось бы поделиться заметками относительно использования Probe в кубернетес. И предоставить понимание того, на чем строиться ресурс менеджмент - реквесты и лимиты, QoS-классы.
Probes
В kubernetes реализован механизм проверки доступности нашего приложения. Существую 3 типа проверок:
Liveness Probe
- выполняет контроль за состоянием приложения в процессе его жизни. Liveness проверки выполняются постоянно. В случаи, если выполнение liveness пробы завершилось с результатом - failed, то kubernetes перезапустил приложение (под).Readiness Probe
- выполняют проверки за состоянием контейнеров, для того что бы понять готов ли под принимать клиентский трафик. В случаи неудачного выполнения readiness проды, приложение убирается из балансировки. Так же как и с liveness, readiness пробы выполняются постоянно, с некой переодичностью.Startup Probe
- с помошью startup пробы мы можем проверить, что наше приложение действительно проинициализировалось и готово принимать принимать запросы. Startup проба выполняется только до последнего успешного выполнения, после чего разблокирует выполнение других проб (liveness и readiness). Такой механизм может быть полезен, когда наш контейнер долго запускается, и чтобы избежать преждевременного убийства контейнера другими пробами они блокируются. Теперь напишем деплоймент, и будем разбираться с настройками проб.
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-with-probes
spec:
replicas: 2
selector:
matchLabels:
app: my-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: my-app
spec:
containers:
- image: nginx:1.12
name: nginx-web
ports:
- containerPort: 80
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: 80
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 80
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
initialDelaySeconds: 10
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 30
periodSeconds: 10
Пробы указываются в контексте - containers. И могу быть сконфигурированы полями:
failureThreshold
- в этом поле указывается количество проверок. Например в нашем деплойменте указано значение равное 3-м. Это означает, что если проба 3 раза выполняется с результатом - failed, то контейнер будет перезащен в случаи с livenessProbe пробы и будет помечан какUnready
в случаи c readynessProbe.httpGet
- это тип нашей проверки, то есть в нашем случаи мы будем отправлять http-запрос контейнеру. По мимо -httpGet
, есть возможность выполнять команды внутри контейнера через поле -exec
. Также есть проверка -tcpSocket
, проверка на доступность tcp-порта. В нашем случаи мы проверяем обычным http-запросом.path
- указывается локейшейн, в нашем случае это корневойport
- порт, на который будем стучаться.
periodSeconds
- переодичность проверки, в данном случаи мы хотим проверять наше приложение каждые 10 секунд.successThreshold
- это поле задает количество успешно выполненых проб после неуспешной. Например в нашем случаи при заданном количествеfailureThreshold: 3
, если хоть одна проверка из этих трех завершиться успешно, то счетчикfailureThreshold
обнуляется.timeoutSeconds
- здесь указывается количество секунд для ожидания пробы.initialDelaySeconds
- задается колличество секунд для отсрочки начала выполнения пробы. В нашем примере, мы задаем 10 секунд, что означает подождать 10 секунд после запуска прилы, прежде чем начать запускать пробы.
Запустим деплоймент, и посмотрим информацию по деплойменту:
$ kubectl apply -f deployment-probes.yml
$ kubectl describe pod deployment-with-probes-8556d554-2prkw | grep http-get
----
Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Startup: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=30
Limits & Requests
Когда мы запускаем наше приложение в kubernetes, нам крайне важно понимать, сколько ресурсов оно будет потреблять в процессе своей работы. У нас есть два параметра, которые относятся к resource managment в kubernetes:
Limits
- это верхняя граница по ресурсам, которые может использовать под. Например, если у нас выставлен лимит на память в 256мб, то приложение не сможет потреблять вышего этого значения. В случаи выхода за отведенный лимит, OOM Killer прибьет прилу.Requests
- здесь указывается количество ресурсов, которые необходимы для работы или запуска нашего приложения, эти ресурсы будут зарезервированы за подом.
Наш деплоймент из прошлой главы дополним новыми полями. Лимиты и Реквесты указывается в контексте поля нашего контейнера.
resources:
requests:
cpu: 50m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
В полях requests
и limits
, мы указываем:
cpu: 50m
- здесь мы указываем значение в milicpu (milicores). В терминалогии kubernetes - 1 ядро (1 виртуальное ядро) равно 1000 milicpu (milicores).memory: 100Mi
- тут все просто, указывается значение в 100 мегабайт. Соотношение milicores к сore.
1000m (milicores) = 1 core = 1 vCPU = 1 AWS vCPU = 1 GCP Core
Применяем обновленный манифест, и смотрим подробную информация по подам.
$ kubectl describe pod
---
Containers:
nginx-web:
Container ID: docker://0dae14de4d43f2717ea7a40a2ca38f8a5f6e77bf3ae329df7e8f85600c840677
Image: nginx:1.12
Image ID: docker-pullable://nginx@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 04 Dec 2022 00:39:19 +0600
Ready: True
Restart Count: 0
Limits:
cpu: 100m
memory: 100Mi
Requests:
cpu: 50m
memory: 100Mi
Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Startup: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=30
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-c2rxq (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-c2rxq:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Стоит отметить еще важную штуку в kubernetes, это QoS Class
. Кластер использует QoS
- классы для принятия решения о shedulling-e или исключении подов. Есть три класса:
BestEffort
- этот класс будет назначен тем подам, у которых не указаны ни реквесты, ни лимиты. Для кубернетес эти поды не значительные или менее важные, значит их можно прибить и запустить в другом месте.Burstable
- класс, который назначается подам с выставленными лимитами и реквестами по разным соотношениям. (Например, как в нашем примере). Поды с этим классом начнуть переезжать, или вырубаться во вторую очередь. То есть у подов с этим классом, приоритет немного выше, чем у подов класса -BestEffort
.Guaranteed
- этот класс назначается, когда выставленные cpu memory для limits и requests. И когда значения cpu/memory лимитов равное cpu/memory реквестов. Поды с этим классом, кубернетес будет держать до последнего.
Полезные ссылки
Пока разбирался по этим темам, нашем много информации и решил поделиться: