HAProxy – Не удалось chroot в /var/lib/haproxy

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

Я пытаюсь запустить haproxy в docker, следуя этой статье из блога haproxy. https://www.haproxy.com/blog/haproxy-on-docker-swarm-load-balancing-and-dns-service-discovery/
У меня возникает следующая ошибка Cannot chroot /var/lib/haproxy

hap_haproxy.3.j24pbth7qsup@prox1    | [NOTICE]   (1) : Новый worker #1 (9) forked
hap_haproxy.3.j24pbth7qsup@prox1    | [NOTICE]   (9) : версия haproxy 2.4.7-b5e51a5
hap_haproxy.3.j24pbth7qsup@prox1    | [NOTICE]   (9) : путь к исполняемому файлу /usr/local/sbin/haproxy
hap_haproxy.3.j24pbth7qsup@prox1    | [ALERT]    (9) : [haproxy.main()] Не удалось выполнить chroot(/var/lib/haproxy).
hap_haproxy.3.j24pbth7qsup@prox1    | [WARNING]  (1) : Текущий worker #1 (9) завершился с кодом 1 (Выход)

Вот моя конфигурация haproxy

global
    log          fd@2 local2
#    log     stdout format raw local0 info
    chroot       /var/lib/haproxy
    pidfile      /var/lib/haproxy/haproxy.pid
    maxconn      4000
    user         haproxy 
    group        haproxy
    stats socket /var/lib/haproxy/stats user haproxy group haproxy mode 660 level admin expose-fd listeners
    master-worker

resolvers docker
    nameserver dns1 127.0.0.11:53
    resolve_retries 3
    timeout resolve 1s
    timeout retry   1s
    hold other      10s
    hold refused    10s
    hold nx         10s
    hold timeout    10s
    hold valid      10s
    hold obsolete   10s

defaults
    timeout connect 10s
    timeout client 30s
    timeout server 30s
    log global
    mode http
    option httplog

frontend  fe_web
    bind *:8080
    use_backend stat if { path -i /stats }
    default_backend be_service

backend be_service
    balance roundrobin
    server-template nginx- 6 nginx-Service:80 check resolvers docker init-addr libc,none

backend be_service_wrong_case
    balance roundrobin
    server-template nginx- 6 nginx-service:80 check resolvers docker init-addr libc,none

backend stat
    stats enable
    stats uri /stats
    stats refresh 15s
    stats show-legends
    stats show-node

Я проверил dockerfile официального образа, и путь /var/lib/haproxy создается.
Может кто-то сказать, что именно идет не так? (отредактировано)

На данный момент я нашел такую же проблему в Dockerfile Haproxy. Может быть, это что-то, что я не уловил. В любом случае, простое решение:

Создайте простой контекст docker для отправки:

mkdir haproxy && cd haproxy

Создайте Dockerfile следующим образом:

FROM debian:bullseye-slim

# грубо, https://salsa.debian.org/haproxy-team/haproxy/-/blob/732b97ae286906dea19ab5744cf9cf97c364ac1d/debian/haproxy.postinst#L5-6
RUN set -eux; \
    groupadd --gid 99 --system haproxy; \
    useradd \
        --gid haproxy \
        --home-dir /var/lib/haproxy \
        --no-create-home \
        --system \
        --uid 99 \
        haproxy \
    ; \
    mkdir /var/lib/haproxy; \
    chown haproxy:haproxy /var/lib/haproxy

ENV HAPROXY_VERSION 2.5.4
ENV HAPROXY_URL https://www.haproxy.org/download/2.5/src/haproxy-2.5.4.tar.gz
ENV HAPROXY_SHA256 dc4015d85c7fef811b459803b763001d809b07a9251dc1864fedb9a07b44aefb

