如何使用 CLI 在裸机上设置 Docker Swarm + Traefik 2.4 + 基于域的路由?

如何使用 CLI 在裸机上设置 Docker Swarm + Traefik 2.4 + 基于域的路由?

我想扩展我的小型 Docker Web 应用并使其具有高可用性。我已经使用 Docker 多年,K8s 似乎过于复杂,因此我正在研究 Docker Swarm。

多彩的 IT 架构图

这个想法很简单:首先使用高可用性负载均衡器,将所有 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

假设:

  1. Traefik 在 Swarm 主节点上运行以获取 Docker 事件通知
  2. Traefik 直接监听主节点的外部端口 80
  3. Traefik 将识别新服务并根据域名路由到容器
  4. 同一服务的多个 webapp 容器可以运行在同一个工作节点上

主要问题:如何启动并运行基本版本?有什么问题?

进一步的问题:

  1. 我可以将环境变量与容器等服务一起使用吗(用于 DB 连接字符串)?

  2. 如何访问 Traefik 仪表板?我认为每个仪表板都会显示不同的数据。

  3. 如何向 Traefik 添加自己的 SSL 证书?Swarm 服务是否支持本地存储?(我支持简单的解决方案,很乐意每年一次在所有 3 个节点上复制我的 .pem)

  4. 如何启用 SSL 并将 http 重定向到 https?

  5. 我可以添加域路径以http://a.domain.tld/api使用不同的服务吗?

  6. 如何收集容器日志?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 中描述了这次讨论

相关内容