首页 > 解决方案 > 如何使 websocket 与 traefik 和 docker 一起工作?

问题描述

我已经阅读了所有相关的 traefik / websocket 问题here和其他论坛,但我无法解决我的设置问题。

我正在尝试在 Traefik 后面运行 Dataiku DSS 作为反向代理。但我还是 Traefik 的新手,不知道如何通过 Traefik 为我的服务制作 websockets。

我正在使用以下配置:

traefik.yml:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  http:
    acme:
      email: admin@example.com
      storage: acme.json
      httpChallenge:
        entryPoint: http

traefik/docker-compose.yml:

version: '3'

services:
  traefik:
    image: traefik:v2.0
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=<USER>:<PW>"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "traefik.http.routers.traefik-secure.service=api@internal"

networks:
  proxy:
    external: true

dataiku/docker-compose.yml:

version: '3.7'
services:
  dataiku:
    build:
      context: .
      dockerfile: Dockerfile
    restart: on-failure
    volumes:
      - dss_data:/home/dataiku/dss
    labels:
      - traefik.enable=true
      - traefik.http.routers.dataiku.entrypoints=http
      - traefik.http.routers.dataiku.rule=Host(`dataiku.example.com`)
      #- traefik.http.middlewares.dataiku-https-redirect.redirectscheme.scheme=https
      #- traefik.http.routers.dataiku.middlewares=dataiku-https-redirect
      #- traefik.http.routers.dataiku-secure.entrypoints=https
      #- traefik.http.routers.dataiku-secure.rule=Host(`dataiku.example.com`)
      #- traefik.http.routers.dataiku-secure.tls=true
      #- traefik.http.routers.dataiku-secure.tls.certresolver=http
      #- traefik.http.routers.dataiku-secure.service=dataiku
      - traefik.http.services.dataiku.loadbalancer.server.port=10000
      - traefik.docker.network=proxy

volumes:
  dss_data:

networks:
  proxy:
    external: true

但是,当我运行 dataiku 时,我看到 websocket 连接失败。在 Firefox 中,我看到在尝试 WS 连接之后,我收到以下错误:XSRF validation failed. 在 Chrome 上,我看到以下内容:Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received

请求标头如下所示:

Host: example.com
User-Agent: ...
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://example.com
Sec-WebSocket-Protocol: dummy, xsrf-7646db48d09813bbe5038c1aa2967e0a9712f81a24b156731f88bde5d3c4d8a5
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: 3sSlW9J6GN6d4+bhFr1IIQ==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

响应标头如下所示:

HTTP/1.1 101 Switching Protocols
Connection: upgrade
Date: Sat, 06 Jun 2020 15:18:08 GMT
Sec-Websocket-Accept: x29WLUMyl5OmRfhZOncdLE65lOU=
Server: nginx
Upgrade: WebSocket

这两个错误都向我表明,响应缺少正确的Sec-WebSocket-Protocol标头。但我不知道如何解决这个问题。最初我认为它可能与 TLS 有关,这就是我注释掉安全入口点和重定向的原因。但它仍然存在。

我以前对像这样的 nginx 配置没有任何问题:

server {
    # Host/port on which to expose Data Science Studio to users
    listen 80;
    server_name dss.example.com;
    location / {
        # Base url of the Data Science Studio installation
        proxy_pass http://DSS_HOST:DSS_PORT/;
        proxy_redirect off;
        # Allow long queries
        proxy_read_timeout 3600;
        proxy_send_timeout 600;
        # Allow large uploads
        client_max_body_size 0;
        # Allow protocol upgrade to websocket
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

有谁知道如何解决这个问题?

标签: dockerwebsockettraefik

解决方案


推荐阅读