HAProxy проверка состояния не удалась с неверным статусом Level 7, код: 400, информация: “Проверка статуса HTTP вернула код 400”

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

У меня есть сервер HAProxy, который я использую в качестве L7 балансировщика нагрузки для моих узлов k8s. Мой кластер поддерживает istio, и у меня есть сервис istio-ingressgateway, выставленный через NodePort

ИМЯ                   ТИП         CLUSTER-IP      EXTERNAL-IP   ПОРТ(Ы)                                                                      ВРЕМЯ
istio-ingressgateway   NodePort    10.11.140.167   <нет>        15021:30301/TCP,80:31916/TCP,443:31517/TCP,15012:30768/TCP,15443:32020/TCP   11д

С сервера HAProxy я пытаюсь выполнять проверки здоровья на конечной точке /healthz/ready. Я использую HAProxy 1.8, и мой haproxy.cfg выглядит следующим образом:

global
    log         /dev/log    local0
    log         /dev/log    local1 notice
    chroot      /var/lib/haproxy
    pidfile     /var/run/rh-haproxy18-haproxy.pid

    user        haproxy
    group       haproxy
    daemon
    stats       socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners

    spread-checks  21

    # По умолчанию местоположения SSL-материалов
    ca-base     /etc/ssl/certs
    crt-base    /etc/ssl/private

    # По умолчанию шифры для использования на SSL-включенных слушающих сокетах.
    # Для получения дополнительной информации смотрите ciphers(1SSL). Этот список взят из:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    # Альтернативный список с дополнительными директивами можно получить с
    #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  redispatch
    retries                 3

    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 10000
    balance                 roundrobin


frontend http-80
        bind *:80
        mode http
        option httplog
        default_backend www-80

backend www-80
        balance roundrobin
        mode http
        option httpchk /healthz/ready HTTP/1.1
        http-check expect status 200
        server backendnode1 155.13.200.29:31916 check port 30301 fall 3 rise 2 inter 1597
        server backendnode2 155.13.200.28:31916 check port 30301 fall 3 rise 2 inter 1597
        server backendnode3 155.13.200.27:31916 check port 30301 fall 3 rise 2 inter 1597


frontend health-80
    bind *:8080
    acl backend_dead nbsrv(www-80) lt 1
    monitor-uri /haproxy_status
    monitor fail if backend_dead

listen stats # Определите раздел прослушивания под названием "stats"
    bind :9000 # Прослушивать на localhost:9000
    mode http
    stats enable  # Включить страницу статистики
    stats hide-version  # Скрыть версию HAProxy
    stats realm Haproxy\ Statistics  # Текст заголовка для всплывающего окна
    stats uri /haproxy_stats  # URI статистики
    stats auth haproxy:passwd  

Я использую HTTP/1.1 для проверки здоровья бэкенда, потому что istio-ingressgateway не принимает запросы HTTP/1.0, что приводит к ошибочному коду 426.

Запрос бэкенду с сервера HAProxy дает успешный результат:

curl -I  http://155.13.200.29:31916/healthz/ready
HTTP/1.1 200 OK
date: Fri, 11 Jun 2021 07:21:09 GMT
x-envoy-upstream-service-time: 0
server: envoy
transfer-encoding: chunked

Однако проверка здоровья HAProxy все равно не проходит. Я получаю следующие ошибки:

