av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

如何對Pod容器進(jìn)行RemoteDebug

如何對Pod容器進(jìn)行Remote Debug

作者:LanceZhang 2022-04-26 05:55:13
云計算
云原生 先不談通過看log來debug的效率問題,在 VM 上這樣搞尚且可行,可當(dāng)我們把應(yīng)用容器化并讓K8s管理后,怎么辦呢?

大家好,我是二哥。

在一個面試場景中,就debug問題,一般會出現(xiàn)下面的對話:

二哥:你平時開發(fā)的時候是用什么方法debug ?

應(yīng)聘者:看日志。

二哥:萬一log level沒設(shè)對或者關(guān)鍵的地方?jīng)]有加log怎么辦呢?

應(yīng)聘者:那就改代碼,加log,重啟服務(wù),然后繼續(xù)看日志。

先不談通過看log來debug的效率問題,在 VM 上這樣搞尚且可行,可當(dāng)我們把應(yīng)用容器化并讓K8s管理后,怎么辦呢?

我們都知道在Pod里是沒法方便地通過執(zhí)行類似 systemctl和 monit等命令來重啟應(yīng)用的,那繼續(xù)用看日志的方式的話,就剩下一條路了:

  1. 改代碼,加log。
  2. commit到git。
  3. CI/CD。
  4. 如果log沒有加對,或者想看一下某一個函數(shù)調(diào)用的返回值,那從步驟1開始重頭再來。

um, 看上去挺累的樣子。CI/CD和K8s也被折騰得夠嗆。

二哥稍微有點(diǎn)強(qiáng)迫癥,不能忍受這么折磨人的debug方式。另外,相比人肉看Log,通過調(diào)試器的方式來debug更優(yōu)雅、更快捷,也更能激發(fā)RD的想象力。最重要的是,通過調(diào)試器debug會倒逼RD從代碼調(diào)用邏輯、和OS交互等多角度思考問題。比如會設(shè)斷點(diǎn)不難,難的是何時設(shè)斷點(diǎn),把斷點(diǎn)設(shè)在哪里最合適。

“道—法—術(shù)—器—勢”,是老子《道德經(jīng)》的精髓思想。本文講的其實是“術(shù)”和“器”,但二哥想說“道”更本質(zhì),也更重要,它是核心思想、理念、本質(zhì)規(guī)律。強(qiáng)烈建議好奇心重的同學(xué)多思考一下這些“術(shù)”背后的實現(xiàn)原理。

二哥通過一個示例給老鐵們演示一下,如何從本地機(jī)器遠(yuǎn)程調(diào)試Pod里面的應(yīng)用。應(yīng)用本身非常簡單,是用Node.js寫的一段http server。對于其它語言寫的應(yīng)用,你肯定能找到變通方法。

進(jìn)入debug模式

首先得把http server切換到調(diào)試模式。注意這里demo的方法僅適用于Node.js。

kubectl exec nodejs-8448d4cbc6-nbjwd -n lancehbzhang -- /bin/bash -c "kill -USR1 1"

一切順利的話,你可以從Pod的log里面看到如下所示的信息。這表示debugger偵聽在端口9229。

圖 1:將容器切換進(jìn)入debug模式

K8s port-forward

下面的問題是:如何才能把本地debugger發(fā)出的調(diào)試命令連進(jìn)來?

方法其實有不少。比如通過一個Load Balancer類型的service。不過這種方法比較費(fèi)錢,據(jù)我所知,騰訊云的Load Balancer價格不菲。

這里二哥介紹一個既免費(fèi)又通用的方法。用K8s自帶的port-forward功能,命令如下所示:

$ kubectl port-forward deploy/nodejs -n lancehbzhang 9229:9229

在一臺可以執(zhí)行kubectl命令的機(jī)器上執(zhí)行這行命令后,如果一切正常,你會看到下面的界面。

圖 2:使用K8s port-forward

恭喜你,這表示從此以后任何發(fā)往這臺機(jī)器 9229 端口的請求都將會 forward 到 pod nodejs 的 9229 端口,如你所猜,那正是 debugger 正在偵聽的端口。

到現(xiàn)在為止,下圖中的 ③ 和 ④ 你應(yīng)該都準(zhǔn)備好了。

圖 3:從本機(jī)debugger到遠(yuǎn)程debuggee全景圖

你是不是摩拳擦掌,擼起袖子準(zhǔn)備從本地機(jī)器連過來了?且慢,有一種場景我們還沒解決。

如果執(zhí)行 kubectl port-forward 的機(jī)器和我們的本地機(jī)器無法直連怎么辦?假如出于安全考慮,上圖中 ③ 和 ④ 是可以網(wǎng)絡(luò)直連的,但 ① 和 ③ 被防火墻隔開了,只留了一個22端口供 ① 通過 ssh 登錄到 ③ 。這種情況下,該如何從本機(jī)連接到 ④ 上的debugger呢?

