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 功能]

我自己试了一下,对我有用。