Перезапустите под Kubernetes, если существует строка журнала.

Вопрос или проблема

Существует ли встроенный или элегантный способ автоматически перезапускать под Kubernetes, если в логах появляется определенная строка лога?

Нет встроенного контроля работоспособности, который напрямую проверяет вывод kubectl logs или то, что процесс внутри вашего контейнера записывает в stdout.

Однако, если процесс вашего контейнера записывает свои сообщения в файл или если вы можете перенаправить вывод процесса в файл внутри контейнера (например, с использованием tee, но будьте осторожны, чтобы правильно вращать файл), вы можете использовать контроль работоспособности.

Предположим, что логи записываются в /var/log/my-service.log, и каждый раз, когда мы наблюдаем time to say good bye, нам нужно перезапустить контейнер.

Мы можем добиться такого поведения, используя следующий шаблон пода:

spec:
  containers:
  - image: busybox
    name: sf-1102768
    command: ["/bin/sh", "-c", "mkdir -p /var/log && echo hello && sleep 60 && echo time to say good bye > /var/log/my-service.log && sleep 3600 && echo hm... still here"]
    livenessProbe:
      exec:
        command: ["/bin/sh", "-c", "! grep -q 'time to say good bye' /var/log/my-service.log"]
      initialDelaySeconds: 5
      periodSeconds: 5

Таким образом, альтернативой может быть создание cronjob, который потенциально вызывает перезапуск, в этом примере мой развертывание home-assistant:

apiVersion: batch/v1
kind: CronJob
metadata:
  annotations: {}
  labels:
    cronjob: ha-restart-checker
  name: ha-restart-checker
  namespace: ha
spec:
  concurrencyPolicy: Replace
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            cronjob: ha-restart-checker
        spec:
          tolerations:
            - key: node-role.kubernetes.io/control-plane
              effect: NoSchedule
          containers:
            - args:
                - |-
                  set -euo pipefail
                  echodate() { echo "$(date) $@"; }
                  echodate "Проверка HA ошибки для вызова перезапуска"
                  echo ---------------------------
                  grep -i 'Ошибка во время резервного копирования. Не удалось освободить блокировку записи базы данных' /config/home-assistant.log && \
                    kubectl -n ha rollout restart deployment home-assistant
                  echo ---------------------------
              command:
                - /bin/bash
                - -c
              #image: quay.io/kubermatic/util:2.5.0 #AMD64
              image: quay.io/toschneck/kubermatic-util:2024-10-23 #ARM
              imagePullPolicy: IfNotPresent
              name: ha-restart-checker
              resources: {}
              volumeMounts:
                - name: config
                  mountPath: /config
                  readOnly: true
          dnsPolicy: ClusterFirst
          restartPolicy: Never
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccountName: ha-restart-checker
          terminationGracePeriodSeconds: 30
          volumes:
            - name: config
              persistentVolumeClaim:
                claimName: home-assistant-config
                readOnly: true
  timeZone: Europe/Berlin
  schedule: '20 * * * *'
  startingDeadlineSeconds: 30
  successfulJobsHistoryLimit: 1
  suspend: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations: {}
  name: ha-restart-checker
  namespace: ha
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  annotations: {}
  name: toschneck:ha:restart
  namespace: ha
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: toschneck:ha:restart
subjects:
  - kind: ServiceAccount
    name: ha-restart-checker
    namespace: ha
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations: {}
  name: toschneck:ha:restart
  namespace: ha
rules:
  - apiGroups:
      - 'apps'
    resources:
      - deployments
    verbs:
      - list
      - get
      - patch

Ответ или решение

Автоматический перезапуск подов Kubernetes при наличии определенной строки в логах

В современном управлении контейнерами с использованием Kubernetes возникает необходимость не только контролировать состояние подов, но и реагировать на изменения в логах. Когда определенные строки в логах указывают на проблему, необходимо автоматически перезапускать соответствующий под. В данной статье мы рассмотрим элегантные методы достижения этой цели.

1. Использование живых проб (Liveness Probes)

Kubernetes не предоставляет встроенный механизм для мониторинга логов подов через команду kubectl logs. Тем не менее, есть возможность реализации подобного поведения с помощью живых проб, если ваши логи записываются в файл внутри контейнера.

Пример:

Предположим, что ваш процесс пишет логи в файл /var/log/my-service.log и вы хотите перезапустить под, если в логе появляется строка "time to say good bye". Вот пример спецификации пода, который реализует данную логику:

apiVersion: v1
kind: Pod
metadata:
  name: sf-1102768
spec:
  containers:
  - name: sf-1102768
    image: busybox
    command: ["/bin/sh", "-c", "mkdir -p /var/log && echo hello && sleep 60 && echo time to say good bye > /var/log/my-service.log && sleep 3600 && echo hm... still here"]
    livenessProbe:
      exec:
        command: ["/bin/sh", "-c", "! grep -q 'time to say good bye' /var/log/my-service.log"]
      initialDelaySeconds: 5
      periodSeconds: 5

В этом примере живые пробы используют команду grep для проверки наличия определенной строки в логах, что позволяет K8s перезапустить под, если строка найдена.

2. Использование CronJob для проверки логов

Альтернативным и более гибким решением является использование CronJob, который периодически проверяет логи на наличие определенной строки. Если строка найдена, CronJob может вызвать команду для перезапуска развертывания.

Пример CronJob:
apiVersion: batch/v1
kind: CronJob
metadata:
  name: ha-restart-checker
  namespace: ha
spec:
  schedule: '20 * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: ha-restart-checker
            image: quay.io/toschneck/kubermatic-util:2024-10-23
            command: ["/bin/bash", "-c"]
            args:
              - |
                set -euo pipefail
                echodate() { echo "$(date) $@"; }
                echodate "Check HA Error to trigger restart"
                if grep -i 'Error during backup. Could not release database write lock' /config/home-assistant.log; then
                  kubectl -n ha rollout restart deployment home-assistant
                fi
          restartPolicy: Never
          volumes:
          - name: config
            persistentVolumeClaim:
              claimName: home-assistant-config

В этом примере CronJob запускается каждую двадцатую минуту и проверяет логи на наличие ошибок. Если определенная ошибка найдена, выполняется команда для перезапуска развертывания с именем home-assistant.

Заключение

Автоматизация перезапуска подов на основе логов — важный аспект поддержания надежности приложений в Kubernetes. Использование живых проб и CronJob позволяет интегрировать контекстные проверки логов, что минимизирует время простоя и поддерживает работоспособность приложения. Выбор между живыми пробами и CronJob зависит от архитектуры вашего приложения и конкретных бизнес-требований.

Эти методы предоставляют эффективные решения для автоматического управления состоянием подов Kubernetes, основываясь на логах, что значительно улучшает процесс наблюдения и автоматизации в вашем кластере.

Оцените материал
Добавить комментарий

Капча загружается...