歡迎光臨
每天分享高質量文章

KT:一款提升Kubernetes應用開發效率的免費工具

對於使用了Kubernetes作為應用執行環境的開發者而言,在同一個叢集中我們可以使用名稱空間(Namespace)快速建立多套隔離環境,在相同名稱空間下,服務間使用Service的內部DNS域名進行相互訪問。 基於Kubernetes強大的隔離以及服務編排能力,可以實現一套定義編排(YAML)多處部署的能力。
不過,一般來說Kubernetes使用的容器網路與開發者的所在的辦公網路直接並不能直接連通。 因此,如何高效的利用Kubernetes進行服務間的聯調測試,成為在日常開發工作中一道繞不開的坎。本文我們就來聊一聊,如何加速基於Kubernetes的研發效率。
使用自動流水線

 

為了能夠讓開發者能夠更快的將修改的程式碼部署到叢集測試環境中,一般來說我們會引入持續交付流水線,將程式碼的編譯,映象的打包上傳以及部署透過自動化的方式來解決。如下所示: 
從一定程度上來說,這種方式可以避免開發人員進行大量重覆性的工作。但是,雖然整個過程自動化了,但是開發人員也不得不每次進行程式碼變更之後都需要等待流水線的執行。對於開發人員來說,每次程式碼變更後等待流水線執行或許已經成為整個開發任務過程中體驗最糟糕的部分。
打破網路限制,本地聯調

 

理想狀態下是開發者可以直接在本地啟動服務,並且這個服務就可以無縫的和遠端的Kubernetes叢集中的各個其它服務實現互相呼叫。需要解決兩個問題:
  • 我依賴了其它的服務:執行在本地的程式碼可以直接透過PodIP,ClusterIP甚至是Kubernetes叢集內的DNS地址訪問到部署在叢集中的其它應用,如下圖左;

  • 其它的服務依賴了我:執行在Kubernetes叢集中的其它應用可以在不做任何改變的情況下訪問我到執行的本地的程式碼,如下圖右。

要實現剛才說的兩種本地聯調方式,主要需要解決以下3個問題:
  1. 本地網路與Kubernetes叢集網路直接的連通問題;

  2. 在本地實現Kubernetes中內部服務的DNS解析;

  3. 如果將對叢集中其它Pod訪問的流量轉移到本地。

雲效開發者工具KT

 

為了簡化在Kubernetes下進行聯調測試的複雜度,雲效在SSH隧道網路的基礎上並結合Kubernetes特性構建了一款面向開發者的免費輔助工具KT(文末有下載連結),如下所示: 
當本地執行的服務C’希望能夠直接訪問叢集中default名稱空間下的Service A和Service B時,執行如下命令:
  1. $ ktctl -namespace=default
KT會自動在叢集中部署SSH/DNS代理容器,並構建本地到Kubernetes叢集的VPN網路並透過DNS代理實現叢集服務DNS域名解析,在執行KT之後,開發者的本地程式可以直接像執行在叢集中的服務一樣透過Service名字呼叫叢集中部署的其它應用:
而如果希望叢集中的其它Pod(比如圖中的PodD和PodE)能夠透過ServiceC訪問到本地執行的程式C‘,透過如下命令,指定需要替換的標的Deployment以及指定本地服務埠:
  1. # -swap-deployment指定需要替換的標的Deployment
  2. # -expose 指定本地服務執行的埠
  3. 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服務埠對映到本地:
  1. # 將對本地2222埠轉發到kt-porxy實體的22埠
  2. $ kubectl port-forward deployments/kt-proxy 2222:22
  3. Forwarding from 127.0.0.1:8080 -> 8080
  4. Forwarding from [::1]:8080 -> 8080
在執行埠轉發後,就可以直接透過本地的2222埠透過SSH協議進入到Kubernetes叢集的kt-proxy實體中。從而打通本地與叢集之間的SSH網路鏈路。
本地動態埠轉發與VPN
在打通SSH網路之後,我們就可以利用SSH通道實現本地到叢集的網路請求,其中最基本的方式就是使用SSH動態埠轉發的能力。
使用如下命令,透過本地2000執行的代理,可以將網路請求透過叢集中執行的kt-proxy容器進行轉發,從而實現本地到叢集網路請求的轉發:
  1. # ssh -D [本地網絡卡地址:]本地埠 name@ip -p對映到kt-proxy的22埠的本地埠
  2. ssh -D 2000 root@127.0.0.1 -p2222
在啟用SSH動態埠轉發後,透過設定http_proxy環境變數後,即可直接在命令列中訪問叢集網路:
  1. # export http_proxy=socks5://127.0.0.1:ssh動態埠轉發的代理埠
  2. export http_proxy=socks5://127.0.0.1:2000
不過原生SSH動態埠轉發也有一定的限制那就是無法直接使用UDP協議,這裡我們選擇了一個替代方案sshuttle,如下命令所示:
  1. # export http_proxy=socks5://127.0.0.1:ssh動態埠轉發的代理埠
  2. export http_proxy=socks5://127.0.0.1:2000
  3. sshuttle --dns --to-ns 172.16.1.36 -e 'ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' -r root@127.0.0.1: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埠:
  1. # ssh -R 8080:localhost:8080 root@127.0.0.1 -p2222
  2. ssh -R 8080:localhost:8080 root@127.0.0.1 -p2222
因此,在KT的實現過程之中,結合Kubernetes基於標簽的松耦合能力,我們只需要克隆原有應用實體的YAML描述,並將容器替換為kt-proxy即可。從而將對叢集中原有應用的請求透過SSH遠端埠轉發到本地。
綜上,透過利用Kubernetes原生能力以及適度的擴充套件,開發者可以快速在本地利用KT打破本地網路與Kubernetes網路之間的界限,大大提升使用Kubernetes進行聯調測試的效率。
小結

 

工具承載了對特定問題的解決方案,而工程技術實踐則是對其價值的放大。阿裡巴巴雲效平臺,致力於為開發者提供一站式的企業研發與協作服務,並將阿裡多年的軟體工程實踐以一種更加開發的形態反饋技術社群,歡迎更多的技術開發者入駐。
目前,Mac使用者可以下載並體驗KT工具:https://yq.aliyun.com/download/3393。

贊(1)

分享創造快樂