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 都不错。
我设置了一个 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 都不错。