前言
随着 Kubernetes 的普及,越來越多的應用被容器化,并部署到 Kubernetes 上。随之而來的問題是當容器中發生錯誤時,對錯誤的定位和調試也變得很複雜。當一個工具給你帶來便利時,它也可能給你帶來另一些麻煩。
那麼有沒有工具可以在本地聯通 Kubernetes 叢集并進行調試呢?當然是有的,這裡就介紹一款研發側利器:
Kt Connect
Kt Connect
Kt Connect
是阿裡巴巴開源的一款雲原生協同開發測試解決方案,目前的功能包括:
- 直接通路 Kubernetes 叢集
- 轉發叢集流量到本地
- Service Mesh 支援
- 基于 SSH 的輕量級 VPN 網絡
- 作為 kubectl 插件,內建到 Kubectl
(以上内容來自
官方文檔)
目前使用下來最實用的功能就是直接連接配接 Kubernetes 網絡實作在本地使用 k8s 内網域名調用 Kubernetes 叢集内的服務以及将 Kubernetes 叢集中的流量轉發到本地,作用類似于一個 VPN,将本地網絡與 Kubernetes 叢集網絡連接配接。

安裝
Kt Connect
使用 Go 開發,支援 Mac、Linux 和 Windows,安裝方式也很簡單
前往
Github Releases下載下傳可執行檔案
Mac
安裝sshuttle
brew install sshuttle
下載下傳并安裝KT
$ curl -OL https://rdc-incubators.oss-cn-beijing.aliyuncs.com/stable/ktctl_darwin_amd64.tar.gz
$ tar -xzvf ktctl_darwin_amd64.tar.gz
$ mv ktctl_darwin_amd64 /usr/local/bin/ktctl
$ ktctl -h
Linux
pip install sshuttle
$ curl -OL https://rdc-incubators.oss-cn-beijing.aliyuncs.com/stable/ktctl_linux_amd64.tar.gz
$ tar -xzvf ktctl_linux_amd64.tar.gz
$ mv ktctl_linux_amd64 /usr/local/bin/ktctl
$ ktctl -h
Windows
下載下傳并解壓可執行檔案,并確定ktctl在PATH路徑下
本地連接配接叢集
以MacOS為例
使用
ktctl connect
指令,啟動的時候需要 admin 權限,需要輸入密碼
$ ktctl --namespace=default connect
1:51PM INF Connect Start At 69444
1:51PM INF Client address 192.168.7.121
1:51PM INF deploy shadow deployment kt-connect-daemon-rcacy in namespace default
1:51PM INF pod label: kt=kt-connect-daemon-rcacy
1:51PM INF pod: kt-connect-daemon-rcacy-fd4c587f-zmn4z is running,but not ready
1:51PM INF pod: kt-connect-daemon-rcacy-fd4c587f-zmn4z is running,but not ready
1:51PM INF Shadow pod: kt-connect-daemon-rcacy-fd4c587f-zmn4z is ready.
Forwarding from 127.0.0.1:2222 -> 22
Forwarding from [::1]:2222 -> 22
1:51PM INF port-forward start at pid: 69445
[local sudo] Password: 1:51PM INF vpn(sshuttle) start at pid: 69449
1:51PM INF KT proxy start successful
# 這裡需要輸入密碼
Handling connection for 2222
Warning: Permanently added '[127.0.0.1]:2222' (ECDSA) to the list of known hosts.
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
client: Connected.
這裡可以看到在
namespace:default
中部署了一個
kt-connect-daemon-*
的
Deployment
,如果這個
Deployment
啟動正常,就可以直接在本地通路 Kubernetes 叢集内的服務了。
$ kubectl get deploy | grep kt
kt-connect-daemon-rcacy 1/1 1 1 5m35s
通路叢集服務,可以使用
curl
或者直接在浏覽器通路。(這裡使用之前文章
《使用 Grafana 展示肺炎疫情動态》中部署的服務)
curl
curl
$ curl kk-feiyan
UP
直接使用浏覽器
ktctl exchange
指令,這個指令的前提條件是 Kubernetes 叢集中必須有已經已經存在的
Deployment
,在運作該指令時,将會起一個 shadow 容器,來代替已存在的 Deployment,調用該容器的流量,都會被轉發到本地的指定端口。
要注意的是:該指令會将其代替的 Deployment 的 replicas 設定為0,可能會導緻業務的暫停,請勿在生産環境中使用!
本地啟動一個服務
運作指令
$ ktctl exchange kk-feiyan --expose 8088
2:13PM INF 'KT Connect' is runing, you can access local app from cluster and localhost
2:13PM INF Client address 192.168.7.121
2:13PM INF deploy shadow deployment kk-feiyan-kt-yssnq in namespace default
2:13PM INF pod label: kt=kk-feiyan-kt-yssnq
2:13PM INF pod: kk-feiyan-kt-yssnq-6464bbf74d-smvhc is running,but not ready
2:13PM INF pod: kk-feiyan-kt-yssnq-6464bbf74d-smvhc is running,but not ready
2:13PM INF Shadow pod: kk-feiyan-kt-yssnq-6464bbf74d-smvhc is ready.
2:13PM INF create exchange shadow kk-feiyan-kt-yssnq in namespace default
2:13PM INF scale deployment kk-feiyan to 0
2:13PM INF * kk-feiyan (0 replicas) success
2:13PM INF remote 172.22.1.166 forward to local 8088
Forwarding from 127.0.0.1:2266 -> 22
Forwarding from [::1]:2266 -> 22
2:13PM INF exchange port forward to local start at pid: 70269
2:13PM INF redirect request from pod 172.22.1.166 22 to 127.0.0.1:2266 starting
Handling connection for 2266
Warning: Permanently added '[127.0.0.1]:2266' (ECDSA) to the list of known hosts.
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
2:13PM INF ssh remote port-forward start at pid: 70270
檢視 Deployment
$ kubectl get deploy | grep kk-feiyan
kk-feiyan 0/0 0 0 39d # 原服務
kk-feiyan-kt-eclcc 1/1 1 1 89s # 轉發流量服務
這樣的話,叢集内調用
kk-feiyan
這個服務的流量都會被轉發到本地
叢集内調用:
$ curl kk-feiyan
UP
可以看到流量被抓發到了本地
将本地服務暴露到 Kubernetes 叢集
有些時候,我們并不想使用
exchange
來代替已經存在的 Deployment,隻想在叢集内建立一個服務來将流量轉發到本,以完成調試。
這個時候使用
ktctl run
,就可以滿足需求,該指令會在 Kubernetes 叢集中建立一個服務,并将通路該服務的流量被轉發到本地的指定端口。
$ ktctl run localservice --port 8088 --expose
2:33PM INF Client address 192.168.7.121
2:33PM INF deploy shadow deployment localservice in namespace default
2:33PM INF pod label: kt=localservice
2:33PM INF pod: localservice-77d565c488-64hpp is running,but not ready
2:33PM INF pod: localservice-77d565c488-64hpp is running,but not ready
2:33PM INF Shadow pod: localservice-77d565c488-64hpp is ready.
2:33PM INF create shadow pod localservice-77d565c488-64hpp ip 172.22.1.74
2:33PM INF expose deployment localservice to localservice:8088
2:33PM INF remote 172.22.1.74 forward to local 8088
Forwarding from 127.0.0.1:2274 -> 22
Forwarding from [::1]:2274 -> 22
2:33PM INF exchange port forward to local start at pid: 70899
2:33PM INF redirect request from pod 172.22.1.74 22 to 127.0.0.1:2274 starting
Handling connection for 2274
Warning: Permanently added '[127.0.0.1]:2274' (ECDSA) to the list of known hosts.
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
2:33PM INF ssh remote port-forward start at pid: 70903
2:33PM INF forward remote 172.22.1.74:8088 -> 127.0.0.1:8088
可以看到該服務已經被拉起了
$ kubectl get deploy localservice
NAME READY UP-TO-DATE AVAILABLE AGE
localservice 1/1 1 1 86s
通路該服務
$ curl localservice:8088
UP
可以看到流量被轉發到了本地
總結
本地通路 k8s 内網,将 k8s 流量轉發到本地,靠着這兩大功能
Kt Connect
可以稱之為研發側的利器,我們可以輕松的在本地調用叢集服務,或者讓叢集調用本地的服務,這就讓開發/測試 k8s 叢集中發起調用的服務,在本地斷點 debug 成為了現實,非常好用。同時還有其他一些沒有介紹的功能,比如:
- Service Mesh 支援,可以支援使用者可以基于Service Mesh的能力做更多自定義的流量規則定義
- Dashboard 功能,管理是以使用 kt 連入叢集的使用者等等
值得一提的是,
ktctl run
功能是我提出該場景并希望能實作,該
issue提出僅一天就通過并完成了開發。給高效的開發人員點贊。