docker - 如何使 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";
}
}
有谁知道如何解决这个问题?
解决方案
推荐阅读
- java - 如何制作归并排序算法?
- angular - 如何将离子 http GET 请求从 @angular\Http 转换为 @ion-native\Http?
- java - 从文件创建的数组,程序挂在使用它的任何方法上
- vb.net - 将参数传递给水晶报表
- javascript - Sequelize:如何防止包含关系的虚拟列出现在查询结果中?
- selenium - 在尝试通过 getPagesource 从 Selenium 解析 PageSource 时,元素类型“link”必须由匹配的结束标记“”终止
- reactjs - React v4 和 Redux:API 调用后更新 URL 以显示新路由?
- javascript - ES6通过数组中的对象属性求和
- elasticsearch - elasticsearch date_histogram offset 和 extended_bounds 不能一起工作?
- django - 在 Django-Organizations 中按组织过滤组织用户