• 网关路由
  • 为什么用apiserver转发websocket会产生两次连接

创建部署问题时,请参考下面模板,你提供的信息越多,越容易及时获得解答。如果未按模板创建问题,管理员有权关闭问题。
确保帖子格式清晰易读,用 markdown code block 语法格式化代码块。
你只花一分钟创建的问题,不能指望别人花上半个小时给你解答。

操作系统信息
例如:无关操作系统

Kubernetes版本信息
kubectl version 命令执行结果贴在下方

k8s.io/api v0.19.3
k8s.io/apiextensions-apiserver v0.19.3
k8s.io/apimachinery v0.19.3
k8s.io/apiserver v0.19.3
k8s.io/cli-runtime v0.18.6
k8s.io/client-go v12.0.0+incompatible
k8s.io/code-generator v0.19.0
k8s.io/component-base v0.19.3
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.0.0
k8s.io/kube-openapi v0.0.0-20200923155610-8b5066479488
k8s.io/kubectl v0.19.3
k8s.io/metrics v0.18.6
k8s.io/utils v0.0.0-20201005171033-6301aaf42dc7
kubesphere.io/client-go v0.0.0
kubesphere.io/monitoring-dashboard v0.1.2

容器运行时
docker version / crictl version / nerdctl version 结果贴在下方

KubeSphere版本信息
例如:v2.1.1/v3.0.0。离线安装还是在线安装。在已有K8s上安装还是使用kk安装。

问题是什么
当用api-server转发ws请求时,产生了两个连接。

查看代码,dispatch.go有设置httpProxy.UpgradeTransport

然后进入k8s.io-upgradeaware.go方法ServeHTTP(w http.ResponseWriter, req *http.Request)中

h.tryUpgrade(w, req) ->DialForUpgrade(req *http.Request)

如上图,如果h.UpgradeTransport 不为nil,会先执行UpgradeTransport.WrapRequest(req)后,然后执行dial(updatedReq, h.UpgradeTransport)。理论上WrapRequest(req)只是包装请求吧,会进入到RoundTrip,会有一个getConn的操作,会产生一次连接,然后wrap结束后,dial又产生一次连接。

getConn如图