<p>See the connected question - <a href="https://stackoverflow.com/q/46968582/2790937">Kubernetes pod exec API exception: Response must not include &#39;Sec-WebSocket-Protocol&#39; header if not present in request</a>.</p>

<p>I have been able to successfully make a WebSocket connection using Pod <code>exec</code> API. But I am using <code>kubectl proxy</code> on localhost to handle the authorization on behalf of the terminal client.</p>

<p>The next step is to be able to authorize the request directly to the kubernetes API server, so that there's no need to route the traffic via <code>kubectl proxy</code>. <a href="https://github.com/kubernetes-incubator/client-python/issues/58" rel="nofollow noreferrer">Here's a discussion</a> in the python community where they have been able to send Authorization token to the api-server. But I haven't had any success with this in nodejs. I must admit that I am not familiar with python as well to understand the discussion enough.</p>

<p>Can someone from the kubernetes team point me in the right direction?</p>

<p>Thanks</p>

<p>For future wanderers....</p>

<p>Although the <code>exec</code> API supports <code>Authorization</code> header, the browser WebSocket API doesn't support it yet. So the solution for us was to reverse-proxy it from our server APIs. </p>

<p>It went like this...</p>

<p>client browser -wss-> GKE LB (SSL Termination) -ws-> site API (nodejs) -WSS &amp; Authorization-> kube api-server exec API</p>

<p><strong>So to answer my own question</strong>, per my tests, the GKE kubernetes supports Authorization only in headers, so you need to reverse proxy if you want to connect to it via browser. Per <a href="https://github.com/kubernetes-ui/container-terminal/" rel="nofollow noreferrer">this code</a>, some Kubernetes setups allow tokens in the query string, but I didn't have any success with GKE. If you are using a different cluster host, YMMY. I welcome comments from kubernetes team on my observations.</p>

<p>If you came here only for an authorization issue, you may stop reading further.</p>

<p>There are still more challenges to overcome though, and there's good news and bad news... the good news first:</p>

<p>GKE Loadbalancer automatically handles SSL termination <a href="https://cloud.google.com/compute/docs/load-balancing/http/#websocket_proxy_support" rel="nofollow noreferrer">even for WebSockets</a>, so you can proxy to either WS or WSS without any issues.</p>

<p>And then the bad news:</p>

<p>GKE Loadbalancer force terminates ALL connections within 30 seconds, even if they are in use! There are workarounds, but they either <a href="https://github.com/kubernetes/kubernetes/issues/32273#issuecomment-297190222" rel="nofollow noreferrer">don't stay put</a>, require you to <a href="https://github.com/kubernetes/kubernetes/issues/24745#issuecomment-241410916" rel="nofollow noreferrer">deploy your own controller</a>, or you need to use <a href="https://github.com/kubernetes/ingress-nginx/issues/243" rel="nofollow noreferrer">Ingress</a>. What this means for a Terminal sessions is that Chrome will close the client with a 1006 code, even if a command is running at that time.</p>

<p>For some WS scenarios, it may be acceptable to simply reconnect on a 1006 close, but for a terminal session, this is a deal-breaker as you cannot reconnect to the previous terminal instance and must begin with a new one.</p>

<p>For now we have resorted to increasing the timeout of the GKE Loadbalancer. But eventually we are planning to deploy our own Loadbalancer which can handle this better. Ingress has <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/#before-you-begin" rel="nofollow noreferrer">some issues</a> which we don't want to live with at the moment.</p>
