存活探針副本機(jī)制2

存活探針副本機(jī)制2
本次我們開(kāi)始 k8s 中存活探針和副本控制器的學(xué)習(xí)
如何保持 pod 健康
前面我們已經(jīng)知道如何創(chuàng)建 pod,刪除和管理 pod了,但是我們要如何才能保持 pod 的健康狀態(tài)呢?
我們可以使用 存活探針和副本機(jī)制
探針的分類
探針目前有
存活探針 liveness probe
就緒探針 readiness probe
本次我們這里先分享存活探針
存活探針
使用存活探針可以檢查容器是否還在運(yùn)行,我們可以為 pod 中的每一個(gè)容器單獨(dú)的指定存活探針,如果探測(cè)失敗,那么 k8s 就會(huì)定期的執(zhí)行探針并重啟容器
在 k8s 中,有 3 中探測(cè)容器的機(jī)制:
http get 探針
可以對(duì)容器的 IP 地址,指定的端口和路徑,進(jìn)行 http get 請(qǐng)求,若探測(cè)器收到的狀態(tài)碼不是錯(cuò)誤(2xx,3xx 的狀態(tài)碼),那么就認(rèn)為是認(rèn)為是探測(cè)成功,否則就是探測(cè)失敗,本次容器就會(huì)被終止,然后重新啟動(dòng)一個(gè) pod
tcp 套接字探針
探測(cè)器嘗試與指定端口建立 TCP 連接,如果成功建立連接,則探測(cè)成功,否則,失敗
Exec 探針
在容器內(nèi)部執(zhí)行命令,并檢查退出的錯(cuò)誤碼,如果錯(cuò)誤碼是 0 ,則探測(cè)成功,否則失敗
存活探針案例
我們來(lái)創(chuàng)建一個(gè) pod ,加入我們的存活探針
kubia-liveness.yaml
apiVersion:?v1
kind:?Pod
metadata:
??name:?kubia-liveness
spec:
??containers:
??-?image:?luksa/kubia-unhealthy
????name:?kubia
????livenessProbe:
??????httpGet:
????????path:?/
????????port:?8080
還是使用之前的 kubia 的例子,我們拉取的鏡像是 luksa/kubia-unhealthy,這個(gè)鏡像和之前的鏡像有一些區(qū)別,就是當(dāng)收到外部訪問(wèn)的時(shí)候,前 5 次會(huì)正常響應(yīng),后面的請(qǐng)求都會(huì)報(bào)錯(cuò)
我們就可以通過(guò)這樣的方式來(lái)測(cè)試 存活探針
部署一個(gè) liveprobe 的案例,不健康的應(yīng)用 kubia
部署 pod
kubectl create -f kubia-liveness.yaml
部署之后,大概1-2 分鐘的時(shí)候,我們就可以看到我們啟動(dòng)的 pod 存在重啟的情況

例如上圖,kubia-liveness 11 分鐘內(nèi),就重啟了 5 次
查看崩潰應(yīng)用的日志
我們查看日志的時(shí)候一般使用 kubectl logs -f xxx
,但是我們現(xiàn)在需要查看崩潰應(yīng)用的日志,我們可以這么查看
kubectl logs -f kubia-liveness --previous

我們可以看到崩潰應(yīng)用的程序是這樣的
查看 pod 的詳細(xì)信息
kubectl describe po kubia-liveness

