I'm new to Traefik and struggling to get websockets to work. I have Kubernetes v1.27.1 on-premise, with Traefik v2.10.1 exposed on NodePorts. Furthermore, there is an ingress route to a web service that accepts normal HTTP requests at /
and exposes a websocket at /api/ws
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
spec:
ingressClassName: traefik
rules:
- host: example.com
http:
paths:
- backend:
service:
name: webapp
port:
number: 8000
path: /
pathType: Prefix
The issue is that when a client tries to establish a websocket connection at /api/ws
, Traefik strips the Conenction: upgarde
and Upgrade: websocket
headers. I've verified this by sending and receiving manual requests to the NodePorts with netcat.
I found a workaround by adding another ingress object that always injects the upgrade headers using a middleware. Something like
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-websocket
annotations:
traefik.ingress.kubernetes.io/router.middlewares: traefik-upgrade@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: example.com
http:
paths:
- backend:
service:
name: webapp
port:
number: 8000
path: /api/ws
pathType: Prefix
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: upgrade
namespace: traefik
# --- snip --
spec:
headers:
customRequestHeaders:
Connection: Upgrade
Upgrade: websocket
But I really don't like this approach. What's going wrong in the first place? Is Traefik supposed to strip the Upgrade headers? Is there a way to enable websockets explicitly?