開發與維運

Kt Connect:研發側利器,本地連通 Kubernetes 集群內網

前言

隨著 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

安裝sshuttle

pip install sshuttle

下載並安裝KT

$ 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 kk-feiyan
UP

直接使用瀏覽器

image

轉發集群流量到本地

使用 ktctl exchange 命令,這個命令的前提條件是 Kubernetes 集群中必須有已經已經存在的 Deployment,在運行該命令時,將會起一個 shadow 容器,來代替已存在的 Deployment,調用該容器的流量,都會被轉發到本地的指定端口。

要注意的是:該命令會將其代替的 Deployment 的 replicas 設置為0,可能會導致業務的暫停,請勿在生產環境中使用!

本地啟動一個服務

image

運行命令

$ 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

可以看到流量被抓發到了本地
image

將本地服務暴露到 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

可以看到流量被轉發到了本地
image

總結

本地訪問 k8s 內網,將 k8s 流量轉發到本地,靠著這兩大功能 Kt Connect 可以稱之為研發側的利器,我們可以輕鬆的在本地調用集群服務,或者讓集群調用本地的服務,這就讓開發/測試 k8s 集群中發起調用的服務,在本地斷點 debug 成為了現實,非常好用。同時還有其他一些沒有介紹的功能,比如:

  • Service Mesh 支持,可以支持用戶可以基於Service Mesh的能力做更多自定義的流量規則定義
  • Dashboard 功能,管理所以使用 kt 連入集群的用戶等等

值得一提的是,ktctl run 功能是我提出該場景並希望能實現,該 issue 提出僅一天就通過並完成了開發。給高效的開發人員點贊。

Leave a Reply

Your email address will not be published. Required fields are marked *