在 K8s 集羣中調試微服務很困難。有時我們遇到在不真實的環境下難以復現的 bug。在本機用你最習慣的工具調試達到和在集羣中運行服務一樣的效果,這其實只需要運行幾個命令。 |
爲了達到目標效果,我主要用如下工具:
https://github.com/moshebe/gebug
這個開源工具讓調試容器化了的Go程序非常方便,它是通過開啓熱更新和debugger配置實現的。我就是這個工具的作者嘻嘻。
https://www.telepresence.io/
這是一個很厲害的 CNCF 項目,這個項目可以用來與集羣網絡做網絡隧道。
我認爲,熟悉一個工具最好的辦法就是去用它,接着就來配置demo環境。
我們使用一個小kubernetes集羣,跑一個hello-world deployment、暴露一個服務。
既然是要做demo,我就用minikube了。如果你已經有一個運行中的非生產環境集羣,那麼你就用你的集羣。注意不要在生產環境做測試。
kubectl create deployment hello-world --image=datawire/hello-world kubectl expose deployment hello-world --type=LoadBalancer --port=8000
當前kubernets集羣狀態
查看service external endpoint並跑些測試:
使用minikube提供的命令拉取外部地址。也可以通過kubectl get service hello world命令並查看 EXTERNAL_IP 字段內的信息。img
我們的hello-world部署很成功。我們來做一次把http返回做成json格式。
當然也可以編譯你的程序、打鏡像、push到倉庫、編輯deployment、等等等等,最後搞定。我們來用短平快的辦法做這事。
這是個簡單HTTP server:
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println("Got request 🎉") fmt.Fprintf(w, `{"hello":"world"}`) }) http.ListenAndServe(":8000", nil) } 這是Gebug配置: name: my-server output_binary: /app build_command: go build -gcflags="all=-N -l" -o /app run_command: /app runtime_image: golang:1.15.2 debugger_enabled: true debugger_port: 4321 expose_ports: - 8000:8000 networks: [] environment: []
注意,如果沒有安裝Gebug可以運行go get -u github.com/moshebe/gebug安裝。
Telepresence
這個強大的工具讓我們繞過了複雜難懂的網絡配置,可以直接把服務連接到集羣中。
安裝指南: https://www.telepresence.io/reference/install
下一步是暴露本地的服務、把流量連接到集羣,就可以替換掉已經存在的deployment了。
我們的deployment叫hello-world,暴露8000端口,命令如下:
telepresence --swap-deployment hello-world --expose 8000:8000 --method inject-tcp --run gebug start
上面這個命令做了幾件事:
開一個程序負責把命中的DNS和IP段的請求重定向到k8s集羣上
swap-deployment 這個選項是讓Telepresence用運行在Telepresence代理上的東西替換掉已經存在的hello-world pod。一旦我們退出,老pod也會被恢復。
run 選項告訴Telepresence用Gebug工具運行我們的服務,把這個服務和網絡代理綁定。
只要 http server 在 telepresence 中運行着,就可以從 k8s 集羣內部訪問這個服務。