中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

發布時間:2020-07-25 21:36:22 來源:網絡 閱讀:162 作者:阿里系統軟件技術 欄目:云計算

作者 | 莫源?阿里巴巴技術專家

一、需求來源

首先來看一下,整個需求的來源:當把應用遷移到 Kubernetes 之后,要如何去保障應用的健康與穩定呢?其實很簡單,可以從兩個方面來進行增強:

  1. 首先是提高應用的可觀測性;
  2. 第二是提高應用的可恢復能力。

從可觀測性上來講,可以在三個方面來去做增強:

  1. 首先是應用的健康狀態上面,可以實時地進行觀測;
  2. 第二個是可以獲取應用的資源使用情況;
  3. 第三個是可以拿到應用的實時日志,進行問題的診斷與分析。

當出現了問題之后,首先要做的事情是要降低影響的范圍,進行問題的調試與診斷。最后當出現問題的時候,理想的狀況是:可以通過和 K8s 集成的自愈機制進行完整的恢復。

二、Liveness 與 Readiness

本小節為大家介紹 Liveness probe 和 eadiness probe。

應用健康狀態-初識 Liveness 與 Readiness

Liveness probe 也叫就緒指針,用來判斷一個 pod 是否處在就緒狀態。當一個 pod 處在就緒狀態的時候,它才能夠對外提供相應的服務,也就是說接入層的流量才能打到相應的 pod。當這個 pod 不處在就緒狀態的時候,接入層會把相應的流量從這個 pod 上面進行摘除。

來看一下簡單的一個例子:

如下圖其實就是一個 Readiness 就緒的一個例子:

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

當這個 pod 指針判斷一直處在失敗狀態的時候,其實接入層的流量不會打到現在這個 pod 上。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

當這個 pod 的狀態從 FAIL 的狀態轉換成 success 的狀態時,它才能夠真實地承載這個流量。

Liveness 指針也是類似的,它是存活指針,用來判斷一個 pod 是否處在存活狀態。當一個 pod 處在不存活狀態的時候,會出現什么事情呢?

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

應用健康狀態-使用方式

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

探測方式

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

  1. 第一種是 httpGet。它是通過發送 http Get 請求來進行判斷的,當返回碼是 200-399 之間的狀態碼時,標識這個應用是健康的;
  2. 第二種探測方式是 Exec。它是通過執行容器中的一個命令來判斷當前的服務是否是正常的,當命令行的返回結果是 0,則標識容器是健康的;
  3. 第三種探測方式是 tcpSocket 。它是通過探測容器的 IP 和 Port 進行 TCP 健康檢查,如果這個 TCP 的鏈接能夠正常被建立,那么標識當前這個容器是健康的。
探測結果

從探測結果來講主要分為三種:

  • 第一種是 success,當狀態是 success 的時候,表示 container 通過了健康檢查,也就是 Liveness probe 或 Readiness probe 是正常的一個狀態;
  • 第二種是 Failure,Failure 表示的是這個 container 沒有通過健康檢查,如果沒有通過健康檢查的話,那么此時就會進行相應的一個處理,那在 Readiness 處理的一個方式就是通過 service。service 層將沒有通過 Readiness 的 pod 進行摘除,而 Liveness 就是將這個 pod 進行重新拉起,或者是刪除。
  • 第三種狀態是 Unknown,Unknown 是表示說當前的執行的機制沒有進行完整的一個執行,可能是因為類似像超時或者像一些腳本沒有及時返回,那么此時 Readiness-probe 或 Liveness-probe 會不做任何的一個操作,會等待下一次的機制來進行檢驗。

那在 kubelet 里面有一個叫 ProbeManager 的組件,這個組件里面會包含 Liveness-probe 或 Readiness-probe,這兩個 probe 會將相應的 Liveness 診斷和 Readiness 診斷作用在 pod 之上,來實現一個具體的判斷。

應用健康狀態-Pod Probe Spec

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

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

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

第三種是 tcpSocket,tcpSocket 的使用方式其實也比較簡單,你只需要設置一個檢測的端口,像這個例子里面使用的是 8080 端口,當這個 8080 端口 tcp connect 審核正常被建立的時候,那 tecSocket,Probe 會認為是健康的一個狀態。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

