Kubernetes 1.31:從 SPDY 串流傳輸過渡到 WebSockets

在 Kubernetes 1.31 中,預設情況下 kubectl 現在使用 WebSocket 協定而不是 SPDY 進行串流。

這篇文章描述了這些變更對您的意義,以及為什麼這些串流 API 很重要。

Kubernetes 中的串流 API

在 Kubernetes 中,作為 HTTP 或 RESTful 介面公開的特定端點會升級為串流連線,這需要串流協定。與作為請求-回應協定的 HTTP 不同,串流協定提供持久連線,該連線是雙向、低延遲的,並讓您即時互動。串流協定支援在您的用戶端和伺服器之間雙向讀取和寫入資料,透過相同的連線。例如,當您從本機工作站的執行中容器中建立 Shell 並在容器中執行命令時,這種連線類型很有用。

為什麼要變更串流協定?

在 v1.31 版本之前,Kubernetes 在升級串流連線時預設使用 SPDY/3.1 協定。SPDY/3.1 已被棄用八年,並且從未標準化。許多現代代理伺服器、閘道器和負載平衡器不再支援該協定。因此,當您嘗試透過代理伺服器或閘道器存取叢集時,您可能會注意到 kubectl cpkubectl attachkubectl execkubectl port-forward 等命令停止運作。

從 Kubernetes v1.31 開始,SIG API Machinery 修改了 Kubernetes 用戶端(例如 kubectl)用於這些命令的串流協定,改為更現代的 WebSocket 串流協定。WebSocket 協定是目前支援的標準化串流協定,可保證與不同組件和程式語言的相容性和互操作性。與 SPDY 相比,WebSocket 協定更廣泛地受到現代代理伺服器和閘道器的支援。

串流 API 的運作方式

Kubernetes 透過將特定的升級標頭新增至原始 HTTP 請求,將 HTTP 連線升級為串流連線。例如,在叢集內的 nginx 容器上執行 date 命令的 HTTP 升級請求類似於以下內容

$ kubectl exec -v=8 nginx -- date
GET https://127.0.0.1:43251/api/v1/namespaces/default/pods/nginx/exec?command=date…
Request Headers:
    Connection: Upgrade
    Upgrade: websocket
    Sec-Websocket-Protocol: v5.channel.k8s.io
    User-Agent: kubectl/v1.31.0 (linux/amd64) kubernetes/6911225

如果容器執行階段支援 WebSocket 串流協定,並且至少支援一個子協定版本(例如 v5.channel.k8s.io),伺服器會以成功的 101 Switching Protocols 狀態以及協商的子協定版本回應

Response Status: 101 Switching Protocols in 3 milliseconds
Response Headers:
    Upgrade: websocket
    Connection: Upgrade
    Sec-Websocket-Accept: j0/jHW9RpaUoGsUAv97EcKw8jFM=
    Sec-Websocket-Protocol: v5.channel.k8s.io

此時,用於 HTTP 協定的 TCP 連線已變更為串流連線。然後,此 Shell 互動的後續 STDIN、STDOUT 和 STDERR 資料(以及終端大小調整資料和程序結束代碼資料)將透過此升級的連線進行串流傳輸。

如何使用新的 WebSocket 串流協定

如果您的叢集和 kubectl 版本為 1.29 或更高版本,則有兩個控制平面功能閘道和兩個 kubectl 環境變數控制 WebSockets 而不是 SPDY 的使用。在 Kubernetes 1.31 中,以下所有功能閘道都處於 Beta 階段,並且預設為啟用

  • 功能閘道
    • TranslateStreamCloseWebsocketRequests
      • .../exec
      • .../attach
    • PortForwardWebsockets
      • .../port-forward
  • kubectl 功能控制環境變數
    • KUBECTL_REMOTE_COMMAND_WEBSOCKETS
      • kubectl exec
      • kubectl cp
      • kubectl attach
    • KUBECTL_PORT_FORWARD_WEBSOCKETS
      • kubectl port-forward

如果您連線到較舊的叢集,但可以管理功能閘道設定,請開啟 TranslateStreamCloseWebsocketRequests(在 Kubernetes v1.29 中新增)和 PortForwardWebsockets(在 Kubernetes v1.30 中新增),以嘗試此新行為。kubectl 的 1.31 版本可以自動使用新行為,但您確實需要連線到伺服器端功能已明確啟用的叢集。

深入了解串流 API