溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

發(fā)布時(shí)間:2020-07-25 21:36:22 來源:網(wǎng)絡(luò) 閱讀:162 作者:阿里系統(tǒng)軟件技術(shù) 欄目:云計(jì)算

作者 | 莫源?阿里巴巴技術(shù)專家

一、需求來源

首先來看一下,整個(gè)需求的來源:當(dāng)把應(yīng)用遷移到 Kubernetes 之后,要如何去保障應(yīng)用的健康與穩(wěn)定呢?其實(shí)很簡(jiǎn)單,可以從兩個(gè)方面來進(jìn)行增強(qiáng):

  1. 首先是提高應(yīng)用的可觀測(cè)性;
  2. 第二是提高應(yīng)用的可恢復(fù)能力。

從可觀測(cè)性上來講,可以在三個(gè)方面來去做增強(qiáng):

  1. 首先是應(yīng)用的健康狀態(tài)上面,可以實(shí)時(shí)地進(jìn)行觀測(cè);
  2. 第二個(gè)是可以獲取應(yīng)用的資源使用情況;
  3. 第三個(gè)是可以拿到應(yīng)用的實(shí)時(shí)日志,進(jìn)行問題的診斷與分析。

當(dāng)出現(xiàn)了問題之后,首先要做的事情是要降低影響的范圍,進(jìn)行問題的調(diào)試與診斷。最后當(dāng)出現(xiàn)問題的時(shí)候,理想的狀況是:可以通過和 K8s 集成的自愈機(jī)制進(jìn)行完整的恢復(fù)。

二、Liveness 與 Readiness

本小節(jié)為大家介紹 Liveness probe 和 eadiness probe。

應(yīng)用健康狀態(tài)-初識(shí) Liveness 與 Readiness

Liveness probe 也叫就緒指針,用來判斷一個(gè) pod 是否處在就緒狀態(tài)。當(dāng)一個(gè) pod 處在就緒狀態(tài)的時(shí)候,它才能夠?qū)ν馓峁┫鄳?yīng)的服務(wù),也就是說接入層的流量才能打到相應(yīng)的 pod。當(dāng)這個(gè) pod 不處在就緒狀態(tài)的時(shí)候,接入層會(huì)把相應(yīng)的流量從這個(gè) pod 上面進(jìn)行摘除。

來看一下簡(jiǎn)單的一個(gè)例子:

如下圖其實(shí)就是一個(gè) Readiness 就緒的一個(gè)例子:

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?cdn.com/7972a7447a196a56fc78ede6a4fe04b0161e045c.png">

當(dāng)這個(gè) pod 指針判斷一直處在失敗狀態(tài)的時(shí)候,其實(shí)接入層的流量不會(huì)打到現(xiàn)在這個(gè) pod 上。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

當(dāng)這個(gè) pod 的狀態(tài)從 FAIL 的狀態(tài)轉(zhuǎn)換成 success 的狀態(tài)時(shí),它才能夠真實(shí)地承載這個(gè)流量。

Liveness 指針也是類似的,它是存活指針,用來判斷一個(gè) pod 是否處在存活狀態(tài)。當(dāng)一個(gè) pod 處在不存活狀態(tài)的時(shí)候,會(huì)出現(xiàn)什么事情呢?

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

這個(gè)時(shí)候會(huì)由上層的判斷機(jī)制來判斷這個(gè) pod 是否需要被重新拉起。那如果上層配置的重啟策略是 restart always 的話,那么此時(shí)這個(gè) pod 會(huì)直接被重新拉起。

應(yīng)用健康狀態(tài)-使用方式

接下來看一下 Liveness 指針和 Readiness 指針的具體的用法。

探測(cè)方式

Liveness 指針和 Readiness 指針支持三種不同的探測(cè)方式:

  1. 第一種是 httpGet。它是通過發(fā)送 http Get 請(qǐng)求來進(jìn)行判斷的,當(dāng)返回碼是 200-399 之間的狀態(tài)碼時(shí),標(biāo)識(shí)這個(gè)應(yīng)用是健康的;
  2. 第二種探測(cè)方式是 Exec。它是通過執(zhí)行容器中的一個(gè)命令來判斷當(dāng)前的服務(wù)是否是正常的,當(dāng)命令行的返回結(jié)果是 0,則標(biāo)識(shí)容器是健康的;
  3. 第三種探測(cè)方式是 tcpSocket 。它是通過探測(cè)容器的 IP 和 Port 進(jìn)行 TCP 健康檢查,如果這個(gè) TCP 的鏈接能夠正常被建立,那么標(biāo)識(shí)當(dāng)前這個(gè)容器是健康的。
