我想扩展我的小型 Docker Web 应用并使其具有高可用性。我已经使用 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 page not found
使用时要么得到空响应,要么得到curl http://a.domain.tld
。最新的错误是level=error msg="Skip container : field not found, node: enabled" providerName=docker
。
假设:
- Traefik 在 Swarm 主节点上运行以获取 Docker 事件通知
- Traefik 直接监听主节点的外部端口 80
- Traefik 将识别新服务并根据域名路由到容器
- 同一服务的多个 webapp 容器可以运行在同一个工作节点上
主要问题:如何启动并运行基本版本?有什么问题?
进一步的问题:
我可以将环境变量与容器等服务一起使用吗(用于 DB 连接字符串)?
如何访问 Traefik 仪表板?我认为每个仪表板都会显示不同的数据。
如何向 Traefik 添加自己的 SSL 证书?Swarm 服务是否支持本地存储?(我支持简单的解决方案,很乐意每年一次在所有 3 个节点上复制我的 .pem)
如何启用 SSL 并将 http 重定向到 https?
我可以添加域路径以
http://a.domain.tld/api
使用不同的服务吗?如何收集容器日志?Elastic Filebeat 可以与工作容器配合使用吗?
否则,我很高兴收到有关计划中的 IT 架构的任何反馈。
谢谢,bluepuma
答案1
带有 Traefik 2.4 的 Docker Swarm 基本模板、基于域的路由、常规 SSL以及可扩展的 Web 应用程序,全部位于裸机服务器上。
Traefik 将在所有主节点上运行,直接监听主机的端口 0.0.0.0:80 和 0.0.0.0:443。http 升级为 https,web-apps 在工作节点上启动并自动注册到其域。然后 Traefik 将对所有传入请求进行负载平衡,并将其转发到匹配的工作容器。
请注意,这不是故障转移解决方案。您需要在此设置前面安装一个负载平衡器或一个浮动 IP,以便在服务器发生故障时进行切换。
要求:设置一个 Docker Swarm,这超出了本文的范围。Traefik 运行的每个 Docker Swarm 主节点都需要一个包含 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
配置.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
您可以降低 log.level(或将其完全删除),也可以删除 accesslog。或者,可以将这两种类型记录到两个不同的文件中。此配置中仍缺少 Traefik 仪表板。
为了提高安全性,你可以使用 docker-socket-proxy,@webjocky 在他的 pastebin 中描述了这次讨论。