Jun 11 07:18:22 hap-server01 haproxy[12348]: Сервер www-80/backendnode2 не работает, причина: Неверный статус Layer7, код: 400, информация: "HTTP статус проверки вернул код <3C>400<3E>", продолжительность проверки: 2ms. 1 активный и 0 резервных серверов осталось. 0 активных сессий, 0 повторно поставленных в очередь, 0 осталось в очереди.
Jun 11 07:18:22 hap-server01 haproxy[12348]: Сервер www-80/backendnode2 не работает, причина: Неверный статус Layer7, код: 400, информация: "HTTP статус проверки вернул код <3C>400<3E>", продолжительность проверки: 2ms. 1 активный и 0 резервных серверов осталось. 0 активных сессий, 0 повторно поставленных в очередь, 0 осталось в очереди.
Jun 11 07:18:22 hap-server01 haproxy[11795]: [WARNING] 161/071821 (11795) : Прежний рабочий 11798 завершил работу с кодом 0
Jun 11 07:18:22 hap-server01 haproxy[12348]: Сервер www-80/backendnode3 не работает, причина: Неверный статус Layer7, код: 400, информация: "HTTP статус проверки вернул код <3C>400<3E>", продолжительность проверки: 3ms. 0 активных и 0 резервных серверов осталось. 0 активных сессий, 0 повторно поставленных в очередь, 0 осталось в очереди.
Jun 11 07:18:22 hap-server01 haproxy[12348]: Сервер www-80/backendnode3 не работает, причина: Неверный статус Layer7, код: 400, информация: "HTTP статус проверки вернул код <3C>400<3E>", продолжительность проверки: 3ms. 0 активных и 0 резервных серверов осталось. 0 активных сессий, 0 повторно поставленных в очередь, 0 осталось в очереди.

Я понимаю, что код состояния 400 возникает из-за неверных запросов. Есть ли что-то неправильно настроенное в моем haproxy.cfg? Я чувствую, что проблема в том, как я пытаюсь отправить запрос HTTP/1.1 для проверки здоровья. Но я не уверен, что еще добавить или что изменить в конфигурации.

Проверьте руководство, вы не можете указать версию, не указав метод:

option httpchk <method> <uri> <version>

В вашем случае я бы попробовал

option httpchk GET /healthz/ready HTTP/1.1

Также: изучите tcpdump, очень интересно наблюдать за коммуникацией между системами и выяснять, что не так.

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

Проблема, с которой вы столкнулись на своем HAProxy-сервере, связана с неудачным выполнением проверки работоспособности на уровне приложения (Layer7). Как указано в вашем вопросе, код состояния ответа 400 ("Bad Request") указывает на то, что запрос, отправленный HAProxy, не был правильно обработан бекендом, и это связано с тем, как именно вы выполняете проверку работоспособности.

Причины проблемы

Вы верно заметили, что HAProxy использует HTTP/1.1 для проверки состояния ваших бэкендов. Ваша текущая конфигурация проверки состояния с использованием директивы option httpchk /healthz/ready HTTP/1.1 подразумевает, что HAProxy отправляет запрос без указания метода, что является ошибкой. Это приводит к тому, что бэкенд считает запрос некорректным и возвращает статус 400.

Решение конфигурации

Чтобы исправить это, вам нужно указать метод HTTP вместе с URI и версией. Измените вашу директиву проверки состояния на следующую:

option httpchk GET /healthz/ready HTTP/1.1

Такое изменение гарантирует, что HAProxy отправляет правильный GET-запрос на указанный эндпоинт, и сервер сможет обработать его корректно.

Дополнительные рекомендации

  1. Проверка конфигурации: После внесения изменений в конфигурацию обязательно выполните проверку конфигурации HAProxy, используя команду:

    haproxy -c -f /path/to/haproxy.cfg

    Убедитесь, что конфигурация не содержит ошибок.

  2. Логирование: Настройте более подробное логирование для отладки, если проблемы продолжатся. Это поможет выявить точные причины возврата статуса 400. Вы можете добавить более детализированные записи в лог, изменив уровень логирования.

  3. Использование tcpdump: Вы уже упомянули о tcpdump — это отличный инструмент, позволяющий отслеживать сетевой трафик и видеть, какие запросы HAProxy отправляет на бэкенды и какие ответы возвращаются. Это может оказаться полезным для дальнейшей диагностики.

  4. Проверка подов Istio: Убедитесь, что поды Istio и их сервисы работают корректно. Можно использовать команду kubectl get pods -n istio-system, чтобы проверить состояние подов.

  5. Поведение NodePort: Убедитесь, что ваш бекенд действительно доступен по IP и порту, указанным в конфигурации HAProxy, и что нет сетевых ограничений между серверами.

Заключение

Исправление конфигурации как предложено выше должно устранить вашу проблему с проверкой работоспособности в HAProxy. Если проблема не решится, обратите внимание на другие аспекты сетевой конфигурации или на возможные настройки самих модуля Istio.

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

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