探測(cè)結(jié)果

從探測(cè)結(jié)果來講主要分為三種:

  • 第一種是 success,當(dāng)狀態(tài)是 success 的時(shí)候,表示 container 通過了健康檢查,也就是 Liveness probe 或 Readiness probe 是正常的一個(gè)狀態(tài);
  • 第二種是 Failure,F(xiàn)ailure 表示的是這個(gè) container 沒有通過健康檢查,如果沒有通過健康檢查的話,那么此時(shí)就會(huì)進(jìn)行相應(yīng)的一個(gè)處理,那在 Readiness 處理的一個(gè)方式就是通過 service。service 層將沒有通過 Readiness 的 pod 進(jìn)行摘除,而 Liveness 就是將這個(gè) pod 進(jìn)行重新拉起,或者是刪除。
  • 第三種狀態(tài)是 Unknown,Unknown 是表示說當(dāng)前的執(zhí)行的機(jī)制沒有進(jìn)行完整的一個(gè)執(zhí)行,可能是因?yàn)轭愃葡癯瑫r(shí)或者像一些腳本沒有及時(shí)返回,那么此時(shí) Readiness-probe 或 Liveness-probe 會(huì)不做任何的一個(gè)操作,會(huì)等待下一次的機(jī)制來進(jìn)行檢驗(yàn)。

那在 kubelet 里面有一個(gè)叫 ProbeManager 的組件,這個(gè)組件里面會(huì)包含 Liveness-probe 或 Readiness-probe,這兩個(gè) probe 會(huì)將相應(yīng)的 Liveness 診斷和 Readiness 診斷作用在 pod 之上,來實(shí)現(xiàn)一個(gè)具體的判斷。

應(yīng)用健康狀態(tài)-Pod Probe Spec

下面介紹這三種方式不同的檢測(cè)方式的一個(gè) yaml 文件的使用。

首先先看一下 exec,exec 的使用其實(shí)非常簡(jiǎn)單。如下圖所示,大家可以看到這是一個(gè) Liveness probe,它里面配置了一個(gè) exec 的一個(gè)診斷。接下來,它又配置了一個(gè) command 的字段,這個(gè) command 字段里面通過 cat 一個(gè)具體的文件來判斷當(dāng)前 Liveness probe 的狀態(tài),當(dāng)這個(gè)文件里面返回的結(jié)果是 0 時(shí),或者說這個(gè)命令返回是 0 時(shí),它會(huì)認(rèn)為此時(shí)這個(gè) pod 是處在健康的一個(gè)狀態(tài)。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

那再來看一下這個(gè) httpGet,httpGet 里面有一個(gè)字段是路徑,第二個(gè)字段是 port,第三個(gè)是 headers。這個(gè)地方有時(shí)需要通過類似像 header 頭的一個(gè)機(jī)制做 health 的一個(gè)判斷時(shí),需要配置這個(gè) header,通常情況下,可能只需要通過 health 和 port 的方式就可以了。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

第三種是 tcpSocket,tcpSocket 的使用方式其實(shí)也比較簡(jiǎn)單,你只需要設(shè)置一個(gè)檢測(cè)的端口,像這個(gè)例子里面使用的是 8080 端口,當(dāng)這個(gè) 8080 端口 tcp connect 審核正常被建立的時(shí)候,那 tecSocket,Probe 會(huì)認(rèn)為是健康的一個(gè)狀態(tài)。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

此外還有如下的五個(gè)參數(shù),是 Global 的參數(shù)。

  • 第一個(gè)參數(shù)叫 initialDelaySeconds,它表示的是說這個(gè) pod 啟動(dòng)延遲多久進(jìn)行一次檢查,比如說現(xiàn)在有一個(gè) Java 的應(yīng)用,它啟動(dòng)的時(shí)間可能會(huì)比較長,因?yàn)樯婕暗?jvm 的啟動(dòng),包括 Java 自身 jar 的加載。所以前期,可能有一段時(shí)間是沒有辦法被檢測(cè)的,而這個(gè)時(shí)間又是可預(yù)期的,那這時(shí)可能要設(shè)置一下 initialDelaySeconds;