此外還有如下的五個參數,是 Global 的參數。

  • 第一個參數叫 initialDelaySeconds,它表示的是說這個 pod 啟動延遲多久進行一次檢查,比如說現在有一個 Java 的應用,它啟動的時間可能會比較長,因為涉及到 jvm 的啟動,包括 Java 自身 jar 的加載。所以前期,可能有一段時間是沒有辦法被檢測的,而這個時間又是可預期的,那這時可能要設置一下 initialDelaySeconds;

?

  • 第二個是 periodSeconds,它表示的是檢測的時間間隔,正常默認的這個值是 10 秒;

?

  • 第三個字段是 timeoutSeconds,它表示的是檢測的超時時間,當超時時間之內沒有檢測成功,那它會認為是失敗的一個狀態;

?

  • 第四個是 successThreshold,它表示的是:當這個 pod 從探測失敗到再一次判斷探測成功,所需要的閾值次數,默認情況下是 1 次,表示原本是失敗的,那接下來探測這一次成功了,就會認為這個 pod 是處在一個探針狀態正常的一個狀態;

?

  • 最后一個參數是 failureThreshold,它表示的是探測失敗的重試次數,默認值是 3,表示的是當從一個健康的狀態連續探測 3 次失敗,那此時會判斷當前這個pod的狀態處在一個失敗的狀態。

應用健康狀態-Liveness 與 Readiness 總結

接下來對 Liveness 指針和 Readiness 指針進行一個簡單的總結。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

介紹

Liveness 指針是存活指針,它用來判斷容器是否存活、判斷 pod 是否 running。如果 Liveness 指針判斷容器不健康,此時會通過 kubelet 殺掉相應的 pod,并根據重啟策略來判斷是否重啟這個容器。如果默認不配置 Liveness 指針,則默認情況下認為它這個探測默認返回是成功的。

Readiness 指針用來判斷這個容器是否啟動完成,即 pod 的 condition 是否 ready。如果探測的一個結果是不成功,那么此時它會從 pod 上 Endpoint 上移除,也就是說從接入層上面會把前一個 pod 進行摘除,直到下一次判斷成功,這個 pod 才會再次掛到相應的 endpoint 之上。

檢測失敗

對于檢測失敗上面來講 Liveness 指針是直接殺掉這個 pod,而 Readiness 指針是切掉 endpoint 到這個 pod 之間的關聯關系,也就是說它把這個流量從這個 pod 上面進行切掉。

適用場景

Liveness 指針適用場景是支持那些可以重新拉起的應用,而 Readiness 指針主要應對的是啟動之后無法立即對外提供服務的這些應用。

注意事項

在使用 Liveness 指針和 Readiness 指針的時候有一些注意事項。因為不論是 Liveness 指針還是 Readiness 指針都需要配置合適的探測方式,以免被誤操作。

  • 第一個是調大超時的閾值,因為在容器里面執行一個 shell 腳本,它的執行時長是非常長的,平時在一臺 ecs 或者在一臺 vm 上執行,可能 3 秒鐘返回的一個腳本在容器里面需要 30 秒鐘。所以這個時間是需要在容器里面事先進行一個判斷的,那如果可以調大超時閾值的方式,來防止由于容器壓力比較大的時候出現偶發的超時;

  • 第二個是調整判斷的一個次數,3 次的默認值其實在比較短周期的判斷周期之下,不一定是最佳實踐,適當調整一下判斷的次數也是一個比較好的方式;

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

  • 第四個是如果使用 tcpSocket 方式進行判斷的時候,如果遇到了 TLS 的服務,那可能會造成后邊 TLS 里面有很多這種未健全的 tcp connection,那這個時候需要自己對業務場景上來判斷,這種的鏈接是否會對業務造成影響。

?

三、問題診斷

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

應用故障排查-了解狀態機制

