使用 SOCKS5 代理訪問 Kubernetes API
特性狀態:
Kubernetes v1.24 [stable]
此頁面展示瞭如何使用 SOCKS5 代理訪問遠端 Kubernetes 叢集的 API。當你想訪問的叢集未在公共網際網路上直接公開其 API 時,這非常有用。
準備工作
你需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議你在至少有兩個節點且不作為控制平面主機的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用以下某個 Kubernetes 訓練場:
你的 Kubernetes 伺服器版本必須是 v1.24 或更高。要檢查版本,請輸入 kubectl version
。
你需要 SSH 客戶端軟體(`ssh` 工具)以及在遠端伺服器上執行的 SSH 服務。你必須能夠登入遠端伺服器上的 SSH 服務。
任務背景
注意
此示例使用 SSH 隧道傳輸流量,其中 SSH 客戶端和伺服器充當 SOCKS 代理。你也可以使用任何其他型別的 SOCKS5 代理。圖 1 展示了你在此任務中將要實現的目標。
- 你有一臺客戶端計算機,在接下來的步驟中稱為本地計算機,你將從這臺計算機建立請求以與 Kubernetes API 通訊。
- Kubernetes 伺服器/API 託管在遠端伺服器上。
- 你將使用 SSH 客戶端和伺服器軟體在本地和遠端伺服器之間建立安全的 SOCKS5 隧道。客戶端與 Kubernetes API 之間的 HTTPS 流量將透過 SOCKS5 隧道傳輸,該隧道本身又透過 SSH 隧道傳輸。
graph LR; subgraph local[本地客戶端機器] client([客戶端])-. 本地
流量 .-> local_ssh[本地 SSH
SOCKS5 代理]; end local_ssh[SSH
SOCKS5
代理]-- SSH 隧道 -->sshd subgraph remote[遠端伺服器] sshd[SSH
伺服器]-- 本地流量 -->service1; end client([客戶端])-. 經過代理的 HTTPS 流量
透過代理 .->service1[Kubernetes API]; classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; class ingress,service1,service2,pod1,pod2,pod3,pod4 k8s; class client plain; class cluster cluster;
流量 .-> local_ssh[本地 SSH
SOCKS5 代理]; end local_ssh[SSH
SOCKS5
代理]-- SSH 隧道 -->sshd subgraph remote[遠端伺服器] sshd[SSH
伺服器]-- 本地流量 -->service1; end client([客戶端])-. 經過代理的 HTTPS 流量
透過代理 .->service1[Kubernetes API]; classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; class ingress,service1,service2,pod1,pod2,pod3,pod4 k8s; class client plain; class cluster cluster;
使用 ssh 建立 SOCKS5 代理
以下命令在你的客戶端機器和遠端 SOCKS 伺服器之間啟動 SOCKS5 代理
# The SSH tunnel continues running in the foreground after you run this
ssh -D 1080 -q -N username@kubernetes-remote-server.example
SOCKS5 代理允許你根據以下配置連線到叢集的 API 伺服器
-D 1080
:在本地埠 1080 上開啟一個 SOCKS 代理。-q
:靜默模式。抑制大多數警告和診斷訊息。-N
:不執行遠端命令。僅用於埠轉發時很有用。username@kubernetes-remote-server.example
:Kubernetes 叢集執行的遠端 SSH 伺服器(例如:堡壘主機)。
客戶端配置
要透過代理訪問 Kubernetes API 伺服器,你必須指示 kubectl
透過我們之前建立的 SOCKS
代理傳送查詢。可以透過設定相應的環境變數,或透過 kubeconfig 檔案中的 proxy-url
屬性來完成此操作。使用環境變數:
export HTTPS_PROXY=socks5://:1080
要在特定的 kubectl
上下文中始終使用此設定,請在 ~/.kube/config
檔案中相關 cluster
條目內指定 proxy-url
屬性。例如:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LRMEMMW2 # shortened for readability
server: https://<API_SERVER_IP_ADDRESS>:6443 # the "Kubernetes API" server, in other words the IP address of kubernetes-remote-server.example
proxy-url: socks5://:1080 # the "SSH SOCKS5 proxy" in the diagram above
name: default
contexts:
- context:
cluster: default
user: default
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
user:
client-certificate-data: LS0tLS1CR== # shortened for readability
client-key-data: LS0tLS1CRUdJT= # shortened for readability
一旦你透過前面提到的 ssh 命令建立了隧道,並定義了環境變數或 proxy-url
屬性,你就可以透過該代理與你的叢集進行互動。例如:
kubectl get pods
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-85cb69466-klwq8 1/1 Running 0 5m46s
注意
- 在
kubectl
1.24 之前,大多數kubectl
命令在使用 socks 代理時都可以工作,除了kubectl exec
。 kubectl
支援HTTPS_PROXY
和https_proxy
環境變數。這些變數也被其他支援 SOCKS 的程式(例如curl
)使用。因此,在某些情況下,最好在命令列上定義環境變數HTTPS_PROXY=socks5://:1080 kubectl get pods
- 使用
proxy-url
時,代理僅用於相關的kubectl
上下文,而環境變數將影響所有上下文。 - 透過使用
socks5h
協議名稱而不是上面顯示的更常見的socks5
協議,Kubernetes API 伺服器的主機名可以進一步受到 DNS 洩露的保護。在這種情況下,kubectl
將要求代理伺服器(例如 SSH 堡壘機)解析 Kubernetes API 伺服器域名,而不是在執行kubectl
的系統上解析它。另請注意,對於socks5h
,像https://:6443/api
這樣的 Kubernetes API 伺服器 URL 並非指你的本地客戶端計算機。相反,它指的是在代理伺服器(例如 SSH 堡壘機)上已知的localhost
。
清理
在執行 SSH 埠轉發程序的終端中按 CTRL+C
停止它。
在終端中輸入 unset https_proxy
以停止透過代理轉發 http 流量。
進一步閱讀
上次修改時間為 2024 年 2 月 13 日下午 2:14 PST:修復 Mermaid 語法錯誤 (69706582d4)