Плохой шлюз означает, что traefik настроен на пересылку запросов, но он не может получить доступ к контейнеру на ip и порте, которые он настроил для использования. Распространенные проблемы, вызывающие это:
- трафик и сервис в разных докерских сетях
- услуга существует в нескольких сетях, и трафик выбирает не ту
- неверный порт, используемый для подключения к контейнеру (используйте порт контейнера и убедитесь, что он прослушивает все интерфейсы, он же 0.0.0.0)
Из комментариев это происходит только во время развертывания, что означает, что traefik запускает контейнеры, прежде чем они будут готовы к приему запросов или пока они останавливаются.
Вы можете настроить контейнеры с помощью проверки работоспособности и отправить запрос через VIP-режим режима роя с помощью файла Docker, который выглядит следующим образом:
FROM jwilder/whoami
RUN echo $(date) >/build-date.txt
HEALTHCHECK --start-period=30s --retries=1 CMD wget -O - -q http://localhost:8000
А потом в docker-compose.yml:
labels:
- traefik.enable=true
- traefik.backend=app
- traefik.backend.loadbalancer.swarm=true
...
И я бы также настроил службу traefik со следующими параметрами:
- "--retry.attempts=2"
- "--forwardingTimeouts.dialTimeout=1s"
Однако traefik будет держать соединение открытым, и VIP продолжит отправлять все запросы одному и тому же внутреннему контейнеру по тому же соединению. Вместо этого вы можете использовать traefik для проверки здоровья:
labels:
- traefik.enable=true
- traefik.backend=app
- traefik.backend.healthcheck.path=/
...
Я бы все же оставил проверку работоспособности на самом контейнере, чтобы Docker давал время запуску контейнера перед остановкой другого контейнера. И оставьте параметр повтора в сервисе traefik, чтобы любой запрос к остановившему контейнеру или просто тот, который не был обнаружен проверкой работоспособности, имел шанс повторить попытку.
Вот итоговый файл композиции, который я использовал в своей среде:
version: '3.5'
services:
app:
image: test-whoami:1
ports:
- 6081:8000
deploy:
replicas: 2
restart_policy:
condition: on-failure
update_config:
parallelism: 1
failure_action: rollback
labels:
- traefik.enable=true
- traefik.backend=app
- traefik.backend.healthcheck.path=/
- traefik.frontend.rule=Path:/
- traefik.port=8000
- traefik.docker.network=test_web
networks:
- web
reverse-proxy:
image: traefik
command:
- "--api"
- "--retry.attempts=2"
- "--forwardingTimeouts.dialTimeout=1s"
- "--docker"
- "--docker.swarmMode"
- "--docker.domain=localhost"
- "--docker.watch"
- "--docker.exposedbydefault=false"
- "--docker.network=test_web"
deploy:
replicas: 1
restart_policy:
condition: on-failure
update_config:
parallelism: 1
failure_action: rollback
placement:
constraints:
- node.role == manager
networks:
- web
ports:
- 6080:80
- 6880:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
web:
Dockerfile, как указано выше. Имена изображений, порты, имена сетей и т. Д. Были изменены, чтобы избежать конфликтов с другими объектами в моей среде.