您好,登錄后才能下訂單哦!
首先來看一下,整個需求的來源:當把應用遷移到 Kubernetes 之后,要如何去保障應用的健康與穩定呢?其實很簡單,可以從兩個方面來進行增強:
1,首先是提高應用的可觀測性;
2,第二是提高應用的可恢復能力。
從可觀測性上來講,可以在三個方面來去做增強:
1,首先是應用的健康狀態上面,可以實時地進行觀測;
2,第二個是可以獲取應用的資源使用情況;
3,第三個是可以拿到應用的實時日志,進行問題的診斷與分析。
當出現了問題之后,首先要做的事情是要降低影響的范圍,進行問題的調試與診斷。最后當出現問題的時候,理想的狀況是:可以通過和 K8s 集成的自愈機制進行完整的恢復。
livenessProbe:[活躍度探測],就是根據用戶自定義的規則判斷容器是否健康。也叫存活指針,如果 Liveness 指針判斷容器不健康,此時會通過 kubelet 殺掉相應的 pod,并根據重啟策略來判斷是否重啟這個容器。如果默認不配置 Liveness 指針,則默認情況下認為它這個探測默認返回是成功的。
什么是Endpoint?
Endpoint是k8s集群中的一個資源對象,存儲在etcd中,用來記錄一個service對應的所有pod的訪問地址。
2,Liveness和Readness兩種探測機制的使用場景:
Liveness 指針適用場景是支持那些可以重新拉起的應用,而 Readiness 指針主要應對的是啟動之后無法立即對外提供服務的這些應用。
3,,Liveness和Readness兩種探測機制的相同點和不同點:
相同點是根據探測pod內某個應用或文件,來檢查pod的健康狀況,不同點是liveness如果探測失敗會重啟pod,而readliness則在連續3次探測失敗之后,會將pod設置為不可用的狀態,并不會重啟pod。
4,Liveness 指針和 Readiness 指針支持三種不同的探測方式:
第一種探測方式和第三種非常相似,一般常用的是第一和第二種的探測方式。
方法1:使用exec探測方式,查看pod內某個指定的文件是否存在,如果存在則認為狀態為健康的,否則會根據設置的重啟重啟策略重啟pod。
###pod的配置文件:
[root@sqm-master yaml]# vim livenss.yaml
kind: Pod
apiVersion: v1
metadata:
name: liveness
labels:
name: liveness
spec:
restartPolicy: OnFailure ##定義重啟策略,僅在pod對象出現錯誤時才重啟
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300 #創建文件,并且在30秒后將文件進行刪除
livenessProbe: #執行活躍度探測
exec:
command:
- cat #探測/tmp目錄下是有test文件,如果有則代表健康,如果沒有則執行重啟pod策略。
- /tmp/test
initialDelaySeconds: 10 #當容器運行多久之后開始探測(單位是s)
periodSeconds: 5 #探測頻率(單位s),每隔5秒探測一次。
探測機制中其他的可選字段:
- initialDelaySeconds:容器啟動后第一次執行探測是需要等待多少秒。
- periodSeconds:執行探測的頻率。默認是10秒,最小1秒。
- timeoutSeconds:探測超時時間。默認1秒,最小1秒。
- successThreshold:探測失敗后,最少連續探測成功多少次才被認定為成功。默認是1。對于liveness必須是1。最小值是1。
- failureThreshold:探測成功后,最少連續探測失敗多少次才被認定為失敗。默認是3。最小值是1。
//運行該pod進行測試:
[root@sqm-master yaml]# kubectl apply -f livenss.yaml
pod/liveness created
//監測pod的狀態:
會在容器啟動10秒后開始探測,且每5s探測一次。
我們可以看到pod一直在重啟中,從上圖看到RESTARTS
的次數已經為7次了,原因是在啟動pod時執行了該命令:
/bin/sh -c "touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300"
在容器生命的最初30秒內有一個 /tmp/test 文件,在這30秒內 cat /tmp/test命令會返回一個成功的返回碼。但30秒后, cat /tmp/test 將返回失敗的返回碼,會觸發pod的重啟策略。
//我們來查看一下pod的Events信息:
[root@sqm-master ~]# kubectl describe pod liveness
從上面的事件中可以發現,探測失敗,將重啟容器,原因是在指定的目錄下沒有發現該文件。
方法2:使用httpGet探測方式,運行一個web服務,探測web網頁的根目錄下是否有指定的文件,也就等同于 “curl -I 容器ip地址:/healthy”。(這里的目錄/,指定的是容器內提供web服務的主目錄。)
//pod的yaml文件:
[root@sqm-master yaml]# vim http-livenss.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
name: mynginx
spec:
restartPolicy: OnFailure #定義pod重啟策略
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe: #定義探測機制
httpGet: #探測方式為httpGet
scheme: HTTP #指定協議
path: /healthy #指定路徑下的文件,如果不存在,探測失敗
port: 80
initialDelaySeconds: 10 #當容器運行多久之后開始探測(單位是s)
periodSeconds: 5 #探測頻率(單位s),每隔5秒探測一次
---
apiVersion: v1 #關聯一個service對象
kind: Service
metadata:
name: web-svc
spec:
selector:
name: mynginx
ports:
- protocol: TCP
port: 80
targetPort: 80
httpGet探測方式有如下可選的控制字段:
- host:連接的主機名,默認連接到pod的IP。你可能想在http header中設置”Host”而不是使用IP。
- scheme:連接使用的schema,默認HTTP。
- path: 訪問的HTTP server的path。
- httpHeaders:自定義請求的header。HTTP運行重復的header。
- port:訪問的容器的端口名字或者端口號。端口號必須介于1和65525之間。
//運行該pod:
[root@sqm-master yaml]# kubectl apply -f http-livenss.yaml
pod/web created
service/web-svc created
##查看pod運行10秒前的情況:
##最開始的10秒該容器是活著的,且返回的狀態碼為200.
###10秒后當探測機制開始探測時再次查看pod的情況:
//查看的pod的events:
[root@sqm-master yaml]# kubectl describe pod web
可以看到返回的狀態碼為404,表示在網頁的根目錄下并沒有找到指定的文件,表示探測失敗,且重啟4次,狀態是completed(完成的狀態),說明pod是存在問題的。
2)接下來我們繼續進行檢測,使其最終探測成功:
修改pod的配置文件:
[root@sqm-master yaml]# vim http-livenss.yaml
//重新運行pod:
[root@sqm-master yaml]# kubectl delete -f http-livenss.yaml
pod "web" deleted
service "web-svc" deleted
[root@sqm-master yaml]# kubectl apply -f http-livenss.yaml
pod/web created
service/web-svc created
//最終我們查看pod的狀態及Events信息:
[root@sqm-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web 1/1 Running 0 5s 10.244.1.11 node01 <none> <none>
[root@sqm-master yaml]# kubectl describe pod web
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 71s default-scheduler Successfully assigned default/web to node01
Normal Pulling 71s kubelet, node01 Pulling image "nginx"
Normal Pulled 70s kubelet, node01 Successfully pulled image "nginx"
Normal Created 70s kubelet, node01 Created container nginx
Normal Started 70s kubelet, node01 Started container nginx
可以看到pod的狀態時正常運行的。
##測試訪問網頁頭部信息:
[root@sqm-master yaml]# curl -I 10.244.1.11
返回的狀態碼為200,表示這個pod的狀況時健康的。
方法1:使用exec探測方式,與iveness相同,探測某個文件是否存在。
//pod的配置文件如下:
[root@sqm-master yaml]# vim readiness.yaml
kind: Pod
apiVersion: v1
metadata:
name: readiness
labels:
name: readiness
spec:
restartPolicy: OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300;
readinessProbe: #定義readiness探測方式
exec:
command:
- cat
- /tmp/test
initialDelaySeconds: 10
periodSeconds: 5
//運行該pod:
[root@sqm-master yaml]# kubectl apply -f readiness.yaml
pod/readiness created
//檢測pod的狀態:
//查看pod的Events:
[root@sqm-master yaml]# kubectl describe pod readiness
可以看到找不到該文件,表示探測失敗,但是readiness機制與liveness機制不同,它并不會重啟pod,而是連續探測3次失敗后,則將容器設置為不可用的狀態。
方法二:httpGet方式。
[root@sqm-master yaml]# vim http-readiness.yaml
apiVersion: v1
kind: Pod
metadata:
name: web2
labels:
name: web2
spec:
containers:
- name: web2
image: nginx
ports:
- containerPort: 81
readinessProbe:
httpGet:
scheme: HTTP #指定協議
path: /healthy #指定路徑,如果不存在,則需要進行創建,否則探測失敗
port: 81
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
name: web2
ports:
- protocol: TCP
port: 81
targetPort: 81
//運行pod:
[root@sqm-master yaml]# kubectl apply -f http-readiness.yaml
pod/web2 created
service/web-svc created
//查看pod的狀態:
[root@sqm-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
readiness 0/1 Completed 0 37m 10.244.2.12 node02 <none> <none>
web 1/1 Running 0 50m 10.244.1.11 node01 <none> <none>
web2 0/1 Running 0 2m31s 10.244.1.14 node01 <none> <none>
查看pod的Events信息,通過探測,可以知道pod是不健康的,且http訪問失敗。
它并不會重啟,而是直接將pod設置為不可用的狀態。
首先我們通過explain工具來查看更新使用的字段:
[root@sqm-master ~]# kubectl explain deploy.spec.strategy.rollingUpdate
可以看到在滾動更新的過程中有兩個參數可用:
maxSurge和maxUnavailable的適用場景:
1,如果您希望在保證系統可用性和穩定性的前提下盡可能快地進行升級,可以將 maxUnavailable 設置為 0,同時為 maxSurge 賦予一個較大值。
2,如果系統資源比較緊張,pod 負載又比較低,為了加快升級速度,可以將 maxSurge 設置為 0,同時為 maxUnavailable 賦予一個較大值。需要注意的是,如果 maxSurge 為 0maxUnavailable 為 DESIRED,可能造成整個服務的不可用,此時 RollingUpdate 將退化成停機發布
1)首先我們創建一個deployment資源對象:
[root@sqm-master ~]# vim app.v1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-web
spec:
replicas: 10 #定義副本數量為10個
template:
metadata:
labels:
name: my-web
spec:
containers:
- name: my-web
image: nginx
args:
- /bin/sh
- -c
- touch /usr/share/nginx/html/test.html; sleep 300000; #創建文件,使其在探測時保持pod為健康狀態
ports:
- containerPort: 80
readinessProbe: #使用readiness機制
exec:
command:
- cat
- /usr/share/nginx/html/test.html
initialDelaySeconds: 10
periodSeconds: 10
//運行該pod后,查看pod數量(10個):
[root@sqm-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-web-7bbd55db99-2g6tp 1/1 Running 0 2m11s 10.244.2.44 node02 <none> <none>
my-web-7bbd55db99-2jdbz 1/1 Running 0 118s 10.244.2.45 node02 <none> <none>
my-web-7bbd55db99-5mhcv 1/1 Running 0 2m53s 10.244.1.40 node01 <none> <none>
my-web-7bbd55db99-77b4v 1/1 Running 0 2m 10.244.1.44 node01 <none> <none>
my-web-7bbd55db99-h888n 1/1 Running 0 2m53s 10.244.2.41 node02 <none> <none>
my-web-7bbd55db99-j5tgz 1/1 Running 0 2m38s 10.244.2.42 node02 <none> <none>
my-web-7bbd55db99-kjgm2 1/1 Running 0 2m25s 10.244.1.42 node01 <none> <none>
my-web-7bbd55db99-kkmh3 1/1 Running 0 2m38s 10.244.1.41 node01 <none> <none>
my-web-7bbd55db99-lr896 1/1 Running 0 2m13s 10.244.1.43 node01 <none> <none>
my-web-7bbd55db99-rpd8v 1/1 Running 0 2m23s 10.244.2.43 node02 <none>
探測成功,10個副本全部運行。
2)第一次更新:
更新nginx鏡像版本,且設置滾動更新策略:
[root@sqm-master yaml]# vim app.v1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-web
spec:
strategy: #設置滾動更新策略,通過該字段下的rollingUpdate的子屬性來設置
rollingUpdate:
maxSurge: 3 #指定在滾動更新過程中最多可創建3個額外的 pod
maxUnavailable: 3 #- 指定在滾動更新過程中最多允許3 pod 不可用
replicas: 10
template:
metadata:
labels:
name: my-web
spec:
containers:
- name: my-web
image: 172.16.1.30:5000/nginx:v2.0 #更新的鏡像為私有倉庫中的鏡像nginx:v2.0
args:
- /bin/sh
- -c
- touch /usr/share/nginx/html/test.html; sleep 300000;
ports:
- containerPort: 80
readinessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/test.html
initialDelaySeconds: 10
periodSeconds: 10
//執行yaml文件后,查看pod數量:
[root@sqm-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-web-7db8b88b94-468zv 1/1 Running 0 3m38s 10.244.2.57 node02 <none> <none>
my-web-7db8b88b94-bvszs 1/1 Running 0 3m24s 10.244.1.60 node01 <none> <none>
my-web-7db8b88b94-c4xvv 1/1 Running 0 3m38s 10.244.2.55 node02 <none> <none>
my-web-7db8b88b94-d5fvc 1/1 Running 0 3m38s 10.244.1.58 node01 <none> <none>
my-web-7db8b88b94-lw6nh 1/1 Running 0 3m21s 10.244.2.59 node02 <none> <none>
my-web-7db8b88b94-m9gbh 1/1 Running 0 3m38s 10.244.1.57 node01 <none> <none>
my-web-7db8b88b94-q5dqc 1/1 Running 0 3m38s 10.244.1.59 node01 <none> <none>
my-web-7db8b88b94-tsbmm 1/1 Running 0 3m38s 10.244.2.56 node02 <none> <none>
my-web-7db8b88b94-v5q2s 1/1 Running 0 3m21s 10.244.1.61 node01 <none> <none>
my-web-7db8b88b94-wlgwb 1/1 Running 0 3m25s 10.244.2.58 node02 <none> <none>
//查看pod的版本信息:
[root@sqm-master yaml]# kubectl get deployments. -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-web 10/10 10 10 49m my-web 172.16.1.30:5000/nginx:v2.0 name=my-web
探測成功,10個pod版本全部更新成功。
3)第二次更新:
將鏡像版本更新為3.0版本,且設置滾動更新策略。(探測失敗)
pod的配置文件如下:
[root@sqm-master yaml]# vim app.v1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-web
spec:
strategy:
rollingUpdate:
maxSurge: 3 #定義更新策略,數量依然都是保持3個
maxUnavailable: 3
replicas: 10 #pod數量依然是10個
template:
metadata:
labels:
name: my-web
spec:
containers:
- name: my-web
image: 172.16.1.30:5000/nginx:v3.0 #測試鏡像版本更新為3.0
args:
- /bin/sh
- -c
- sleep 300000; #不在創建指定文件,使其探測失敗
ports:
- containerPort: 80
readinessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/test.html
initialDelaySeconds: 10
periodSeconds: 5
//重新運行pod配置文件:
[root@sqm-master yaml]# kubectl apply -f app.v1.yaml
deployment.extensions/my-web configured
//查看pod更新后的數量:
[root@sqm-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-web-7db8b88b94-468zv 1/1 Running 0 12m 10.244.2.57 node02 <none> <none>
my-web-7db8b88b94-c4xvv 1/1 Running 0 12m 10.244.2.55 node02 <none> <none>
my-web-7db8b88b94-d5fvc 1/1 Running 0 12m 10.244.1.58 node01 <none> <none>
my-web-7db8b88b94-m9gbh 1/1 Running 0 12m 10.244.1.57 node01 <none> <none>
my-web-7db8b88b94-q5dqc 1/1 Running 0 12m 10.244.1.59 node01 <none> <none>
my-web-7db8b88b94-tsbmm 1/1 Running 0 12m 10.244.2.56 node02 <none> <none>
my-web-7db8b88b94-wlgwb 1/1 Running 0 12m 10.244.2.58 node02 <none> <none>
my-web-849cc47979-2g59w 0/1 Running 0 3m9s 10.244.1.63 node01 <none> <none>
my-web-849cc47979-2lkb6 0/1 Running 0 3m9s 10.244.1.64 node01 <none> <none>
my-web-849cc47979-762vb 0/1 Running 0 3m9s 10.244.1.62 node01 <none> <none>
my-web-849cc47979-dv7x8 0/1 Running 0 3m9s 10.244.2.61 node02 <none> <none>
my-web-849cc47979-j6nwz 0/1 Running 0 3m9s 10.244.2.60 node02 <none> <none>
my-web-849cc47979-v5h7h 0/1 Running 0 3m9s 10.244.2.62 node02 <none> <none>
我們可以看到當前pod的總數量為13個,(包括maxSurge增加額外的數量)因為探測失敗,則設置為將3個pod(包括額外的pod)為不可用的狀態,但還剩下7個pod可用( 因為maxUnavailable設置為3個),但注意:這7個pod的版本并沒有更新成功,還是上一個的版本。
//查看pod的更新后的版本信息:
[root@sqm-master yaml]# kubectl get deployments. -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-web 7/10 6 7 58m my-web 172.16.1.30:5000/nginx:v3.0 name=my-web
參數解釋:
READY :表示用戶的期望值
UP-TO-DATE:表示已更新的
AVAILABLE:表示可用的
我們可以發現已更新的鏡像版本數量為6個(包括額外的3個pod),但是為不可用的狀態,但是確保可用的的pod數量為7個,但是版本并沒有更新。
總結:
描述在滾動更新過程中,探測機制有什么作用?
如果在公司中需要對某個應用中的pod進行更新操作,如果沒有探測機制,無論該pod是不是當你已經做好更新工作準備要進行更新的,它都會將該應用中所有的pod進行更新,這樣會造成嚴重的后果,雖然更新后你發現pod的狀態是正常的,為了達到controller manager的期望值,READY的值依然是1/1, 但是pod已經是重新生成的pod了,表示pod內的數據將會全部丟失。
如果加上探測機制的話,會探測容器內你指定的文件或其他應用是否存在,如果達到你指定的條件,則探測成功,則會對你的pod進行更新,如果探測失敗則會設置pod(容器)為不可用,雖然探測失敗的容器不可用了,但至少該模塊中還有其他之前版本的pod可用,確保該公司該服務的正常運行。可見探測機制是多么的重要啊。
———————— 本文至此結束,感謝閱讀 ————————
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。