# см. https://sources.debian.net/src/haproxy/jessie/debian/rules/ для полезной навигации по возможным аргументам "make"
RUN set -eux; \
    \
    savedAptMark="$(apt-mark showmanual)"; \
    apt-get update && apt-get install -y --no-install-recommends \
        ca-certificates \
        gcc \
        libc6-dev \
        liblua5.3-dev \
        libpcre2-dev \
        libssl-dev \
        make \
        wget \
    ; \
    rm -rf /var/lib/apt/lists/*; \
    \
    wget -O haproxy.tar.gz "$HAPROXY_URL"; \
    echo "$HAPROXY_SHA256 *haproxy.tar.gz" | sha256sum -c; \
    mkdir -p /usr/src/haproxy; \
    tar -xzf haproxy.tar.gz -C /usr/src/haproxy --strip-components=1; \
    rm haproxy.tar.gz; \
    \
    makeOpts=" \
        TARGET=linux-glibc \
        USE_GETADDRINFO=1 \
        USE_LUA=1 LUA_INC=/usr/include/lua5.3 \
        USE_OPENSSL=1 \
        USE_PCRE2=1 USE_PCRE2_JIT=1 \
        USE_PROMEX=1 \
        \
        EXTRA_OBJS=" \
        " \
    "; \
# https://salsa.debian.org/haproxy-team/haproxy/-/commit/53988af3d006ebcbf2c941e34121859fd6379c70
    dpkgArch="$(dpkg --print-architecture)"; \
    case "$dpkgArch" in \
        armel) makeOpts="$makeOpts ADDLIB=-latomic" ;; \
    esac; \
    \
    nproc="$(nproc)"; \
    eval "make -C /usr/src/haproxy -j '$nproc' all $makeOpts"; \
    eval "make -C /usr/src/haproxy install-bin $makeOpts"; \
    \
    mkdir -p /usr/local/etc/haproxy; \
    cp -R /usr/src/haproxy/examples/errorfiles /usr/local/etc/haproxy/errors; \
    rm -rf /usr/src/haproxy; \
    \
    apt-mark auto '.*' > /dev/null; \
    [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
    find /usr/local -type f -executable -exec ldd '{}' ';' \
        | awk '/=>/ { print $(NF-1) }' \
        | sort -u \
        | xargs -r dpkg-query --search \
        | cut -d: -f1 \
        | sort -u \
        | xargs -r apt-mark manual \
    ; \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
    \
# дымовой тест
    haproxy -v

# https://www.haproxy.org/download/1.8/doc/management.txt
# "4. Остановка и перезапуск HAProxy"
# "когда сигнал SIGTERM отправляется процессу haproxy, он немедленно завершает работу и все установленные соединения закрываются"
# "аккуратная остановка вызывается, когда сигнал SIGUSR1 отправляется процессу haproxy"
STOPSIGNAL SIGUSR1

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

USER haproxy
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"]

Затем создайте docker-entrypoint.sh следующим образом:

touch docker-entrypoint.sh

и вставьте следующий контент:

#!/bin/sh
set -e

# первый аргумент - это `-f` или `--some-option`
if [ "${1#-}" != "$1" ]; then
    set -- haproxy "$@"
fi

if [ "$1" = 'haproxy' ]; then
    shift # "haproxy"
    # если пользователь хочет "haproxy", добавим несколько полезных флагов
    #   -W  -- "режим master-worker" (аналог старого "haproxy-systemd-wrapper"; позволяет перезагружать через "SIGUSR2")
    #   -db -- отключает фоновый режим
    set -- haproxy -W -db "$@"
fi

exec "$@"

После этих шагов вы можете собрать свой рабочий образ haproxy: docker build -t haproxy .

Для меня решением было просто удалить директиву chroot /var/lib/haproxy из файла конфигурации haproxy.

Я не вижу смысла в chroot, так как он и так изолирован в контейнере.

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

Ошибка HAProxy: "Cannot chroot /var/lib/haproxy" при запуске в Docker

Если вы столкнулись с ошибкой Cannot chroot /var/lib/haproxy, когда пытаетесь запустить HAProxy в контейнере Docker, это может быть связано с несколькими факторами, связанными с конфигурацией и окружением Docker. Давайте разберем детали проблемы и возможные решения на основании представленного вами контекста.

Понимание ошибки

Ошибка Cannot chroot указывает на то, что HAProxy не смог выполнить команду chroot из-за того, что не был найден или недоступен указанный каталог. В контексте контейнера Docker, это может произойти по нескольким причинам:

  1. Подходящие разрешения: HAProxy должен иметь соответствующие права для доступа к директории /var/lib/haproxy. Это касается как пользовательских привилегий, так и прав на уровне файловой системы.

  2. Отсутствие необходимых файлов и подкаталогов: Для успешного выполнения команды chroot, каталог должен содержать необходимые системные файлы и библиотеки, чтобы HAProxy мог корректно функционировать внутри нового окружения.

Решения проблемы

1. Удаление директивы chroot

Наиболее простым способом решения данной проблемы является удаление строки chroot /var/lib/haproxy из конфигурационного файла HAProxy. Как было отмечено в комментариях, в контейнере Docker процесс доступа к системе уже изолирован, что делает использование chroot излишним.

global
    log          fd@2 local2
#    log     stdout format raw local0 info
#    chroot       /var/lib/haproxy  # Удалите или закомментируйте эту строку
    pidfile      /var/lib/haproxy/haproxy.pid
2. Правильная настройка Dockerfile

Если же вы решите оставить команду chroot, убедитесь, что ваш Dockerfile создает необходимую структуру каталогов и выставляет правильные права доступа. Пример настройки может выглядеть следующим образом:

FROM debian:bullseye-slim

# Создание группы и пользователя для HAProxy
RUN set -eux; \
    groupadd --gid 99 --system haproxy; \
    useradd \
        --gid haproxy \
        --home-dir /var/lib/haproxy \
        --no-create-home \
        --system \
        --uid 99 \
        haproxy \
    ; \
    mkdir /var/lib/haproxy; \
    chown haproxy:haproxy /var/lib/haproxy

WORKDIR /var/lib/haproxy

# Установите HAProxy и создайте необходимые файлы конфигурации...
3. Убедитесь в наличии необходимых библиотек

Если вы используете chroot, убедитесь, что директория /var/lib/haproxy содержит все необходимые библиотеки и файлы, чтобы HAProxy мог корректно работать. Это может включать:

  • Библиотеки системных вызовов
  • Конфигурационные файлы и каталоги
4. Проверка конфигурационного файла HAProxy

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

Заключение

Хотя использование chroot может быть полезным в отдельных сценариях, в среде контейнеров Docker это зачастую излишне, поскольку контейнеры уже обеспечивают уровень изоляции. Если удаление этой опции решает вашу проблему, это будет наиболее простое и эффективное решение. Однако, если вы хотите использовать chroot, обязательно проверьте настройки прав доступа и наличие всех необходимых файлов и папок в создаваемом вами окружении.

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

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

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