?

  • 第二個(gè)是 periodSeconds,它表示的是檢測(cè)的時(shí)間間隔,正常默認(rèn)的這個(gè)值是 10 秒;

?

  • 第三個(gè)字段是 timeoutSeconds,它表示的是檢測(cè)的超時(shí)時(shí)間,當(dāng)超時(shí)時(shí)間之內(nèi)沒有檢測(cè)成功,那它會(huì)認(rèn)為是失敗的一個(gè)狀態(tài);

?

  • 第四個(gè)是 successThreshold,它表示的是:當(dāng)這個(gè) pod 從探測(cè)失敗到再一次判斷探測(cè)成功,所需要的閾值次數(shù),默認(rèn)情況下是 1 次,表示原本是失敗的,那接下來探測(cè)這一次成功了,就會(huì)認(rèn)為這個(gè) pod 是處在一個(gè)探針狀態(tài)正常的一個(gè)狀態(tài);

?

  • 最后一個(gè)參數(shù)是 failureThreshold,它表示的是探測(cè)失敗的重試次數(shù),默認(rèn)值是 3,表示的是當(dāng)從一個(gè)健康的狀態(tài)連續(xù)探測(cè) 3 次失敗,那此時(shí)會(huì)判斷當(dāng)前這個(gè)pod的狀態(tài)處在一個(gè)失敗的狀態(tài)。

應(yīng)用健康狀態(tài)-Liveness 與 Readiness 總結(jié)

接下來對(duì) Liveness 指針和 Readiness 指針進(jìn)行一個(gè)簡(jiǎn)單的總結(jié)。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

介紹

Liveness 指針是存活指針,它用來判斷容器是否存活、判斷 pod 是否 running。如果 Liveness 指針判斷容器不健康,此時(shí)會(huì)通過 kubelet 殺掉相應(yīng)的 pod,并根據(jù)重啟策略來判斷是否重啟這個(gè)容器。如果默認(rèn)不配置 Liveness 指針,則默認(rèn)情況下認(rèn)為它這個(gè)探測(cè)默認(rèn)返回是成功的。

Readiness 指針用來判斷這個(gè)容器是否啟動(dòng)完成,即 pod 的 condition 是否 ready。如果探測(cè)的一個(gè)結(jié)果是不成功,那么此時(shí)它會(huì)從 pod 上 Endpoint 上移除,也就是說從接入層上面會(huì)把前一個(gè) pod 進(jìn)行摘除,直到下一次判斷成功,這個(gè) pod 才會(huì)再次掛到相應(yīng)的 endpoint 之上。

檢測(cè)失敗

對(duì)于檢測(cè)失敗上面來講 Liveness 指針是直接殺掉這個(gè) pod,而 Readiness 指針是切掉 endpoint 到這個(gè) pod 之間的關(guān)聯(lián)關(guān)系,也就是說它把這個(gè)流量從這個(gè) pod 上面進(jìn)行切掉。

適用場(chǎng)景

Liveness 指針適用場(chǎng)景是支持那些可以重新拉起的應(yīng)用,而 Readiness 指針主要應(yīng)對(duì)的是啟動(dòng)之后無法立即對(duì)外提供服務(wù)的這些應(yīng)用。

注意事項(xiàng)

