KT Kubernetes 開發效率的免費工具

對於使用了 Kubernetes 作為應用運行環境的開發者而言,在同一個集群中我們可以使用命名空間(Namespace)快速創建多套隔離環境,在相同命名空間下,服務間使用 Service 的內部 DNS 域名進行相互訪問。 基於 Kubernetes 強大的隔離以及服務編排能力,可以實現一套定義編排(YAML)多處部署的能力。

不過,一般來說 Kubernetes 使用的容器網絡與開發者的所在的辦公網絡直接並不能直接連通。 因此,如何高效的利用 Kubernetes 進行服務間的聯調測試,成為在日常開發工作中一道繞不開的坎。本文我們就來聊一聊,如何加速基於 Kubernetes 的研發效率。

使用自動流水線

為了能夠讓開發者能夠更快的將修改的代碼部署到集群測試環境中,一般來說我們會引入持續交付流水線,將代碼的編譯,鏡像的打包上傳以及部署通過自動化的方式來解決。如下所示:

KT Kubernetes 開發效率的免費工具

從一定程度上來說,這種方式可以避免開發人員進行大量重複性的工作。但是,雖然整個過程自動化了,但是開發人員也不得不每次進行代碼變更之後都需要等待流水線的運行。對於開發人員來說,每次代碼變更後等待流水線運行或許已經成為整個開發任務過程中體驗最糟糕的部分。

打破網絡限制,本地聯調

理想狀態下是開發者可以直接在本地啟動服務,並且這個服務就可以無縫的和遠程的 kubernetes 集群中的各個其它服務實現互相調用。需要解決兩個問題:

  • 我依賴了其它的服務:運行在本地的代碼可以直接通過 podIP,clusterIP 甚至是 Kubernetes 集群內的 DNS 地址訪問到部署在集群中的其它應用,如下圖左;
  • 其它的服務依賴了我:運行在 Kubernetes 集群中的其它應用可以在不做任何改變的情況下訪問我到運行的本地的代碼,如下圖右。
KT Kubernetes 開發效率的免費工具

要實現剛才說的兩種本地聯調方式,主要需要解決以下 3 個問題:

  1. 本地網絡與 Kubernetes 集群網絡直接的連通問題
  2. 在本地實現 Kubernetes 中內部服務的 DNS 解析;
  3. 如果將對集群中其它 Pod 訪問的流量轉移到本地;

雲效開發者工具 KT

為了簡化在 Kubernetes 下進行聯調測試的複雜度,雲效在 SSH 隧道網絡的基礎上並結合 Kubernetes 特性構建了一款面向開發者的免費輔助工具 KT(點擊文末閱讀原文可直接下載),如下所示:

KT Kubernetes 開發效率的免費工具

當本地運行的服務 C’希望能夠直接訪問集群中 default 命名空間下的 Service A 和 Service B 時,運行如下命令:

複製代碼

$ ktctl -namespace=default

KT 會自動在集群中部署 SSH/DNS 代理容器,並構建本地到 Kubernetes 集群的 VPN 網絡並通過 DNS 代理實現集群服務 DNS 域名解析,在運行 KT 之後,開發者的本地程序可以直接像運行在集群中的服務一樣通過 service 名字調用集群中部署的其它應用:

而如果希望集群中的其它 Pod(比如圖中的 PodD 和 PodE)能夠通過 ServiceC 訪問到本地運行的程序 C‘,通過如下命令,指定需要替換的目標 Deployment 以及指定本地服務端口:

複製代碼

# -swap-deployment 指定需要替換的目標 Deployment
# -expose 指定本地服務運行的端口
ktctl -swap-deployment c-deployment -expose=8080

KT 在構建 VPN 網絡的同時,還會自動通過代理容器接管集群原有的 PodC 實例,並直接轉發的本地的 8080 端口。實現集群應用聯調本地。

經過上述兩個命令,開發者就可以真正的使用雲原生的方式來開發調試 Kubernetes 中的應用了。

工作原理

下面解析 KT 的工作原理,如果你已經迫不及待的想嘗試 KT 的功能,可以直接跳到文章末尾下載 KT 工具。

