HTTP 状态 502 的 Traefik 自定义错误中间件不起作用

Traefik custom error middleware for HTTP status 502 doesn’t work

我想为常见的 HTTP 错误代码提供自定义错误页面。我正在关注 this tutorial。为此,我创建了以下 docker-compose.yml 文件来测试功能。它包括:

  1. errorPageHandler 这是一个 nginx 服务器,能够 return 静态 HTML 页面(404.html502.html)。

  2. whoami1 将请求路由到 traefik/whoami image

    的端口 80
  3. whoami2 将请求路由到 traefik/whoami 图像的不存在的端口 81,导致 502 - Bad Gateway

version: "3.7"

services:
  errorPageHandler:
    image: "nginx:latest"
    networks:
      - traefik-net
    volumes:
      - "./ErrorPages:/usr/share/nginx/ErrorPages"
      - "./default.conf:/etc/nginx/conf.d/default.conf"
    deploy:
      replicas: 1
      labels:
        # enable Traefik for this service
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-net"

        # router (catches all requests with lowest possible priority)
        - "traefik.http.routers.error-router.rule=HostRegexp(`{catchall:.*}`)"
        - "traefik.http.routers.error-router.priority=1"
        - "traefik.http.routers.error-router.middlewares=error-pages-middleware"

        # middleware
        - "traefik.http.middlewares.error-pages-middleware.errors.status=400-599"
        - "traefik.http.middlewares.error-pages-middleware.errors.service=error-pages-service"
        - "traefik.http.middlewares.error-pages-middleware.errors.query=/{status}.html"

        # service
        - "traefik.http.services.error-pages-service.loadbalancer.server.port=80"
  
  whoami1:
    image: "traefik/whoami"
    networks:
      - traefik-net
    deploy:
      replicas: 1
      labels:
        # enable Traefik for this service
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-net"

        # router
        - "traefik.http.routers.whoami1.rule=HostRegexp(`whoami1.local`)"
        - "traefik.http.routers.whoami1.service=whoami1"
        
        # service
        - "traefik.http.services.whoami1.loadbalancer.server.port=80"
        - "traefik.http.services.whoami1.loadbalancer.server.scheme=http"
        
  whoami2:
    image: "traefik/whoami"
    networks:
      - traefik-net
    deploy:
      replicas: 1
      labels:
        # enable Traefik for this service
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-net"

        # router
        - "traefik.http.routers.whoami2.rule=HostRegexp(`whoami2.local`)"
        - "traefik.http.routers.whoami2.service=whoami2"
        
        # service
        - "traefik.http.services.whoami2.loadbalancer.server.port=81" # purposely wrong port
        - "traefik.http.services.whoami2.loadbalancer.server.scheme=http"

networks:
  traefik-net:
    external: true
    name: traefik-net

文件夹 ErrorPages 包含两个静态 HTML 文件,404.html502.htmldefault.conf的内容是:

server {
    listen       80;
    server_name  localhost;

    error_page  404    /404.html;
    error_page  502    /502.html;

    location / {
        root  /usr/share/nginx/ErrorPages;
        internal;
    }
}

我在我的 hosts 文件中添加了以下条目(172.15.16.17 是部署了 Traefik 和所有提到的服务的服务器的 IP):

172.15.16.17 error404.local
172.15.16.17 whoami1.local
172.15.16.17 whoami2.local

我的观察:

  1. 当我访问 http://error404.local 时,Traefik 将请求路由到 nginx 并且 404.html 被 returned。这是预期的行为,因为 http://error404.local 与 Traefik 中定义的任何路由都不匹配。

  2. 当我访问 http://whoami1.local 时,Traefik 将请求路由到 whoami1 服务,并且有关容器的信息显示在页面上(预期行为)。

  3. 当我访问 http://whoami2.local 时,Traefik 不会将请求路由到 nginx 服务,但会显示其默认的 Bad Gateway 页面。为什么它不将请求路由到 nginx?

traefik 路由器(whoami1 和 whoami2)需要使用您定义的错误中间件

https://doc.traefik.io/traefik/middlewares/http/errorpages/ Traefik error middleware docs

所以将以下标签添加到各自的容器中

- "traefik.http.whoami1.middlewares=error-pages-middleware"

- "traefik.http.whoami2.middlewares=error-pages-middleware"

Traefik 仪表板将显示路由正在使用中间件(参考图片)One of my routes from my traefik dashboard

另一种选择是将中间件添加到入口点,以便所有路由都使用错误中间件(将其添加到 traefik 容器 compose)

command:
  - "--entrypoints.websecure.address=:443"
  - "--entrypoints.websecure.http.middlewares=error-pages-middleware@docker"