在使用 Liveness 指針和 Readiness 指針的時(shí)候有一些注意事項(xiàng)。因?yàn)椴徽撌?Liveness 指針還是 Readiness 指針都需要配置合適的探測(cè)方式,以免被誤操作。

  • 第一個(gè)是調(diào)大超時(shí)的閾值,因?yàn)樵谌萜骼锩鎴?zhí)行一個(gè) shell 腳本,它的執(zhí)行時(shí)長是非常長的,平時(shí)在一臺(tái) ecs 或者在一臺(tái) vm 上執(zhí)行,可能 3 秒鐘返回的一個(gè)腳本在容器里面需要 30 秒鐘。所以這個(gè)時(shí)間是需要在容器里面事先進(jìn)行一個(gè)判斷的,那如果可以調(diào)大超時(shí)閾值的方式,來防止由于容器壓力比較大的時(shí)候出現(xiàn)偶發(fā)的超時(shí);

  • 第二個(gè)是調(diào)整判斷的一個(gè)次數(shù),3 次的默認(rèn)值其實(shí)在比較短周期的判斷周期之下,不一定是最佳實(shí)踐,適當(dāng)調(diào)整一下判斷的次數(shù)也是一個(gè)比較好的方式;

  • 第三個(gè)是 exec,如果是使用 shell 腳本的這個(gè)判斷,調(diào)用時(shí)間會(huì)比較長,比較建議大家可以使用類似像一些編譯性的腳本 Golang 或者一些 C 語言、C++ 編譯出來的這個(gè)二進(jìn)制的 binary 進(jìn)行判斷,那這種通常會(huì)比 shell 腳本的執(zhí)行效率高 30% 到 50%;

  • 第四個(gè)是如果使用 tcpSocket 方式進(jìn)行判斷的時(shí)候,如果遇到了 TLS 的服務(wù),那可能會(huì)造成后邊 TLS 里面有很多這種未健全的 tcp connection,那這個(gè)時(shí)候需要自己對(duì)業(yè)務(wù)場(chǎng)景上來判斷,這種的鏈接是否會(huì)對(duì)業(yè)務(wù)造成影響。

?

三、問題診斷

接下來給大家講解一下在 K8s 中常見的問題診斷。

應(yīng)用故障排查-了解狀態(tài)機(jī)制

首先要了解一下 K8s 中的一個(gè)設(shè)計(jì)理念,就是這個(gè)狀態(tài)機(jī)制。因?yàn)?K8s 是整個(gè)的一個(gè)設(shè)計(jì)是面向狀態(tài)機(jī)的,它里面通過 yaml 的方式來定義的是一個(gè)期望到達(dá)的一個(gè)狀態(tài),而真正這個(gè) yaml 在執(zhí)行過程中會(huì)由各種各樣的 controller來負(fù)責(zé)整體的狀態(tài)之間的一個(gè)轉(zhuǎn)換。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?
從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

比如說上面的圖,實(shí)際上是一個(gè) Pod 的一個(gè)生命周期。剛開始它處在一個(gè) pending 的狀態(tài),那接下來可能會(huì)轉(zhuǎn)換到類似像 running,也可能轉(zhuǎn)換到 Unknown,甚至可以轉(zhuǎn)換到 failed。然后,當(dāng) running 執(zhí)行了一段時(shí)間之后,它可以轉(zhuǎn)換到類似像 successded 或者是 failed,然后當(dāng)出現(xiàn)在 unknown 這個(gè)狀態(tài)時(shí),可能由于一些狀態(tài)的恢復(fù),它會(huì)重新恢復(fù)到 running 或者 successded 或者是 failed 。

其實(shí) K8s 整體的一個(gè)狀態(tài)就是基于這種類似像狀態(tài)機(jī)的一個(gè)機(jī)制進(jìn)行轉(zhuǎn)換的,而不同狀態(tài)之間的轉(zhuǎn)化都會(huì)在相應(yīng)的 K8s對(duì)象上面留下來類似像 Status 或者像 Conditions 的一些字段來進(jìn)行表示。

像下面這張圖其實(shí)表示的就是說在一個(gè) Pod 上面一些狀態(tài)位的一些展現(xiàn)。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

比如說在 Pod 上面有一個(gè)字段叫 Status,這個(gè) Status 表示的是 Pod 的一個(gè)聚合狀態(tài),在這個(gè)里面,這個(gè)聚合狀態(tài)處在一個(gè) pending 狀態(tài)。

然后再往下看,因?yàn)橐粋€(gè) pod 里面有多個(gè) container,每個(gè) container 上面又會(huì)有一個(gè)字段叫 State,然后 State 的狀態(tài)表示當(dāng)前這個(gè) container 的一個(gè)聚合狀態(tài)。那在這個(gè)例子里面,這個(gè)聚合狀態(tài)處在的是 waiting 的狀態(tài),那具體的原因是因?yàn)槭裁茨??是因?yàn)樗溺R像沒有拉下來,所以處在 waiting 的狀態(tài),是在等待這個(gè)鏡像拉取。然后這個(gè) ready 的部分呢,目前是 false,因?yàn)樗@個(gè)進(jìn)行目前沒有拉取下來,所以這個(gè) pod 不能夠正常對(duì)外服務(wù),所以此時(shí) ready 的狀態(tài)是未知的,定義為 false。如果上層的 endpoint 發(fā)現(xiàn)底層這個(gè) ready 不是 true 的話,那么此時(shí)這個(gè)服務(wù)是沒有辦法對(duì)外服務(wù)的。

