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 cp
、kubectl attach
、kubectl exec
和 kubectl 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 版本可以自動使用新行為,但您確實需要連線到伺服器端功能已明確啟用的叢集。