Docker Swarm - 请求无法到达不同节点上的服务

Docker Swarm - Requests fail to reach a service on a different node

我设置了一个 Docker Swarm,使用 Traefik v2 作为反向代理,并且 able to access the dashboard with no issues.

我遇到一个问题,我无法从运行在不同节点上的任何服务获得响应,而 Traefik 是 运行。我一直在测试和研究,并假设这是某种类型的网络问题。

我已经使用一个空的 Nginx 映像进行了一些快速测试,并且能够部署另一个堆栈并在映像位于同一节点上时获得响应。 swarm 上跨多个节点部署的其他堆栈(但不包括 Traefik 节点)能够毫无问题地相互通信。

这里是测试堆栈,提供了我所使用内容的一些上下文。

version: '3.8'

services:
    test:
        image: nginx:latest
        deploy:
            replicas: 1
            placement:
                constraints:
                    - node.role==worker
            labels:
                - "traefik.enable=true"
                - "traefik.docker.network=uccser-dev-public"
                - "traefik.http.services.test.loadbalancer.server.port=80"
                - "traefik.http.routers.test.service=test"
                - "traefik.http.routers.test.rule=Host(`TEST DOMAIN`) && PathPrefix(`/test`)"
                - "traefik.http.routers.test.entryPoints=web"
        networks:
            - uccser-dev-public

networks:
  uccser-dev-public:
    external: true

uccser-dev-public 网络是一个覆盖所有节点的覆盖网络,没有加密。

如果我添加了一个约束来指定 Traefik 节点,那么请求就没有问题。但是,如果我将它切换到不同的节点,我会得到 Traefik 404 页面。

The Traefik dashboard is showing it sees the service.

但是访问日志显示如下:

proxy_traefik.1.6fbx58k4n3fj@SWARM_NODE    | IP_ADDRESS - - [21/Jul/2021:09:03:02 +0000] "GET / HTTP/2.0" - - "-" "-" 1430 "-" "-" 0ms

一片空白,我不知道从哪里开始。正常的日志显示没有我能看到的错误。

Traefik 堆栈文件:

version: '3.8'

x-default-opts:
  &default-opts
  logging:
    options:
      max-size: '1m'
      max-file: '3'

services:
  # Custom proxy to secure docker socket for Traefik
  docker-socket:
    <<: *default-opts
    image: tecnativa/docker-socket-proxy
    networks:
      - traefik-docker
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      NETWORKS: 1
      SERVICES: 1
      SWARM: 1
      TASKS: 1
    deploy:
      placement:
        constraints:
          - node.role == manager

  # Reverse proxy for handling requests
  traefik:
    <<: *default-opts
    image: traefik:2.4.11
    networks:
      - uccser-dev-public
      - traefik-docker
    volumes:
      - traefik-public-certificates:/etc/traefik/acme/
    ports:
      - target: 80 # HTTP
        published: 80
        protocol: tcp
        mode: host
      - target: 443 # HTTPS
        published: 443
        protocol: tcp
        mode: host
    command:
      # Docker
      - --providers.docker
      - --providers.docker.swarmmode
      - --providers.docker.endpoint=tcp://docker-socket:2375
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=uccser-dev-public
      - --providers.docker.watch
      - --api
      - --api.dashboard
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443
      - --log.level=DEBUG
      - --global.sendAnonymousUsage=false
    deploy:
      placement:
        constraints:
            - node.role==worker
      # Dynamic Configuration
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.dashboard.rule=Host(`SWARM_NODE`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
        - "traefik.http.routers.dashboard.service=api@internal"
        - "traefik.http.services.dummy-svc.loadbalancer.server.port=9999" # Dummy service for Swarm port detection. The port can be any valid integer value.

volumes:
  traefik-public-certificates: {}

networks:
  # This network is used by other services
  # to connect to the proxy.
  uccser-dev-public:
    external: true
  # This network is used for Traefik to talk to
  # the Docker socket.
  traefik-docker:
    driver: overlay
    driver_opts:
      encrypted: 'true'

有什么想法吗?

进一步的测试表明其他服务在不同的节点上运行,因此我认为这一定是我的应用程序的问题。原来我的 Django 应用程序仍然为它以前的托管位置配置了一堆关于 HTTPS 的设置。由于它没有通过所需的设置,因此在处理之前拒绝了请求。我需要降低 gunicorn (WSGI) 的日志记录级别才能看到更多信息。

总而言之,Traefik 和 Swarm 都不错。