再往下是 condition,condition 這個(gè)機(jī)制表示是說:在 K8s 里面有很多這種比較小的這個(gè)狀態(tài),而這個(gè)狀態(tài)之間的聚合會(huì)變成上層的這個(gè) Status。那在這個(gè)例子里面有幾個(gè)狀態(tài),第一個(gè)是 Initialized,表示是不是已經(jīng)初始化完成?那在這個(gè)例子里面已經(jīng)是初始化完成的,那它走的是第二個(gè)階段,是在這個(gè) ready 的狀態(tài)。因?yàn)樯厦鎺讉€(gè) container 沒有拉取下來相應(yīng)的鏡像,所以 ready 的狀態(tài)是 false。

然后再往下可以看到這個(gè) container 是否 ready,這里可以看到是 false,而這個(gè)狀態(tài)是 PodScheduled,表示說當(dāng)前這個(gè) pod 是否是處在一個(gè)已經(jīng)被調(diào)度的狀態(tài),它已經(jīng) bound 在現(xiàn)在這個(gè) node 之上了,所以這個(gè)狀態(tài)也是 true。

那可以通過相應(yīng)的 condition 是 true 還是 false 來判斷整體上方的這個(gè)狀態(tài)是否是正常的一個(gè)狀態(tài)。而在 K8s 里面不同的狀態(tài)之間的這個(gè)轉(zhuǎn)換都會(huì)發(fā)生相應(yīng)的事件,而事件分為兩種: 一種叫做 normal 的事件,一種是 warning 事件。大家可以看見在這第一條的事件是有個(gè) normal 事件,然后它相應(yīng)的 reason 是 scheduler,表示說這個(gè) pod 已經(jīng)被默認(rèn)的調(diào)度器調(diào)度到相應(yīng)的一個(gè)節(jié)點(diǎn)之上,然后這個(gè)節(jié)點(diǎn)是 cn-beijing192.168.3.167 這個(gè)節(jié)點(diǎn)之上。

再接下來,又是一個(gè) normal 的事件,表示說當(dāng)前的這個(gè)鏡像在 pull 相應(yīng)的這個(gè) image。然后再往下是一個(gè) warning 事件,這個(gè) warning 事件表示說 pull 這個(gè)鏡像失敗了。

以此類推,這個(gè)地方表示的一個(gè)狀態(tài)就是說在 K8s 里面這個(gè)狀態(tài)機(jī)制之間這個(gè)狀態(tài)轉(zhuǎn)換會(huì)產(chǎn)生相應(yīng)的事件,而這個(gè)事件又通過類似像 normal 或者是 warning 的方式進(jìn)行暴露。開發(fā)者可以通過類似像通過這個(gè)事件的機(jī)制,可以通過上層 condition Status 相應(yīng)的一系列的這個(gè)字段來判斷當(dāng)前這個(gè)應(yīng)用的具體的狀態(tài)以及進(jìn)行一系列的診斷。

應(yīng)用故障排查-常見應(yīng)用異常

本小節(jié)介紹一下常見應(yīng)用的一些異常。首先是 pod 上面,pod 上面可能會(huì)停留幾個(gè)常見的狀態(tài)。

Pod 停留在 Pending

第一個(gè)就是 pending 狀態(tài),pending 表示調(diào)度器沒有進(jìn)行介入。此時(shí)可以通過 kubectl describe pod 來查看相應(yīng)的事件,如果由于資源或者說端口占用,或者是由于 node selector 造成 pod 無法調(diào)度的時(shí)候,可以在相應(yīng)的事件里面看到相應(yīng)的結(jié)果,這個(gè)結(jié)果里面會(huì)表示說有多少個(gè)不滿足的 node,有多少是因?yàn)?CPU 不滿足,有多少是由于 node 不滿足,有多少是由于?tag?打標(biāo)造成的不滿足。

Pod 停留在 waiting

