无法通过 Kubernetes 入口访问 websocket
Unable to access websocket over Kubernetes ingress
我已将两项服务部署到 GCP 上的 Kubernetes 集群:
一个是Spring云Api网关实现:
apiVersion: v1
kind: Service
metadata:
name: api-gateway
spec:
ports:
- name: main
port: 80
targetPort: 8080
protocol: TCP
selector:
app: api-gateway
tier: web
type: NodePort
另一个是后端聊天服务实现,它在 /ws/
路径公开了一个 WebSocket。
apiVersion: v1
kind: Service
metadata:
name: chat-api
spec:
ports:
- name: main
port: 80
targetPort: 8080
protocol: TCP
selector:
app: chat
tier: web
type: NodePort
API 网关通过 Contour Ingress Controller:
暴露在互联网上
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: api-gateway-ingress
annotations:
kubernetes.io/tls-acme: "true"
certmanager.k8s.io/cluster-issuer: "letsencrypt-prod"
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- secretName: api-gateway-tls
hosts:
- api.mydomain.com.br
rules:
- host: api.mydomain.com.br
http:
paths:
- backend:
serviceName: api-gateway
servicePort: 80
网关将传入呼叫路由到 /chat/
路径到 /ws/
上的聊天服务:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/chat/**")
.filters(f -> f.rewritePath("/chat/(?<segment>.*)", "/ws/(?<segment>.*)"))
.uri("ws://chat-api"))
.build();
}
当我尝试通过网关连接到 WebSocket 时,出现 403 错误:
error: Unexpected server response: 403
我什至尝试使用 http、https、ws 和 wss 进行连接,但错误仍然存在。
有人知道吗?
我在使用 Contour 0.5.0 的 Ingress 资源时遇到了同样的问题,但我设法解决了它
使用 IngressRoute 将 Contour 升级到 v0.6.0-beta.3(但请注意,它是测试版)。
您可以像这样添加 IngressRoute 资源 (crd)(删除您之前的入口资源):
#ingressroute.yaml
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
name: api-gateway-ingress
namespace: default
spec:
virtualhost:
fqdn: api.mydomain.com.br
tls:
secretName: api-gateway-tls
routes:
- match: /
services:
- name: api-gateway
port: 80
- match: /chat
enableWebsockets: true # Setting this to true enables websocket for all paths that match /chat
services:
- name: api-gateway
port: 80
然后应用它
Websockets 将仅在 /chat
路径上被授权。
有关 Contour IngressRoute 的更多详细信息,请参阅 here。
我已将两项服务部署到 GCP 上的 Kubernetes 集群:
一个是Spring云Api网关实现:
apiVersion: v1
kind: Service
metadata:
name: api-gateway
spec:
ports:
- name: main
port: 80
targetPort: 8080
protocol: TCP
selector:
app: api-gateway
tier: web
type: NodePort
另一个是后端聊天服务实现,它在 /ws/
路径公开了一个 WebSocket。
apiVersion: v1
kind: Service
metadata:
name: chat-api
spec:
ports:
- name: main
port: 80
targetPort: 8080
protocol: TCP
selector:
app: chat
tier: web
type: NodePort
API 网关通过 Contour Ingress Controller:
暴露在互联网上apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: api-gateway-ingress
annotations:
kubernetes.io/tls-acme: "true"
certmanager.k8s.io/cluster-issuer: "letsencrypt-prod"
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- secretName: api-gateway-tls
hosts:
- api.mydomain.com.br
rules:
- host: api.mydomain.com.br
http:
paths:
- backend:
serviceName: api-gateway
servicePort: 80
网关将传入呼叫路由到 /chat/
路径到 /ws/
上的聊天服务:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/chat/**")
.filters(f -> f.rewritePath("/chat/(?<segment>.*)", "/ws/(?<segment>.*)"))
.uri("ws://chat-api"))
.build();
}
当我尝试通过网关连接到 WebSocket 时,出现 403 错误:
error: Unexpected server response: 403
我什至尝试使用 http、https、ws 和 wss 进行连接,但错误仍然存在。
有人知道吗?
我在使用 Contour 0.5.0 的 Ingress 资源时遇到了同样的问题,但我设法解决了它 使用 IngressRoute 将 Contour 升级到 v0.6.0-beta.3(但请注意,它是测试版)。
您可以像这样添加 IngressRoute 资源 (crd)(删除您之前的入口资源):
#ingressroute.yaml
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
name: api-gateway-ingress
namespace: default
spec:
virtualhost:
fqdn: api.mydomain.com.br
tls:
secretName: api-gateway-tls
routes:
- match: /
services:
- name: api-gateway
port: 80
- match: /chat
enableWebsockets: true # Setting this to true enables websocket for all paths that match /chat
services:
- name: api-gateway
port: 80
然后应用它
Websockets 将仅在 /chat
路径上被授权。
有关 Contour IngressRoute 的更多详细信息,请参阅 here。