首先要了解一下 K8s 中的一個設計理念,就是這個狀態機制。因為 K8s 是整個的一個設計是面向狀態機的,它里面通過 yaml 的方式來定義的是一個期望到達的一個狀態,而真正這個 yaml 在執行過程中會由各種各樣的 controller來負責整體的狀態之間的一個轉換。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?
從零開始入門 K8s | 可觀測性:你的應用健康嗎?

比如說上面的圖,實際上是一個 Pod 的一個生命周期。剛開始它處在一個 pending 的狀態,那接下來可能會轉換到類似像 running,也可能轉換到 Unknown,甚至可以轉換到 failed。然后,當 running 執行了一段時間之后,它可以轉換到類似像 successded 或者是 failed,然后當出現在 unknown 這個狀態時,可能由于一些狀態的恢復,它會重新恢復到 running 或者 successded 或者是 failed 。

其實 K8s 整體的一個狀態就是基于這種類似像狀態機的一個機制進行轉換的,而不同狀態之間的轉化都會在相應的 K8s對象上面留下來類似像 Status 或者像 Conditions 的一些字段來進行表示。

像下面這張圖其實表示的就是說在一個 Pod 上面一些狀態位的一些展現。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

然后再往下看,因為一個 pod 里面有多個 container,每個 container 上面又會有一個字段叫 State,然后 State 的狀態表示當前這個 container 的一個聚合狀態。那在這個例子里面,這個聚合狀態處在的是 waiting 的狀態,那具體的原因是因為什么呢?是因為它的鏡像沒有拉下來,所以處在 waiting 的狀態,是在等待這個鏡像拉取。然后這個 ready 的部分呢,目前是 false,因為它這個進行目前沒有拉取下來,所以這個 pod 不能夠正常對外服務,所以此時 ready 的狀態是未知的,定義為 false。如果上層的 endpoint 發現底層這個 ready 不是 true 的話,那么此時這個服務是沒有辦法對外服務的。

再往下是 condition,condition 這個機制表示是說:在 K8s 里面有很多這種比較小的這個狀態,而這個狀態之間的聚合會變成上層的這個 Status。那在這個例子里面有幾個狀態,第一個是 Initialized,表示是不是已經初始化完成?那在這個例子里面已經是初始化完成的,那它走的是第二個階段,是在這個 ready 的狀態。因為上面幾個 container 沒有拉取下來相應的鏡像,所以 ready 的狀態是 false。

然后再往下可以看到這個 container 是否 ready,這里可以看到是 false,而這個狀態是 PodScheduled,表示說當前這個 pod 是否是處在一個已經被調度的狀態,它已經 bound 在現在這個 node 之上了,所以這個狀態也是 true。

那可以通過相應的 condition 是 true 還是 false 來判斷整體上方的這個狀態是否是正常的一個狀態。而在 K8s 里面不同的狀態之間的這個轉換都會發生相應的事件,而事件分為兩種: 一種叫做 normal 的事件,一種是 warning 事件。大家可以看見在這第一條的事件是有個 normal 事件,然后它相應的 reason 是 scheduler,表示說這個 pod 已經被默認的調度器調度到相應的一個節點之上,然后這個節點是 cn-beijing192.168.3.167 這個節點之上。

再接下來,又是一個 normal 的事件,表示說當前的這個鏡像在 pull 相應的這個 image。然后再往下是一個 warning 事件,這個 warning 事件表示說 pull 這個鏡像失敗了。

以此類推,這個地方表示的一個狀態就是說在 K8s 里面這個狀態機制之間這個狀態轉換會產生相應的事件,而這個事件又通過類似像 normal 或者是 warning 的方式進行暴露。開發者可以通過類似像通過這個事件的機制,可以通過上層 condition Status 相應的一系列的這個字段來判斷當前這個應用的具體的狀態以及進行一系列的診斷。

應用故障排查-常見應用異常

本小節介紹一下常見應用的一些異常。首先是 pod 上面,pod 上面可能會停留幾個常見的狀態。

Pod 停留在 Pending