那第二個(gè)狀態(tài)就是 pod 可能會(huì)停留在 waiting 的狀態(tài),pod 的 states 處在 waiting 的時(shí)候,通常表示說這個(gè) pod 的鏡像沒有正常拉取,原因可能是由于這個(gè)鏡像是私有鏡像,但是沒有配置 Pod secret;那第二種是說可能由于這個(gè)鏡像地址是不存在的,造成這個(gè)鏡像拉取不下來;還有一個(gè)是說這個(gè)鏡像可能是一個(gè)公網(wǎng)的鏡像,造成鏡像的拉取失敗。

Pod 不斷被拉取并且可以看到 crashing

第三種是 pod 不斷被拉起,而且可以看到類似像 backoff 。這個(gè)通常表示說 pod 已經(jīng)被調(diào)度完成了,但是啟動(dòng)失敗,那這個(gè)時(shí)候通常要關(guān)注的應(yīng)該是這個(gè)應(yīng)用自身的一個(gè)狀態(tài),并不是說配置是否正確、權(quán)限是否正確,此時(shí)需要查看的應(yīng)該是 pod 的具體日志。

Pod 處在 Runing 但是沒有正常工作

第四種 pod 處在 running 狀態(tài),但是沒有正常對(duì)外服務(wù)。那此時(shí)比較常見的一個(gè)點(diǎn)就可能是由于一些非常細(xì)碎的配置,類似像有一些字段可能拼寫錯(cuò)誤,造成了 yaml 下發(fā)下去了,但是有一段沒有正常地生效,從而使得這個(gè) pod 處在 running 的狀態(tài)沒有對(duì)外服務(wù),那此時(shí)可以通過 apply-validate-f pod.yaml 的方式來進(jìn)行判斷當(dāng)前 yaml 是否是正常的,如果 yaml 沒有問題,那么接下來可能要診斷配置的端口是否是正常的,以及 Liveness 或 Readiness 是否已經(jīng)配置正確。

Service 無法正常的工作

最后一種就是 service 無法正常工作的時(shí)候,該怎么去判斷呢?那比較常見的 service 出現(xiàn)問題的時(shí)候,是自己的使用上面出現(xiàn)了問題。因?yàn)?service 和底層的 pod 之間的關(guān)聯(lián)關(guān)系是通過 selector 的方式來匹配的,也就是說 pod 上面配置了一些 label,然后 service 通過 match label 的方式和這個(gè) pod 進(jìn)行相互關(guān)聯(lián)。如果這個(gè) label 配置的有問題,可能會(huì)造成這個(gè) service 無法找到后面的 endpoint,從而造成相應(yīng)的 service 沒有辦法對(duì)外提供服務(wù),那如果 service 出現(xiàn)異常的時(shí)候,第一個(gè)要看的是這個(gè) service 后面是不是有一個(gè)真正的 endpoint,其次來看這個(gè) endpoint 是否可以對(duì)外提供正常的服務(wù)。

四、應(yīng)用遠(yuǎn)程調(diào)試

本節(jié)講解的是在 K8s 里面如何進(jìn)行應(yīng)用的遠(yuǎn)程調(diào)試,遠(yuǎn)程調(diào)試主要分為 pod 的遠(yuǎn)程調(diào)試以及 service 的遠(yuǎn)程調(diào)試。還有就是針對(duì)一些性能優(yōu)化的遠(yuǎn)程調(diào)試。

應(yīng)用遠(yuǎn)程調(diào)試 - Pod 遠(yuǎn)程調(diào)試

首先把一個(gè)應(yīng)用部署到集群里面的時(shí)候,發(fā)現(xiàn)問題的時(shí)候,需要進(jìn)行快速驗(yàn)證,或者說修改的時(shí)候,可能需要類似像登陸進(jìn)這個(gè)容器來進(jìn)行一些診斷。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

比如說可以通過 exec 的方式進(jìn)入一個(gè) pod。像這條命令里面,通過 kubectl exec-it pod-name 后面再填寫一個(gè)相應(yīng)的命令,比如說 /bin/bash,表示希望到這個(gè) pod 里面進(jìn)入一個(gè)交互式的一個(gè) bash。然后在 bash 里面可以做一些相應(yīng)的命令,比如說修改一些配置,通過 supervisor 去重新拉起這個(gè)應(yīng)用,都是可以的。