查看 pod 的詳細(xì)信息的時(shí)候,我們可以看到這些關(guān)鍵信息:
Exit Code
137 是代表 128 + x , 可以看出 x 是 9,也就是 SIGKILL 的信號(hào)編號(hào),以為這強(qiáng)行終止
有時(shí)候,也會(huì)是 143,那么 x 就是 15,就是 SIGTERM 信號(hào)
Liveness
容器啟動(dòng)后延時(shí)多少時(shí)間才開(kāi)始探測(cè),若 該數(shù)值為 0 , 那么在容器啟動(dòng)后,就會(huì)立即探測(cè)
超時(shí)時(shí)間,可以看出上圖超時(shí)時(shí)間為 1 秒,因此容器必須在 1 s 內(nèi)做出響應(yīng),否則為探測(cè)失敗
上圖為 10 s 探測(cè)一次
指 失敗多少次之后,就會(huì)重啟容器(此處說(shuō)的重啟容器,指刪除掉原有 pod,重新創(chuàng)建一個(gè) pod),上圖是 失敗 3 次后會(huì)重啟容器
failure 失敗次數(shù)
period 周期
timeout 超時(shí)時(shí)間
delay ?延遲

如上圖,我們還可以看到 pod 的狀態(tài)是不健康的,存活探針探測(cè)失敗,原因是容器報(bào) 500 了,沒(méi)有響應(yīng),因此會(huì)立即重啟容器
配置存活探針的參數(shù)
配置存活探針的參數(shù)也就是和上述的 liveness probe 的參數(shù)一一對(duì)應(yīng),我們一般會(huì)設(shè)置一個(gè)延遲時(shí)間,因?yàn)槿萜鲉?dòng)之后,具體的應(yīng)用程序有時(shí)并準(zhǔn)備好
因此我們需要設(shè)定一個(gè)延遲時(shí)間,這個(gè)延遲時(shí)間,也可以標(biāo)志是應(yīng)用程序的啟動(dòng)時(shí)間
我們可以這樣加入配置,設(shè)置容器啟動(dòng)后第一次探測(cè)時(shí)間延遲 20 s:
apiVersion:?v1
kind:?Pod
metadata:
??name:?kubia-liveness
spec:
??containers:
??-?image:?luksa/kubia-unhealthy
????name:?kubia
????livenessProbe:
??????httpGet:
????????path:?/
????????port:?8080
??????initialDelaySeconds:?20
存活探針的注意事項(xiàng)
我們創(chuàng)建存活探針的時(shí)候,需要保證是一個(gè)有效的存活探針
配置存活探針請(qǐng)求的端口和地址,保證端口和地址有效
存活探針訪問(wèn)地址的時(shí)候,保證不需要認(rèn)證,否則會(huì)一直失敗,一起重啟容器
一定要檢查程序的內(nèi)部,沒(méi)有被外部因素所影響
要注意探針的不應(yīng)消耗太多資源,一般必須在 1 s 內(nèi)完成響應(yīng)
遺留問(wèn)題
使用探測(cè)保持 pod 健康,看上去感覺(jué)還不錯(cuò),當(dāng) pod 中容器出現(xiàn)異常的時(shí)候,存活探針能夠刪除掉異常的 pod ,并立刻重新創(chuàng)建 pod
但是,如果是 pod 所在節(jié)點(diǎn)掛掉了,那么 存活探針就沒(méi)有辦法進(jìn)行處理了,因?yàn)槭枪?jié)點(diǎn)上面的 Kubelet 來(lái)處理存活探針的事項(xiàng),現(xiàn)在節(jié)點(diǎn)都異常了
我們可以使用副本機(jī)制來(lái)解決

ReplicationController 副本控制器
ReplicationController ?也是K8S 的一種資源,前面有簡(jiǎn)單說(shuō)到過(guò),可以確保它管理的 pod 始終保持運(yùn)行狀態(tài),如果 pod 因?yàn)槿魏卧蛳Я?,ReplicationController ?都會(huì)檢測(cè)到這個(gè)情況,并會(huì)創(chuàng)建 pod 用于替代
舉個(gè) rc 的例子
rc 是 ReplicationController ?的簡(jiǎn)稱,rc 旨在創(chuàng)建和管理 pod 的多個(gè)副本
例如,node1 上面 有 2 個(gè) pod, podAA 和 pod BB
podAA 是單獨(dú)創(chuàng)建的 pod,不受 rc 控制
pod BB,是由 rc 控制的

