Google 云 运行 自定义域不适用于网络套接字
Google Cloud Run custom domains do not work with web sockets
我使用 Google Cloud Run for Anthos. However, since I created the deployment using a GitLab CI pipeline, by default the service was assigned a long and obscure domain name (e.g. http://sudoku.dashboards-19751688-sudoku.k8s.proteinsolver.org/).
成功部署了一个简单的 Voila 仪表板
我遵循了 mapping custom domains to map a shorter custom domain to the service described above (e.g http://sudoku.k8s.proteinsolver.org) 中的说明。然而,虽然静态资产可以从这个新的自定义域中正常加载,但交互式仪表板不会加载,并且 javascript 控制台会填充错误:
default.js:64 WebSocket connection to 'wss://sudoku.k8s.proteinsolver.org/api/kernels/5bcab8b9-11d5-4de0-8a64-399e35258aa1/channels?session_id=7a0eed38-77bb-40e8-ad77-d05632b5fa1b' failed: Error during WebSocket handshake: Unexpected response code: 503
_createSocket @ scheduler.production.min.js:10
[...]
有没有办法让网络套接字与自定义域一起工作?我做错了什么吗?
我对您的 GitLab CI 管道一无所知。默认情况下,Knative(Cloud 运行 for Anthos)分配外部域名,例如 {name}.{namespace}.example.com
,其中 example.com 可以根据您的域进行自定义。
您可以在 Cloud Console 或 kubectl get ksvc
中找到此域。
首先尝试此域是否可以与 websockets 一起正常工作。如果是这样,那确实是一个“自定义域”问题。 (如果您不确定,请编辑您的 title/question,不要提及“自定义域”。)
此外,您需要在 Knative 上明确地将您的容器端口标记为 h2c
,以便 websockets 工作。请参阅下面的 ports
部分,特别是 name: h2c
:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
ports:
- name: h2c
containerPort: 8080
我还看到您的请求的响应代码是 HTTP 503,可能表示服务器错误。请检查您的应用程序日志。
TLDR,需要应用以下 yaml 才能使 websocket 工作:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: allowconnect-cluser-local-gateway
namespace: gke-system
spec:
workloadSelector:
labels:
app: cluster-local-gateway
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
http2_protocol_options:
allow_connect: true
这里是解释。
对于自定义域功能,请求路径为
client ---> istio-ingress envoy pods ---> cluster-local-gateway envoy pods ---> user's application.
专门针对websocket请求,需要cluster-local-gateway
envoy pods支持extended CONNECT特性。
EnvoyFilter
yaml 通过在 cluster-local-gateway
pods.[=19= 中将 allow_connect
设置为 true
来启用 extended CONNECT
功能]
我自己试了一下,对我有用。
我使用 Google Cloud Run for Anthos. However, since I created the deployment using a GitLab CI pipeline, by default the service was assigned a long and obscure domain name (e.g. http://sudoku.dashboards-19751688-sudoku.k8s.proteinsolver.org/).
成功部署了一个简单的 Voila 仪表板我遵循了 mapping custom domains to map a shorter custom domain to the service described above (e.g http://sudoku.k8s.proteinsolver.org) 中的说明。然而,虽然静态资产可以从这个新的自定义域中正常加载,但交互式仪表板不会加载,并且 javascript 控制台会填充错误:
default.js:64 WebSocket connection to 'wss://sudoku.k8s.proteinsolver.org/api/kernels/5bcab8b9-11d5-4de0-8a64-399e35258aa1/channels?session_id=7a0eed38-77bb-40e8-ad77-d05632b5fa1b' failed: Error during WebSocket handshake: Unexpected response code: 503
_createSocket @ scheduler.production.min.js:10
[...]
有没有办法让网络套接字与自定义域一起工作?我做错了什么吗?
我对您的 GitLab CI 管道一无所知。默认情况下,Knative(Cloud 运行 for Anthos)分配外部域名,例如 {name}.{namespace}.example.com
,其中 example.com 可以根据您的域进行自定义。
您可以在 Cloud Console 或 kubectl get ksvc
中找到此域。
首先尝试此域是否可以与 websockets 一起正常工作。如果是这样,那确实是一个“自定义域”问题。 (如果您不确定,请编辑您的 title/question,不要提及“自定义域”。)
此外,您需要在 Knative 上明确地将您的容器端口标记为 h2c
,以便 websockets 工作。请参阅下面的 ports
部分,特别是 name: h2c
:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
ports:
- name: h2c
containerPort: 8080
我还看到您的请求的响应代码是 HTTP 503,可能表示服务器错误。请检查您的应用程序日志。
TLDR,需要应用以下 yaml 才能使 websocket 工作:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: allowconnect-cluser-local-gateway
namespace: gke-system
spec:
workloadSelector:
labels:
app: cluster-local-gateway
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
http2_protocol_options:
allow_connect: true
这里是解释。
对于自定义域功能,请求路径为
client ---> istio-ingress envoy pods ---> cluster-local-gateway envoy pods ---> user's application.
专门针对websocket请求,需要cluster-local-gateway
envoy pods支持extended CONNECT特性。
EnvoyFilter
yaml 通过在 cluster-local-gateway
pods.[=19= 中将 allow_connect
设置为 true
来启用 extended CONNECT
功能]
我自己试了一下,对我有用。