第一個就是 pending 狀態,pending 表示調度器沒有進行介入。此時可以通過 kubectl describe pod 來查看相應的事件,如果由于資源或者說端口占用,或者是由于 node selector 造成 pod 無法調度的時候,可以在相應的事件里面看到相應的結果,這個結果里面會表示說有多少個不滿足的 node,有多少是因為 CPU 不滿足,有多少是由于 node 不滿足,有多少是由于?tag?打標造成的不滿足。

Pod 停留在 waiting

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

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

第三種是 pod 不斷被拉起,而且可以看到類似像 backoff 。這個通常表示說 pod 已經被調度完成了,但是啟動失敗,那這個時候通常要關注的應該是這個應用自身的一個狀態,并不是說配置是否正確、權限是否正確,此時需要查看的應該是 pod 的具體日志。

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

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

Service 無法正常的工作

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

四、應用遠程調試

本節講解的是在 K8s 里面如何進行應用的遠程調試,遠程調試主要分為 pod 的遠程調試以及 service 的遠程調試。還有就是針對一些性能優化的遠程調試。

應用遠程調試 - Pod 遠程調試

首先把一個應用部署到集群里面的時候,發現問題的時候,需要進行快速驗證,或者說修改的時候,可能需要類似像登陸進這個容器來進行一些診斷。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

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

應用遠程調試 - Servic 遠程調試

那么 service 的遠程調試該怎么做呢?service 的遠程調試其實分為兩個部分:

  • 第一個部分是說我想將一個服務暴露到遠程的一個集群之內,讓遠程集群內的一些應用來去調用本地的一個服務,這是一條反向的一個鏈路;
  • 還有一種方式是我想讓這個本地服務能夠去調遠程的服務,那么這是一條正向的鏈路。

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

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

第二個是如果本地應用需要調用遠程集群的服務時候,可以通過 port-forward 的方式將遠程的應用調用到本地的端口之上。比如說現在遠程的里面有一個 API server,這個 API server 提供了一些端口,本地在調試 Code 時候,想要直接調用這個 API server,那么這時,比較簡單的一個方式就是通過 port-forward 的方式。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

開源的調試工具 - kubectl-debug

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

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

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

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

像這個例子里面,去查看類似像 hostname、進程、netstat 等等,這些其實都是和這個需要 debug 的 pod 是在同一個環境里面的,所以你之前這三條命令可以看到里面相關的信息。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

如果此時進行 logout 的話,相當于會把相應的這個 debug pod 殺掉,然后進行退出,此時對應用實際上是沒有任何的影響的。那么通過這種方式可以不介入到容器里面,就可以實現相應的一個診斷。

從零開始入門 K8s | 可觀測性:你的應用健康嗎?

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

本節總結

  • 關于 Liveness 和 Readiness 的指針。Liveness probe 就是保活指針,它是用來看 pod 是否存活的,而 Readiness probe 是就緒指針,它是判斷這個 pod 是否就緒的,如果就緒了,就可以對外提供服務。這個就是 Liveness 和 Readiness 需要記住的部分;

  • 應用診斷的三個步驟:首先 describe 相應的一個狀態;然后提供狀態來排查具體的一個診斷方向;最后來查看相應對象的一個 event 獲取更詳細的一個信息;

  • 提供 pod 一個日志來定位應用的自身的一個狀態;

  • 遠程調試的一個策略,如果想把本地的應用代理到遠程集群,此時可以通過 Telepresence 這樣的工具來實現,如果想把遠程的應用代理到本地,然后在本地進行調用或者是調試,可以用類似像 port-forward 這種機制來實現。

“ 阿里巴巴云原生微信公眾號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的技術公眾號。”

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

铜陵市| 达州市| 曲阳县| 阿克陶县| 周口市| 遵化市| 兴安县| 海兴县| 鄄城县| 大新县| 平罗县| 丹凤县| 德江县| 南昌市| 拜城县| 上犹县| 和硕县| 沅江市| 文化| 沁阳市| 馆陶县| 安仁县| 临洮县| 五原县| 瑞金市| 天全县| 拉萨市| 中卫市| 盖州市| 北宁市| 巴林右旗| 桐乡市| 葫芦岛市| 漠河县| 枣强县| 巴马| 札达县| 雅江县| 阳春市| 当涂县| 中卫市|