KT 主要由兩部分組成:

  1. 在本地運行的命令行工具 ktctl
  2. 運行在集群中的 SSH/DNS 代理容器。

在工作原理上 KT 實際上是結合 Kubernetes 自身能力實現的一個基於 SSH 的 VPN 網絡。這這部分,筆者將詳細介紹雲效 Kubernetes 開發者工具 KT 的工作原理:

打通 SSH 協議通道

在 Kubernetes 命令行工具 kubectl 中內置的 port-forward 命令可以幫助用戶建立本地端口到 Kubernetes 集群中特定 Pod 實例端口間的網絡轉發。

當我們在集群中部署一個包含 sshd 服務的容器後,通過 port-forward 可以將容器的 SSH 服務端口映射到本地:

複製代碼

# 將對本地 2222 端口轉發到 kt-porxy 實例的 22 端口
$ kubectl port-forward deployments/kt-proxy 2222:22
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

在運行端口轉發後,就可以直接通過本地的 2222 端口通過 SSH 協議進入到 Kubernetes 集群的 kt-proxy 實例中。從而打通本地與集群之間的 SSH 網絡鏈路。

本地動態端口轉發與 VPN

在打通 SSH 網絡之後,我們就可以利用 SSH 通道實現本地到集群的網絡請求,其中最基本的方式就是使用 SSH 動態端口轉發的能力。

使用如下命令,通過本地 2000 運行的代理,可以將網絡請求通過集群中運行的 kt-proxy 容器進行轉發,從而實現本地到集群網絡請求的轉發:

複製代碼

# ssh -D [本地網卡地址:] 本地端口 name@ip -p 映射到 kt-proxy 的 22 端口的本地端口
ssh -D 2000 [email protected] -p2222

在啟用 SSH 動態端口轉發後,通過設置 http_proxy 環境變量後,即可直接在命令行中訪問集群網絡:

複製代碼

# export http_proxy=socks5://127.0.0.1:ssh 動態端口轉發的代理端口
export http_proxy=socks5://127.0.0.1:2000

不過原生 SSH 動態端口轉發也有一定的限制那就是無法直接使用 UDP 協議,這裡我們選擇了一個替代方案 sshuttle. 如下命令所示:

複製代碼

# export http_proxy=socks5://127.0.0.1:ssh 動態端口轉發的代理端口
export http_proxy=socks5://127.0.0.1:2000
sshuttle --dns --to-ns 172.16.1.36 -e 'ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' -r [email protected]:2222 172.16.1.0/16 172.19.1.0/16 -vv

sshuttle 工具在 SSH 協議之上構建了一個簡易的 VPN 網絡,同時支持 DNS 協議轉發。

因此,接下來的問題就是實現一個自定義的 DNS 服務即可,而該服務在 KT 中是直接內置在 KT 代理鏡像中。

遠程端口轉發

在本地到集群的鏈路打通之後。 接下來需要解決的就是從集群到本地的訪問鏈路。這部分,我們會使用到 SSH 的遠程端口轉發能力,如下所示,指定所有對 kt-proxy 的 8080 端口的網絡請求都會通過 SSH 隧道直接轉發到本地的 8080 端口:

複製代碼

# ssh -R 8080:localhost:8080 [email protected] -p2222
ssh -R 8080:localhost:8080 [email protected] -p2222

因此,在 KT 的實現過程之中,結合 Kubernetes 基於標籤的松耦合能力,我們只需要克隆原有應用實例的 YAML 描述,並將容器替換為 kt-proxy 即可。從而將對集群中原有應用的請求通過 SSH 遠程端口轉發到本地。

綜上,通過利用 Kubernetes 原生能力以及適度的擴展,開發者可以快速在本地利用 KT 打破本地網絡與 Kubernetes 網絡之間的界限,大大提升使用 Kubernetes 進行聯調測試的效率。

小結

工具承載了對特定問題的解決方案,而工程技術實踐則是對其價值的放大。阿里巴巴雲效平臺,致力於為開發者提供一站式的企業研發與協作服務,並將阿里多年的軟件工程實踐以一種更加開發的形態反饋技術社區,歡迎更多的技術開發者入駐。

目前,Mac 用戶可以下載並體驗 KT 工具。


分享到:


相關文章: