Вопрос или проблема
Я пытаюсь запустить 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, это может произойти по нескольким причинам:
-
Подходящие разрешения: HAProxy должен иметь соответствующие права для доступа к директории
/var/lib/haproxy
. Это касается как пользовательских привилегий, так и прав на уровне файловой системы. -
Отсутствие необходимых файлов и подкаталогов: Для успешного выполнения команды
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-контейнере.