這個時候就需要輪到步驟 ② 所示的 SSH Tunnel 登場了。通過這樣的方式, 本機(jī)VS code只需 attach 到 127.0.0.1:9229,諸如設(shè)置斷點(diǎn)、單步執(zhí)行、查看變量等調(diào)試命令都被封裝起來,塞進(jìn) SSH Tunnel 再送至 ③ 上,然后再通過 port-forwarding 轉(zhuǎn)至 ④ 上的debuggee。

注:SSH Tunnel的使用并非本文的重點(diǎn),大家可以自行谷歌找到使用方法。

演示

好了,準(zhǔn)備工作做完了。下面開始二哥的表演。

本地機(jī)器打開VS Code,在launch.json里面輸入如下所示的配置。其中參數(shù) port表示本機(jī)debugger需要連接的端口,localRoot表示本地的代碼路徑,而remoteRoot則表示 ④ 中應(yīng)用所在的路徑。二哥在build Docker image時,將應(yīng)用的WORKDIR設(shè)置為了/myapp,所以這里也得填成/myapp。其它參數(shù)各位自行谷歌。

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach-2-nodejs",
"port": 9229,
"request": "attach",
"skipFiles": ["/**"],
"type": "pwa-node",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/myapp",
"sourceMaps": true
}
]
}

在第17行設(shè)置斷點(diǎn),按下F5開始debugging。

圖 4:本機(jī)debugger

還記得前文我們已經(jīng)打開的 SSH Tunnel 界面嗎?這個時候,你會看到它會打印出一些諸如 "Successfully established connection 127.0.0.1:9229 -> 127.0.0.1:9229" 這樣的信息。當(dāng)然,具體信息內(nèi)容與你使用的工具相關(guān)。

圖 5:SSH Tunnel正在工作示意圖

沒有問題的話,網(wǎng)絡(luò)包應(yīng)該來到了圖3中位置 ③ 。我們來看看這個時候 K8s port-forward 會打印出什么來:

圖 6:K8s port-forward正在工作示意圖

非常不錯,看起來它收到了請求,并且也在勤奮地工作著。那最后我們來看看圖3中 ④ 中打印出來的令人激動的信息:"Debugger attached"。

圖 7:debuggee顯示已有debugger attach上來了

萬事俱備,只差最后一腳了:發(fā)個請求,看看能不能命中斷點(diǎn):

圖 8:發(fā)個請求,命中一下斷點(diǎn)

回頭看看圖4吧,多么讓人陶醉的界面,在那里你可以查看變量、?;厮?,還可以干很多很多其它騷操作。是的,這個時候才是發(fā)揮你想象力的時候。

其它需要做的工作

到目前為止,本文略過一些雖不是重點(diǎn),但有的時候又可能會影響調(diào)試體驗的細(xì)枝末節(jié),我列舉一二。

將Pod的replica設(shè)置為 1。不然你就得發(fā)了瘋地尋找debugger發(fā)出的調(diào)試命令發(fā)到哪里去了呢?

還記得K8s的livenessProbe和readinessProbe嗎?如果容器內(nèi)應(yīng)用因為被調(diào)試而長時間未響應(yīng)這兩個probe,那么Pod有可能會被K8s殺掉。這個時候,或許你費(fèi)勁千辛萬苦才等來的斷點(diǎn)命中瞬間化為烏有了。

網(wǎng)上有不少解決方法,比如通過 kubectl patch deploy/nodejs 安裝dummy的livenessProbe和readinessProbe。

這個dummy probe不需要真的去probe container是否活著,相反它永遠(yuǎn)返回 true。比如下面這種方法用 kubectl patch 命令修改了 deployment 的spec。

# 移除 livenessProbe
$ kubectl patch deploy/nodejs -n lancehbzhang --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
# 安裝 dummy livenessProbe
$ kubectl patch deploy/nodejs -n lancehbzhang -p '{"spec": {"template": {"spec": {"containers": [{"name": "nodejs", "livenessProbe": {"initialDelaySeconds": 5, "periodSeconds": 5, "exec": {"command": ["true"]}}}]}}}}'

總結(jié)

首先需要將容器內(nèi)的應(yīng)用切換到debug模式。具體如何操作與所使用的語言密切相關(guān)。

  • 通過K8s port-forward可以將debugger發(fā)出的調(diào)試命令轉(zhuǎn)發(fā)至被調(diào)試應(yīng)用(debuggee)。
  • 如果運(yùn)行于你本機(jī)的debugger無法和運(yùn)行著K8s port-forward的那臺機(jī)器直接通信,那么這個時候就需要把debugger的調(diào)試命令丟進(jìn)SSH Tunnel送至對端。
  • 一切準(zhǔn)備就緒后,本機(jī)debugger就可以attach到debuggee了。

分享標(biāo)題:如何對Pod容器進(jìn)行RemoteDebug
鏈接地址:http://uogjgqi.cn/article/dhjgijg.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流