當(dāng) node1 節(jié)點(diǎn)出現(xiàn)異常的時(shí)候,podAA 是沒(méi)了就沒(méi)了,沒(méi)有人管它,自身自滅的
pod BB 就不一樣,當(dāng) node1 出現(xiàn)異常的時(shí)候,rc 會(huì)在 node2 上面創(chuàng)建一個(gè) pod BB 的副本
rc 小案例
rc 也是 k8s 的一種資源,那么創(chuàng)建 rc 的時(shí)候,也是通過(guò) json 或者 yaml 的方式來(lái)創(chuàng)建的,創(chuàng)建 rc 有 3 個(gè)重要的組成部分:
label selector 標(biāo)簽選擇器
用于 rc 作用域哪些 pod
replica count 副本個(gè)數(shù)
指定應(yīng)運(yùn)行的 pod 數(shù)量
pod template pod 模板
用于創(chuàng)建新的 pod 股本
我們可以這樣寫(xiě),創(chuàng)建一個(gè)名為 kubia 的 rc
kubia-rc.yaml
apiVersion:?v1
kind:?ReplicationController
metadata:
??name:?kubia
spec:
??replicas:?3
??selector:
????app:?xmt-kubia
??template:
????metadata:
??????labels:
????????app:?xmt-kubia
????spec:
??????containers:
??????-?name:?rc-kubia
????????image:?xiaomotong888/xmtkubia
????????ports:
????????-?containerPort:?8080
表示創(chuàng)建一個(gè) rc,名字是 kubia,副本數(shù)是 3 個(gè),選擇器是 app=xmt-kubia
rc 對(duì)應(yīng)的 pod 模板,拉取的鏡像地址是 xiaomotong888/xmtkubia,標(biāo)簽是 ?app=xmt-kubia
我們創(chuàng)建 rc 的時(shí)候,一般也可以不用寫(xiě) selector,因?yàn)?Kubernetes API 會(huì)去檢查 yaml 是否正確,yaml 中是否有模板,如果有模板的話,selector 對(duì)應(yīng)的標(biāo)簽,就是 pod 模板中的標(biāo)簽
但是一定要寫(xiě) pod 的模板 template,否則 Kubernetes API 就會(huì)報(bào)錯(cuò)誤信息
部署 rc
kubectl create -f kubia-rc.yaml
查看 rc 和 查看 pod 的標(biāo)簽
kubectl get rc
kubectl get pod --show-labels

我們可以看到創(chuàng)建的 rc 資源,所需要?jiǎng)?chuàng)建 pod 數(shù)量是 3,當(dāng)前實(shí)際數(shù)量是 3 ,就緒的也是 3 個(gè)
kubia-749wj
kubia-mpvkd
kubia-tw848
并且,他們的標(biāo)簽都是 app=xmt-kubia,沒(méi)毛病老鐵
rc 的擴(kuò)容和縮容
rc 控制器會(huì)控制創(chuàng)建 pod 和刪除 pod,大致邏輯是這樣的
rc 啟動(dòng)的時(shí)候,會(huì)在環(huán)境中搜索匹配的標(biāo)簽,
若搜索到的標(biāo)簽數(shù)量小于 rc 中配置的期望數(shù)量,則進(jìn)行創(chuàng)建新的 pod
若搜索到的標(biāo)簽數(shù)量大于rc 中配置的期望數(shù)量,則進(jìn)行刪除多余的 pod

我們嘗試刪除掉 kubia-749wj ,驗(yàn)證 rc 是否會(huì)自動(dòng)創(chuàng)建新的 pod
kubectl delete po kubia-749wj

果然 ?kubia-749wj 已經(jīng)是終止?fàn)顟B(tài)了,且 rc 已經(jīng)為我們創(chuàng)建了一個(gè) 新的 pod
查看 rc 的詳情
kubectl describe rc kubia