那如果指定這一個(gè) pod 里面可能包含著多個(gè) container,這個(gè)時(shí)候該怎么辦呢?怎么通過 pod 來指定 container 呢?其實(shí)這個(gè)時(shí)候有一個(gè)參數(shù)叫做 -c,如上圖下方的命令所示。-c 后面是一個(gè) container-name,可以通過 pod 在指定 -c 到這個(gè) container-name,具體指定要進(jìn)入哪個(gè) container,后面再跟上相應(yīng)的具體的命令,通過這種方式來實(shí)現(xiàn)一個(gè)多容器的命令的一個(gè)進(jìn)入,從而實(shí)現(xiàn)多容器的一個(gè)遠(yuǎn)程調(diào)試。

應(yīng)用遠(yuǎn)程調(diào)試 - Servic 遠(yuǎn)程調(diào)試

那么 service 的遠(yuǎn)程調(diào)試該怎么做呢?service 的遠(yuǎn)程調(diào)試其實(shí)分為兩個(gè)部分:

  • 第一個(gè)部分是說我想將一個(gè)服務(wù)暴露到遠(yuǎn)程的一個(gè)集群之內(nèi),讓遠(yuǎn)程集群內(nèi)的一些應(yīng)用來去調(diào)用本地的一個(gè)服務(wù),這是一條反向的一個(gè)鏈路;
  • 還有一種方式是我想讓這個(gè)本地服務(wù)能夠去調(diào)遠(yuǎn)程的服務(wù),那么這是一條正向的鏈路。

在反向列入上面有這樣一個(gè)開源組件,叫做 Telepresence,它可以將本地的應(yīng)用代理到遠(yuǎn)程集群中的一個(gè) service 上面,使用它的方式非常簡(jiǎn)單。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

首先先將 Telepresence 的一個(gè) Proxy 應(yīng)用部署到遠(yuǎn)程的 K8s 集群里面。然后將遠(yuǎn)程單一個(gè) deployment swap 到本地的一個(gè) application,使用的命令就是 Telepresence-swap-deployment 然后以及遠(yuǎn)程的 DEPLOYMENT_NAME。通過這種方式就可以將本地一個(gè) application 代理到遠(yuǎn)程的 service 之上、可以將應(yīng)用在遠(yuǎn)程集群里面進(jìn)行本地調(diào)試,這個(gè)有興趣的同學(xué)可以到 GitHub 上面來看一下這個(gè)插件的使用的方式。

第二個(gè)是如果本地應(yīng)用需要調(diào)用遠(yuǎn)程集群的服務(wù)時(shí)候,可以通過 port-forward 的方式將遠(yuǎn)程的應(yīng)用調(diào)用到本地的端口之上。比如說現(xiàn)在遠(yuǎn)程的里面有一個(gè) API server,這個(gè) API server 提供了一些端口,本地在調(diào)試 Code 時(shí)候,想要直接調(diào)用這個(gè) API server,那么這時(shí),比較簡(jiǎn)單的一個(gè)方式就是通過 port-forward 的方式。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

它的使用方式是 kubectl port-forward,然后 service 加上遠(yuǎn)程的 service name,再加上相應(yīng)的 namespace,后面還可以加上一些額外的參數(shù),比如說端口的一個(gè)映射,通過這種機(jī)制就可以把遠(yuǎn)程的一個(gè)應(yīng)用代理到本地的端口之上,此時(shí)通過訪問本地端口就可以訪問遠(yuǎn)程的服務(wù)。

開源的調(diào)試工具 - kubectl-debug

最后再給大家介紹一個(gè)開源的調(diào)試工具,它也是 kubectl 的一個(gè)插件,叫 kubectl-debug。我們知道在 K8s 里面,底層的容器 runtime 比較常見的就是類似像 docker 或者是 containerd,不論是 docker 還是 containerd,它們使用的一個(gè)機(jī)制都是基于 Linux namespace 的一個(gè)方式進(jìn)行虛擬化和隔離的。

通常情況下 ,并不會(huì)在鏡像里面帶特別多的調(diào)試工具,類似像 netstat telnet 等等這些 ,因?yàn)檫@個(gè)會(huì)造成應(yīng)用整體非常冗余。那么如果想要調(diào)試的時(shí)候該怎么做呢?其實(shí)這個(gè)時(shí)候就可以依賴類似于像 kubectl-debug 這樣一個(gè)工具。<br />?<br /> kubectl-debug 這個(gè)工具是依賴于 Linux namespace 的方式來去做的,它可以 datash 一個(gè) Linux namespace 到一個(gè)額外的 container,然后在這個(gè) container 里面執(zhí)行任何的 debug 動(dòng)作,其實(shí)和直接去 debug 這個(gè) Linux namespace 是一致的。這里有一個(gè)簡(jiǎn)單的操作,給大家來介紹一下:

