«1. Введение
В этом руководстве мы поговорим о зондах Kubernetes и продемонстрируем, как мы можем использовать HealthIndicator Actuator, чтобы получить точное представление о состоянии нашего приложения.
Для целей этого руководства мы предполагаем, что у нас уже есть опыт работы с Spring Boot Actuator, Kubernetes и Docker.
2. Зонды Kubernetes
Kubernetes определяет два разных зонда, которые мы можем использовать для периодической проверки того, все ли работает должным образом: живость и готовность.
2.1. Liveness and Readiness
С помощью тестов Liveness и Readiness Kubelet может действовать, как только обнаружит, что что-то не так, и свести к минимуму время простоя нашего приложения.
Оба настроены одинаково, но имеют разную семантику, и Kubelet выполняет разные действия в зависимости от того, какое из них срабатывает:
-
Готовность — Готовность проверяет, готов ли наш под начать получать трафик. Наш под готов, когда готовы все его контейнеры. Живучесть — в отличие от готовности, живость проверяет, следует ли перезапустить наш под. Он может выбрать варианты использования, когда наше приложение работает, но находится в состоянии, когда оно не может развиваться; например, он находится в тупике
Мы настраиваем оба типа зондов на уровне контейнера:
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 1
successThreshold: 1
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 2
failureThreshold: 1
successThreshold: 1
Существует ряд полей, которые мы можем настроить для более точного управления поведением наших зондов:
-
initialDelaySeconds â – После создания контейнера подождите n секунд перед запуском зонда. periodSeconds – как часто следует запускать этот зонд, по умолчанию 10 секунд; минимальное значение равно 1 секунде. timeoutSeconds — сколько мы ждем перед истечением времени проверки, по умолчанию 1 секунда; минимум снова равен 1 секунде. Порог отказа — попробуйте n раз, прежде чем сдаться. В случае готовности наш под будет помечен как не готовый, тогда как отказ в случае живости означает перезапуск пода. Значение по умолчанию здесь равно 3 сбоям, минимальное значение равно 1 SuccessThreshold. Это минимальное количество последовательных успешных попыток, при котором зонд считается успешным после сбоя. По умолчанию он равен 1 успеху, и его минимум также равен 1
В этом случае мы выбрали tcp-зонд, однако есть и другие типы зондов, которые мы можем использовать.
2.2. Типы зондов
В зависимости от нашего варианта использования один тип зонда может оказаться более полезным, чем другой. Например, если наш контейнер представляет собой веб-сервер, использование пробы http может быть более надежным, чем проба tcp.
К счастью, в Kubernetes есть три различных типа зондов, которые мы можем использовать:
-
exec — выполняет инструкции bash в нашем контейнере. Например, проверьте, существует ли определенный файл. Если инструкция возвращает код ошибки, зонд терпит неудачу. tcpSocket — пытается установить tcp-соединение с контейнером, используя указанный порт. Если не удается установить соединение, зонд завершается ошибкой httpGet — отправляет HTTP-запрос GET на сервер, работающий в контейнере и прослушивающий указанный порт. Любой код больше или равен 200 и меньше 400 указывает на успех
Важно отметить, что HTTP-запросы имеют дополнительные поля, помимо упомянутых ранее:
-
хост — имя хоста для подключения, по умолчанию используется наш IP-схема модуля — схема, которая должна использоваться для подключения, HTTP или HTTPS, по умолчанию — HTTP-путь — путь доступа к веб-серверу httpHeaders — настраиваемые заголовки для установки в порте запроса — Имя или номер порта для доступа в контейнере
3. Spring Actuator и возможности самовосстановления Kubernetes
Теперь, когда у нас есть общее представление о том, как Kubernetes может определить, находится ли наше приложение в неисправном состоянии, давайте посмотрим, как мы можем использовать Spring Actuator, чтобы внимательно следить не только за нашим приложением, но и за его зависимостями!
В этих примерах мы будем полагаться на Minikube.
3.1. Актуатор и его индикаторы работоспособности
«Учитывая, что Spring имеет ряд готовых к использованию индикаторов HealthIndicators, отражение состояния некоторых зависимостей нашего приложения от зондов Kubernetes так же просто, как добавление зависимости Actuator в наш pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.2. Пример живучести
Начнем с приложения, которое загружается нормально и через 30 секунд переходит в неисправное состояние.
Мы собираемся эмулировать неисправное состояние, создав HealthIndicator, который проверяет, является ли логическая переменная истинной. Мы инициализируем переменную значением true, а затем запланируем задачу, чтобы через 30 секунд изменить ее значение на false: ~ Затем мы создаем наш шаблон Kubernetes:
@Component
public class CustomHealthIndicator implements HealthIndicator {
private boolean isHealthy = true;
public CustomHealthIndicator() {
ScheduledExecutorService scheduled =
Executors.newSingleThreadScheduledExecutor();
scheduled.schedule(() -> {
isHealthy = false;
}, 30, TimeUnit.SECONDS);
}
@Override
public Health health() {
return isHealthy ? Health.up().build() : Health.down().build();
}
}
Мы используем зонд httpGet, указывающий на конечную точку работоспособности Actuator. Любое изменение состояния нашего приложения (и его зависимостей) будет отражаться на работоспособности нашего развертывания.
FROM openjdk:8-jdk-alpine
RUN mkdir -p /usr/opt/service
COPY target/*.jar /usr/opt/service/service.jar
EXPOSE 8080
ENTRYPOINT exec java -jar /usr/opt/service/service.jar
После развертывания нашего приложения в Kubernetes мы сможем увидеть оба зонда в действии: примерно через 30 секунд наш под будет помечен как неготовый и удален из ротации; через несколько секунд Pod перезапускается.
apiVersion: apps/v1
kind: Deployment
metadata:
name: liveness-example
spec:
...
spec:
containers:
- name: liveness-example
image: dbdock/liveness-example:1.0.0
...
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 3
failureThreshold: 1
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 2
periodSeconds: 8
failureThreshold: 1
Мы можем видеть, как события нашего модуля, выполняющего kubectl, описывают живость модуля: пример:
3.3. Пример готовности
В предыдущем примере мы видели, как можно использовать HealthIndicator для отражения состояния нашего приложения в отношении работоспособности развертывания Kubernetes.
Warning Unhealthy 3s (x2 over 7s) kubelet, minikube Readiness probe failed: HTTP probe failed ...
Warning Unhealthy 1s kubelet, minikube Liveness probe failed: HTTP probe failed ...
Normal Killing 0s kubelet, minikube Killing container with id ...
Давайте использовать его в другом случае: предположим, что нашему приложению требуется некоторое время, прежде чем оно сможет получать трафик. Например, ему нужно загрузить файл в память и проверить его содержимое.
Это хороший пример того, когда мы можем воспользоваться проверкой готовности.
Давайте изменим шаблон HealthIndicator и Kubernetes из предыдущего примера и адаптируем их к этому варианту использования:
Мы инициализируем переменную значением false, и через 40 секунд будет выполнена задача, установившая для нее значение true.
Затем мы докеризуем и развертываем наше приложение, используя следующий шаблон:
@Component
public class CustomHealthIndicator implements HealthIndicator {
private boolean isHealthy = false;
public CustomHealthIndicator() {
ScheduledExecutorService scheduled =
Executors.newSingleThreadScheduledExecutor();
scheduled.schedule(() -> {
isHealthy = true;
}, 40, TimeUnit.SECONDS);
}
@Override
public Health health() {
return isHealthy ? Health.up().build() : Health.down().build();
}
}
Несмотря на то, что это похоже, есть несколько изменений в конфигурации зондов, на которые нам нужно указать:
Поскольку мы знаем, что наше приложение требуется около 40 секунд, чтобы стать готовым к приему трафика, мы увеличили initialDelaySeconds нашего зонда готовности до 40 секунд. Точно так же мы увеличили initialDelaySeconds нашего зонда живучести до 100 секунд, чтобы избежать преждевременного уничтожения Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: readiness-example
spec:
...
spec:
containers:
- name: readiness-example
image: dbdock/readiness-example:1.0.0
...
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 40
timeoutSeconds: 2
periodSeconds: 3
failureThreshold: 2
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 100
timeoutSeconds: 2
periodSeconds: 8
failureThreshold: 1
Если он все еще не t закончился через 40 секунд, у него еще есть около 60 секунд, чтобы закончить. После этого наш зонд живости сработает и перезапустит под.
-
4. Заключение
В этой статье мы говорили о зондах Kubernetes и о том, как мы можем использовать Spring Actuator для улучшения мониторинга работоспособности нашего приложения.
Полную реализацию этих примеров можно найти на Github.
«
The full implementation of these examples can be found over on Github.