我們可以看到,從創(chuàng)建 rc 到現(xiàn)在,rc 創(chuàng)建的 pod 的記錄是 4 個(gè)
修改 pod 的標(biāo)簽
我們嘗試修改某個(gè) pod 的標(biāo)簽,看看是否會(huì)影響 rc 的
在 kubia–mpvkd pod 上面增加一個(gè) ver=dev 的標(biāo)簽,看看該 pod 是否會(huì)被刪除掉
kubectl?get?pod?--show-labels
kuebctl?label?pod?kubia-mpvkd?ver=dev

果然是沒(méi)有的,對(duì)于 rc 來(lái)說(shuō),他只會(huì)管理和控制自己配置好的標(biāo)簽,其余的標(biāo)簽他一概不管
重寫(xiě) app 標(biāo)簽
前面我們有說(shuō)到過(guò),如果 pod 上已經(jīng)有標(biāo)簽,若是要修改的話,需要使用--overwrite
?進(jìn)行重寫(xiě),這也是 k8s 為了方式誤操作,覆蓋了已經(jīng)配置好的標(biāo)簽
我們將 app標(biāo)簽修改成 app=anonymous
kubectl label pod kubia-mpvkd app=anonymous --overwrite

查看到的效果是原來(lái)的 ?kubia-mpvkd pod 沒(méi)有什么影響,但是 rc 檢測(cè)到 app=xmt-kubia 標(biāo)簽的數(shù)量小于 rc 的期望值,因此會(huì)主動(dòng)創(chuàng)建一個(gè)新的 pod 作為替代
簡(jiǎn)單流程和效果如下圖:


說(shuō)一下修改模板
修改模板的話,是很簡(jiǎn)單的,只需要編輯一個(gè) rc 配置即可
kubectl edit rc kubia
執(zhí)行命令后,將 rc 配置中 pod 模板中 image 的位置,修改成自己需要下載的鏡像地址即可,關(guān)于 pod 模板的簡(jiǎn)單流程如下:

上圖中,我們可以理解,修改了 pod 模板的話,對(duì)于之前的 pod 是沒(méi)有影響的,因?yàn)楦北镜膫€(gè)數(shù)還是沒(méi)有變化
當(dāng)我們刪除掉一個(gè) pod 的時(shí)候,次數(shù) rc 檢測(cè)到 實(shí)際的 pod 個(gè)數(shù)小于 期望的個(gè)數(shù),因此會(huì)創(chuàng)建一個(gè)新的 pod,此時(shí)創(chuàng)建的 pod,用的就是剛才我們修改的 pod 模板
修改副本數(shù)
我們可以嘗試修改副本數(shù)為 6 ,還是一樣的操作,編輯 rc 配置即可
kubectl edit rc kubia


效果如上, rc 為我們又創(chuàng)建了 3 個(gè) pod,總共是 6 個(gè)
修改副本數(shù)為 2

效果如上,rc 確實(shí)將其余的 4 個(gè)pod 都干掉了,最后剩下 2 個(gè) pod
刪除 rc
小伙伴們有沒(méi)有這樣的疑問(wèn),刪除 rc 的話,是不是 pod 也就跟著被銷毀了,是的,沒(méi)毛病老鐵
但是我們也可以做到刪除 rc 后,不影響 pod 資源,可以這樣來(lái)執(zhí)行
kubectl delete rc kubia --cascade=false
看到信息提示, --cascade=false
已經(jīng)被廢棄了,我們可以使用 --cascade=orphan
刪除 rc 生效,我們來(lái)看看簡(jiǎn)單的刪除流程和效果
今天就到這里,學(xué)習(xí)所得,若有偏差,還請(qǐng)斧正
歡迎點(diǎn)贊,關(guān)注,收藏
朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力

好了,本次就到這里
技術(shù)是開(kāi)放的,我們的心態(tài),更應(yīng)是開(kāi)放的。擁抱變化,向陽(yáng)而生,努力向前行。
我是阿兵云原生,歡迎點(diǎn)贊關(guān)注收藏,下次見(jiàn)~