Я хотел бы масштабировать свое маленькое веб-приложение Docker и сделать его высокодоступным. Я использую Docker много лет, и K8s кажется слишком сложным, поэтому я изучаю Docker Swarm.
Красочная диаграмма ИТ-архитектуры
Идея проста: используйте высокодоступный балансировщик нагрузки в качестве первого контакта, перенаправляя весь трафик TCP / IP на 3 главных узла Docker Swarm, а Traefik 2.4 слушает непосредственно порт сервера. Traefik использует http-домен, настроенный в службе, для перенаправления его в соответствующий контейнер на одном из рабочих процессов по сети Docker.
Для простоты мы пока опускаем https, так как даже простой http мне не подходит. Балансировщик нагрузки настроен правильно, Docker Swarm запущен и работает. Вот как я запускаю службы:
sudo docker network create --driver=overlay traefik-public
# reverse proxy service
sudo docker service create \
--name traefik \
-p 80:80 \
--mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock \
--mode=global \
--constraint node.role==manager \
--network traefik-public \
traefik:2.4 \
--providers.docker.swarmMode=true \
--providers.docker.endpoint=unix:///var/run/docker.sock \
--providers.docker.exposedbydefault=false \
--providers.docker.watch=true \
--providers.docker.network=traefik-public \
--entryPoints.web.address=:80
# webapp A service
sudo docker service create \
--replicas 5 \
--name hostname \
--constraint node.role!=manager \
--network traefik-public \
--publish published=8080,target=80 \
--label traefik.enabled=true \
--label 'traefik.http.routers.hostname.rule=Host(`a.domain.tld`)' \
--label traefik.http.routers.hostname.entrypoints=http \
--label traefik.http.services.hostname.loadbalancer.server.scheme=http \
--label traefik.http.services.hostname.loadbalancer.server.port=8080 \
nginxdemos/hello
По какой-то причине кажется, что в конфигурации есть ошибка. Я пытался настроить его, но либо получаю пустой ответ, либо страница 404 не найдена
при использовании curl http: //a.domain.tld
. Последняя ошибка: level = error msg = «Пропустить контейнер: поле не найдено, узел: включен» providerName = docker
.
Предположения:
Главный вопрос: как мне запустить и запустить базовую версию? Что не так?
Дополнительные вопросы:
Могу ли я использовать переменные env с такими службами, как контейнеры (для строки подключения к БД)?
Как мне получить доступ к панели инструментов Traefik? Я предполагаю, что на каждой панели инструментов будут отображаться разные данные.
Как добавить в Traefik собственные SSL-сертификаты? Поддерживают ли службы Swarm локальное хранилище? (Я предпочитаю простые решения, с удовольствием копирую свой .pem на все 3 узла один раз в год)
Как включить SSL и перенаправление http на https?
Могу ли я добавить пути к доменам, чтобы http: //a.domain.tld/api
использовал другую службу?
Как собирать журналы контейнеров? Будет ли Elastic Filebeat работать с рабочими контейнерами?
В противном случае я рад любым отзывам о планируемой ИТ-архитектуре.
Спасибо, bluepuma
Базовый шаблон для Docker Swarm с Traefik 2.4, маршрутизацией на основе домена, обычным SSL и масштабируемым веб-приложением, все на пустых металлических серверах.
Traefik будет запущен на всех главных узлах, напрямую прослушивая порт хоста 0.0.0.0:80 и 0.0.0.0:443. http обновляется до https, веб-приложения запускаются на рабочих узлах и автоматически регистрируются в их домене. Затем Traefik сбалансирует нагрузку всех входящих запросов и направит их на соответствующие рабочие контейнеры.
Обратите внимание, что это НЕ отказоустойчивое решение. Вам необходимо иметь балансировщик нагрузки перед этой установкой или плавающий IP, на который вы можете переключиться в случае отказа сервера.
Требования: Настройте рой докеров, здесь это не рассматривается. Каждый мастер-узел Docker Swarm, на котором работает Traefik, должен иметь локальную папку с config.yml и SSL-сертификатом. В качестве альтернативы вы можете использовать том Docker, который может быть удаленным монтированием NFS.
traefik.yml
version: '3.8'
services:
traefik:
image: traefik:v2.4
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
command:
- --providers.docker.swarmMode=true
- --providers.docker.exposedByDefault=false
- --providers.docker.network=proxy
- --providers.file.filename=/data/traefik/config.yml
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.websecure.address=:443
- --accesslog
- --log.level=info
environment:
- TZ=Europe/Berlin
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /data/traefik:/data/traefik
networks:
- proxy
deploy:
mode: global
placement:
constraints:
- node.role == manager
networks:
proxy:
external: true
config.yml, том из локальной папки, настройки SSL сертификата НЕОБХОДИМО хранить в отдельном файле
tls:
certificates:
- certFile: /data/traefik/certs/wildcard.crt
keyFile: /data/traefik/certs/wildcard.key
- certFile: /data/traefik/certs/another-certificate.crt
keyFile: /data/traefik/certs/another-certificate.key
stores:
default:
defaultCertificate:
certFile: /data/traefik/certs/wildcard.crt
keyFile: /data/traefik/certs/wildcard.key
Командная строка, запускайте свои двигатели :-)
# create network (just once)
docker network create --driver=overlay proxy
# start traefik via traefic.yml
docker stack deploy --compose-file traefik.yml traefik
# start a web-app with its domain name
docker service create \
--replicas 15 \
--name web-app \
--constraint node.role!=manager \
--network proxy \
--label traefik.enable=true \
--label 'traefik.http.routers.traefik.rule=Host(`app.doma.in`)' \
--label traefik.http.routers.traefik.entrypoints=websecure \
--label traefik.http.routers.traefik.tls=true \
--label traefik.http.services.hostname.loadbalancer.server.port=80 \
nginxdemos/hello
Вы можете уменьшить уровень лога (или убрать его совсем), также можно убрать accesslog. В качестве альтернативы можно записывать эти два типа логов в два разных файла. Дашборд Traefik все еще отсутствует в этой конфигурации.
Для большей безопасности вы можете использовать docker-socket-proxy, который @webjocky описывает в своем pastebin в этом обсуждении.