這個(gè)地方其實(shí)已經(jīng)安裝好了 kubectl-debug,它是 kubectl 的一個(gè)插件。所以這個(gè)時(shí)候,你可以直接通過 kubectl-debug 這條命令來去診斷遠(yuǎn)程的一個(gè) pod。像這個(gè)例子里面,當(dāng)執(zhí)行 debug 的時(shí)候,實(shí)際上它首先會(huì)先拉取一些鏡像,這個(gè)鏡像里面實(shí)際上會(huì)默認(rèn)帶一些診斷的工具。當(dāng)這個(gè)鏡像啟用的時(shí)候,它會(huì)把這個(gè) debug container 進(jìn)行啟動(dòng)。與此同時(shí)會(huì)把這個(gè) container 和相應(yīng)的你要診斷的這個(gè) container 的 namespace 進(jìn)行掛靠,也就說此時(shí)這個(gè) container 和你是同 namespace 的,類似像網(wǎng)絡(luò)站,或者是類似像內(nèi)核的一些參數(shù),其實(shí)都可以在這個(gè) debug container 里面實(shí)時(shí)地進(jìn)行查看。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

像這個(gè)例子里面,去查看類似像 hostname、進(jìn)程、netstat 等等,這些其實(shí)都是和這個(gè)需要 debug 的 pod 是在同一個(gè)環(huán)境里面的,所以你之前這三條命令可以看到里面相關(guān)的信息。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

如果此時(shí)進(jìn)行 logout 的話,相當(dāng)于會(huì)把相應(yīng)的這個(gè) debug pod 殺掉,然后進(jìn)行退出,此時(shí)對(duì)應(yīng)用實(shí)際上是沒有任何的影響的。那么通過這種方式可以不介入到容器里面,就可以實(shí)現(xiàn)相應(yīng)的一個(gè)診斷。

從零開始入門 K8s | 可觀測(cè)性:你的應(yīng)用健康嗎?

此外它還支持額外的一些機(jī)制,比如說我給設(shè)定一些 image,然后類似像這里面安裝了的是 htop,然后開發(fā)者可以通過這個(gè)機(jī)制來定義自己需要的這個(gè)命令行的工具,并且通過這種 image 的方式設(shè)置進(jìn)來。那么這個(gè)時(shí)候就可以通過這種機(jī)制來調(diào)試遠(yuǎn)程的一個(gè) pod。

本節(jié)總結(jié)

  • 關(guān)于 Liveness 和 Readiness 的指針。Liveness probe 就是?;钪羔槪怯脕砜?pod 是否存活的,而 Readiness probe 是就緒指針,它是判斷這個(gè) pod 是否就緒的,如果就緒了,就可以對(duì)外提供服務(wù)。這個(gè)就是 Liveness 和 Readiness 需要記住的部分;

  • 應(yīng)用診斷的三個(gè)步驟:首先 describe 相應(yīng)的一個(gè)狀態(tài);然后提供狀態(tài)來排查具體的一個(gè)診斷方向;最后來查看相應(yīng)對(duì)象的一個(gè) event 獲取更詳細(xì)的一個(gè)信息;

  • 提供 pod 一個(gè)日志來定位應(yīng)用的自身的一個(gè)狀態(tài);

  • 遠(yuǎn)程調(diào)試的一個(gè)策略,如果想把本地的應(yīng)用代理到遠(yuǎn)程集群,此時(shí)可以通過 Telepresence 這樣的工具來實(shí)現(xiàn),如果想把遠(yuǎn)程的應(yīng)用代理到本地,然后在本地進(jìn)行調(diào)用或者是調(diào)試,可以用類似像 port-forward 這種機(jī)制來實(shí)現(xiàn)。

“ 阿里巴巴云原生微信公眾號(hào)(ID:Alicloudnative)關(guān)注微服務(wù)、Serverless、容器、Service Mesh等技術(shù)領(lǐng)域、聚焦云原生流行技術(shù)趨勢(shì)、云原生大規(guī)模的落地實(shí)踐,做最懂云原生開發(fā)者的技術(shù)公眾號(hào)?!?/strong>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI