目錄
一、Pod簡(jiǎn)介
Pod的退出流程
1、什么是Pod
2、定義一個(gè)Pod
二、探針、零宕機(jī)發(fā)布
1、Pod探針
2、Pod探針的檢測(cè)方式
3、探針檢查參數(shù)配置
4、startupProbe
5、liveness
6、readiness
7、Pod 優(yōu)雅關(guān)閉
一、Pod簡(jiǎn)介
Pod的退出流程
-
管理員 執(zhí)行的刪除操作
-
Pod 的狀態(tài)為 terminating
-
EndPoint 會(huì)刪除 對(duì)應(yīng)的 Pod-IP
-
執(zhí)行Prestop的指令
1、什么是Pod
Pod是Kubernetes中最小的單元,它由一組、一個(gè)或多個(gè)容器組成,每個(gè)Pod還包含了一個(gè)Pause容器,Pause容器是Pod的父容器,主要負(fù)責(zé)僵尸進(jìn)程的回收管理,通過Pause容器可以使同一個(gè)Pod里面的多個(gè)容器共享存儲(chǔ)、網(wǎng)絡(luò)、PID、IPC等。
通過Pod的概念能夠方便 管理容器,因?yàn)槿萜鞑恢灰环N,有多種容器
副本的概念,便捷的擴(kuò)容與伸縮,資源的管理,Pod使容器之間的通信更為密切(通過Pause鏡像),減少端口的資源浪費(fèi)
2、Pod基礎(chǔ)參數(shù)解析
apiVersion: v1 # 必選,API的版本號(hào)
kind: Pod # 必選,類型Pod
metadata: # 必選,元數(shù)據(jù)
name: nginx # 必選,符合RFC 1035規(guī)范的Pod名稱
# namespace: default # 可選,Pod所在的命名空間,不指定默認(rèn)為default,可以使用-n 指定namespace
labels: # 可選,標(biāo)簽選擇器,一般用于過濾和區(qū)分Pod,根據(jù)業(yè)務(wù)自定義
app: nginx
role: frontend # 可以寫多個(gè)
annotations: # 可選,注釋列表,可以寫多個(gè)
app: nginx1.21 #可以注釋一些 Nginx版本
spec: # 必選,用于定義容器的詳細(xì)信息
# initContainers: # 初始化容器,在容器啟動(dòng)之前執(zhí)行的一些初始化操作
# - command:
# - sh
# - -c
# - echo "I am InitContainer for init some configuration"
# image: busybox
# imagePullPolicy: IfNotPresent
# name: init-container
containers: # 必選,容器列表
- name: nginx # 必選,符合RFC 1035規(guī)范的容器名稱
image: nginx:1.15.2 # 必選,容器所用的鏡像的地址
imagePullPolicy: IfNotPresent # 可選,鏡像拉取策略, IfNotPresent: 如果宿主機(jī)有這個(gè)鏡像,那就不需要拉取了. Always: 總是拉取, Never: 不管是否存儲(chǔ)都不拉去
command: # 可選,容器啟動(dòng)執(zhí)行的命令 ENTRYPOINT, arg --> cmd
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可選,容器的工作目錄
# volumeMounts: # 可選,存儲(chǔ)卷配置,可以配置多個(gè)
# - name: webroot # 存儲(chǔ)卷名稱
# mountPath: /usr/share/nginx/html # 掛載目錄
# readOnly: true # 只讀
ports: # 可選,容器需要暴露的端口號(hào)列表
- name: http # 端口名稱
containerPort: 80 # 端口號(hào)
protocol: TCP # 端口協(xié)議,默認(rèn)TCP
env: # 可選,環(huán)境變量配置列表
- name: TZ # 變量名
value: Asia/Shanghai # 變量的值
- name: LANG
value: en_US.utf8
# resources: # 可選,資源限制和資源請(qǐng)求限制
# limits: # 最大限制設(shè)置
# cpu: 1000m
# memory: 1024Mi
# requests: # 啟動(dòng)所需的資源
# cpu: 100m
# memory: 512Mi
# startupProbe: # 可選,檢測(cè)容器內(nèi)進(jìn)程是否完成啟動(dòng)。注意三種檢查方式同時(shí)只能使用一種。
# httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
# path: /api/successStart # 檢查路徑
# port: 80
# readinessProbe: # 可選,健康檢查。注意三種檢查方式同時(shí)只能使用一種。
# httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
# path: / # 檢查路徑
# port: 80 # 監(jiān)控端口
# livenessProbe: # 可選,健康檢查
#exec: # 執(zhí)行容器命令檢測(cè)方式
#command:
#- cat
#- /health
#httpGet: # httpGet檢測(cè)方式
# path: /_health # 檢查路徑
# port: 8080
# httpHeaders: # 檢查的請(qǐng)求頭
# - name: end-user
# value: Jason
# tcpSocket: # 端口檢測(cè)方式
# port: 80
# initialDelaySeconds: 60 # 初始化時(shí)間
# timeoutSeconds: 2 # 超時(shí)時(shí)間
# periodSeconds: 5 # 檢測(cè)間隔
# successThreshold: 1 # 檢查成功為2次表示就緒
# failureThreshold: 2 # 檢測(cè)失敗1次表示未就緒
# lifecycle:
# postStart: # 容器創(chuàng)建完成后執(zhí)行的指令, 可以是exec httpGet TCPSocket
# exec:
# command:
# - sh
# - -c
# - 'mkdir /data/ '
# preStop:
# httpGet:
# path: /
# port: 80
# exec:
# command:
# - sh
# - -c
# - sleep 9
restartPolicy: Always # 可選,默認(rèn)為Always,容器故障或者沒有啟動(dòng)成功,那就自動(dòng)該容器,Onfailure: 容器以不為0的狀態(tài)終止,自動(dòng)重啟該容器, Never:無論何種狀態(tài),都不會(huì)重啟
#nodeSelector: # 可選,指定Node節(jié)點(diǎn)
# region: subnet7
# imagePullSecrets: # 可選,拉取鏡像使用的secret,可以配置多個(gè)
# - name: default-dockercfg-86258
# hostNetwork: false # 可選,是否為主機(jī)模式,如是,會(huì)占用主機(jī)端口
# volumes: # 共享存儲(chǔ)卷列表
# - name: webroot # 名稱,與上述對(duì)應(yīng)
# emptyDir: {} # 掛載目錄
# #hostPath: # 掛載本機(jī)目錄
# # path: /etc/hosts
二、探針、零宕機(jī)發(fā)布
1、Pod探針
??實(shí)現(xiàn) 零宕機(jī) 上線應(yīng)用
-
StartupProbe:k8s1.16版本后新加的探測(cè)方式,用于判斷容器內(nèi)應(yīng)用程序是否已經(jīng)啟動(dòng)。如果配置了startupProbe,就會(huì)先禁止其他的探測(cè),直到它成功為止,成功后將不在進(jìn)行探測(cè)。
-
LivenessProbe:用于探測(cè)容器是否運(yùn)行,如果探測(cè)失敗,kubelet會(huì)根據(jù)配置的重啟策略進(jìn)行相應(yīng)的處理。若沒有配置該探針,默認(rèn)就是success。
-
ReadinessProbe:一般用于探測(cè)容器內(nèi)的程序是否健康,它的返回值如果為success,那么久代表這個(gè)容器已經(jīng)完成啟動(dòng),并且程序已經(jīng)是可以接受流量的狀態(tài)。
2、Pod探針的檢測(cè)方式
-
ExecAction:在容器內(nèi)執(zhí)行一個(gè)命令,如果返回值為0,則認(rèn)為容器健康。
livenessProbe:
exec:
command:
- pgrep
- nginx
-
TCPSocketAction:通過TCP連接檢查容器內(nèi)的端口是否是通的,如果是通的就認(rèn)為容器健康。
livenessProbe:
tcpSocket:
port: 80
-
HTTPGetAction:通過應(yīng)用程序暴露的API地址來檢查程序是否是正常的,如果狀態(tài)碼為200~400之間,則認(rèn)為容器健康。
linvenessProbe:
httpGet:
path: /index.html
port: 80
-
在公司,開發(fā)人員需要暴露該服務(wù)的兩個(gè)健康檢查API接口,如果測(cè)試兩個(gè)API接口通,代表容器正常運(yùn)行,不會(huì)去誤停容器。
3、探針檢查參數(shù)配置
探針的參數(shù)
-
initialDelaySeconds: 3
-
容器的初始化時(shí)長(zhǎng),用于容器中的服務(wù)初始化時(shí)間較長(zhǎng)的場(chǎng)景
-
合理使用初始化時(shí)長(zhǎng),避免容器中的應(yīng)用應(yīng)初始化時(shí)長(zhǎng)被探針檢測(cè)失敗
-
-
timeoutSeconds: 2
-
超時(shí)時(shí)長(zhǎng),檢測(cè)一個(gè)容器中的服務(wù),超時(shí)2秒,認(rèn)定檢測(cè)失敗
-
-
periodSeconds: 2
-
當(dāng)檢測(cè)失敗后,每隔 2 秒檢測(cè)一次
-
-
successThreshold: 1
-
檢測(cè)成功的次數(shù),檢測(cè)1次成功認(rèn)定該容器ready
-
-
failureThreshold: 2
-
檢測(cè)失敗的次數(shù),有兩次檢測(cè)失敗,認(rèn)定該容器 NotReady
-
檢測(cè)失敗的重啟時(shí)長(zhǎng)
-
容器初始化檢測(cè)失敗的時(shí)長(zhǎng),唯一的區(qū)別就是加上容器初始化時(shí)長(zhǎng)
-
{ ( timeoutSecounds + periodSeconds ) * failureThreshold } + initialDelaySeconds
-
{ (2+2) * 2} + 3 = 11s
-
-
容器啟動(dòng)之后檢測(cè)的方式
-
( timeoutSecounds + periodSeconds ) * failureThreshold
-
{(2+2) * 2 = 8s
-
初始化時(shí)間,不建議設(shè)置太長(zhǎng),滾動(dòng)發(fā)布受影響 ? # initialDelaySecond: 60 ? 超時(shí)時(shí)間,命令去GET頁面的超時(shí)時(shí)間 ? # timeoutSeconds: 2 ? 檢測(cè)間隔,每5秒檢測(cè)一次 ? # periodSeconds: 5 ? 檢查成功為1次表示就緒,檢測(cè)失敗2次表示未就緒 ? ? # successThreshold: 1 # failureThreshold: 2 檢測(cè)失敗的重啟時(shí)間:(2+5)* 2 = 14 s 所以檢測(cè)失敗次數(shù)不建議設(shè)置太大
Prestop:先去請(qǐng)求eureka接口,把自己的IP地址和端口號(hào),進(jìn)行下線,eureka從注冊(cè)表中刪除該應(yīng)用的IP地址。然后容器進(jìn)行sleep 90;kill pgrep java
??注意:
在生產(chǎn)環(huán)境中,一定要合理設(shè)置探針檢查的參數(shù)
假如一個(gè)Java程序的初始化時(shí)間為90s,我們沒有合理設(shè)置探測(cè)參數(shù),這樣會(huì)造成,初始化時(shí)間沒有給到,后面的檢查又失敗,失敗后Pod又被kubelet干掉,又重啟,重啟之后又初始化,無限循環(huán),這樣對(duì)業(yè)務(wù)造成的影響非常大
所以就有新的一種探針模式的增加 --> startupProbe
4、startupProbe
原理:在1.16+版本后,為了防止程序的初始化時(shí)間的過長(zhǎng),導(dǎo)致的Pod被檢測(cè)失敗與無限次的重啟,設(shè)置startupProbe后,程序會(huì)在初始化時(shí),先進(jìn)行startupProbe的檢測(cè),檢測(cè)期間會(huì)將其他的兩種檢測(cè)方式進(jìn)行禁用。只執(zhí)行一次,自動(dòng)退出。
4.1、進(jìn)行測(cè)試
[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml
apiVersion: v1 # 必選,API的版本號(hào)
kind: Pod # 必選,類型Pod
metadata: # 必選,元數(shù)據(jù)
name: nginx # 必選,符合RFC 1035規(guī)范的Pod名稱
# namespace: default # 可選,Pod所在的命名空間,不指定默認(rèn)為default,可以使用-n 指定namespace
labels: # 可選,標(biāo)簽選擇器,一般用于過濾和區(qū)分Pod,根據(jù)業(yè)務(wù)自定義
app: nginx
role: frontend # 可以寫多個(gè)
annotations: # 可選,注釋列表,可以寫多個(gè)
app: nginx1.19 #可以注釋一些 Nginx版本
spec: # 必選,用于定義容器的詳細(xì)信息
nodeSelector:
kubernetes.io/hostname: k8s-node01
containers: # 必選,容器列表
- name: nginx # 必選,符合RFC 1035規(guī)范的容器名稱
image: daocloud.io/library/nginx:latest # 必選,容器所用的鏡像的地址
imagePullPolicy: IfNotPresent # 可選,鏡像拉取策略, IfNotPresent: 如果宿主機(jī)有這個(gè)鏡像,那就不需要拉取了. Always: 總是拉取, Never: 不管是否存儲(chǔ)都不拉去
command: # 可選,容器啟動(dòng)執(zhí)行的命令 ENTRYPOINT, arg --> cmd
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可選,容器的工作目錄
ports: # 可選,容器需要暴露的端口號(hào)列表
- name: http # 端口名稱
containerPort: 80 # 端口號(hào)
protocol: TCP # 端口協(xié)議,默認(rèn)TCP
env: # 可選,環(huán)境變量配置列表
- name: TZ # 變量名
value: Asia/Shanghai # 變量的值
- name: LANG
value: en_US.utf8
startupProbe: # 可選,檢測(cè)容器內(nèi)進(jìn)程是否完成啟動(dòng)。注意三種檢查方式同時(shí)只能使用一種。
httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
path: /api/successStart # 檢查路徑
port: 80
restartPolicy: Always # 可選,默認(rèn)為Always,容器故障或者沒有啟動(dòng)成功,那就自動(dòng)該容器,Onfailure: 容器以不為0的狀態(tài)終止,自動(dòng)重啟該容器, Never:無論何種狀態(tài),都不會(huì)重啟
?
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
?
[root@k8s-master01 k8s-day01]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 9s
?
[root@k8s-master01 k8s-day01]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 2 3m
? # 重啟2次了
#可以看,nginx的Pod并未ready,一直在重啟
4.2、解析報(bào)錯(cuò)信息
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Events"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m38s default-scheduler Successfully assigned default/nginx to k8s-node01
Normal Pulled 3m56s (x4 over 7m38s) kubelet Container image "daocloud.io/library/nginx:latest" already present on machine
Normal Created 3m56s (x4 over 7m38s) kubelet Created container nginx
Normal Started 3m55s (x4 over 7m38s) kubelet Started container nginx
Warning Unhealthy 3m55s (x10 over 7m35s) kubelet Startup probe failed: HTTP probe failed with statuscode: 404 # 注意看這里,探針檢測(cè)失敗
Normal Killing 2m35s (x4 over 6m32s) kubelet Container nginx failed startup probe, will be restarted
??注意:從報(bào)錯(cuò)的信息看,HTTP probe 檢測(cè)失敗,主要是因?yàn)?"path: /api/successStart",nginx網(wǎng)站并沒有/api/successStart該路徑, 我們可以加入 TcpSocker 對(duì)nginx進(jìn)行Tcp方面的探測(cè)
4.3、進(jìn)行優(yōu)化,添加 TcpSocker
[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml
#進(jìn)行注釋與添加
startupProbe: # 可選,檢測(cè)容器內(nèi)進(jìn)程是否完成啟動(dòng)。注意三種檢查方式同時(shí)只能使用一種。
# httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
# path: /api/successStart # 檢查路徑
# port: 80
tcpSocket:
port: 80
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
?
[root@k8s-master01 k8s-day01]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 2m14s
?
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "^Event"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m24s default-scheduler Successfully assigned default/nginx to k8s-node01
Normal Pulled 3m24s kubelet Container image "daocloud.io/library/nginx:latest" already present on machine
Normal Created 3m24s kubelet Created container nginx
Normal Started 3m24s kubelet Started container nginx
??:可以看到,Pod已經(jīng)重新恢復(fù),主要是 tcpSocket 檢測(cè) 80端口 成功,nginx默認(rèn)80端口
5、liveness
??注意:一定要使用接口級(jí)的健康檢查 /path /index.html.........,盡量少使用命令去檢查 pgrep nginx
apiVersion: v1 # 必選,API的版本號(hào)
kind: Pod # 必選,類型Pod
metadata: # 必選,元數(shù)據(jù)
name: nginx # 必選,符合RFC 1035規(guī)范的Pod名稱
# namespace: default # 可選,Pod所在的命名空間,不指定默認(rèn)為default,可以使用-n 指定namespace
labels: # 可選,標(biāo)簽選擇器,一般用于過濾和區(qū)分Pod,根據(jù)業(yè)務(wù)自定義
app: nginx
role: frontend # 可以寫多個(gè)
annotations: # 可選,注釋列表,可以寫多個(gè)
app: nginx1.21 #可以注釋一些 Nginx版本
spec: # 必選,用于定義容器的詳細(xì)信息
nodeSelector:
kubernetes.io/hostname: k8s-node01
containers: # 必選,容器列表
- name: nginx # 必選,符合RFC 1035規(guī)范的容器名稱
image: daocloud.io/library/nginx:latest # 必選,容器所用的鏡像的地址
imagePullPolicy: IfNotPresent # 可選,鏡像拉取策略, IfNotPresent: 如果宿主機(jī)有這個(gè)鏡像,那就不需要拉取了. Always: 總是拉取, Never: 不管是否存儲(chǔ)都不拉去
command: # 可選,容器啟動(dòng)執(zhí)行的命令 ENTRYPOINT, arg --> cmd
- nginx
- -g
- "daemon off;"
ports: # 可選,容器需要暴露的端口號(hào)列表
- name: http # 端口名稱
containerPort: 80 # 端口號(hào)
protocol: TCP # 端口協(xié)議,默認(rèn)TCP
env: # 可選,環(huán)境變量配置列表
- name: TZ # 變量名
value: Asia/Shanghai # 變量的值
- name: LANG
value: en_US.utf8
startupProbe: # 可選,檢測(cè)容器內(nèi)進(jìn)程是否完成啟動(dòng)。注意三種檢查方式同時(shí)只能使用一種。
# httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
# path: /api/successStart # 檢查路徑
# port: 80
tcpSocket:
port: 80
readinessProbe: # 可選,健康檢查。注意三種檢查方式同時(shí)只能使用一種。
httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
path: / # 檢查路徑
port: 80 # 監(jiān)控端口
#-------------------------------------------------
livenessProbe: # 可選,健康檢查
#exec: # 執(zhí)行容器命令檢測(cè)方式
#command:
#- cat
#- /health
httpGet: # httpGet檢測(cè)方式
path: /index.html # 檢查路徑
port: 80
# httpHeaders: # 檢查的請(qǐng)求頭
# - name: end-user
# value: Jason
#-------------------------------------------------
initialDelaySeconds: 3 # 初始化時(shí)間
timeoutSeconds: 2 # 超時(shí)時(shí)間
periodSeconds: 2 # 檢測(cè)間隔
successThreshold: 1 # 檢查成功為2次表示就緒
failureThreshold: 2 # 檢測(cè)失敗1次表示未就緒
restartPolicy: Always
6、readiness
-
readiness 美 /'r?d?n?s/ 英 /'red?n?s/ n. 敏捷,迅速;準(zhǔn)備就緒;愿意
解析:自定義 監(jiān)控項(xiàng)對(duì)容器啟動(dòng)時(shí)的監(jiān)控,如果監(jiān)測(cè)失敗,不會(huì)去重啟容器,不會(huì)停止容器
只會(huì) 限制 服務(wù)的 進(jìn)出流量,用戶只能通過 Pod-IP進(jìn)行訪問,無法從Cluster-IP、NodePort-IP進(jìn)行訪問。
1、報(bào)錯(cuò)演示
[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml
apiVersion: v1 # 必選,API的版本號(hào)
kind: Pod # 必選,類型Pod
metadata: # 必選,元數(shù)據(jù)
name: nginx # 必選,符合RFC 1035規(guī)范的Pod名稱
# namespace: default # 可選,Pod所在的命名空間,不指定默認(rèn)為default,可以使用-n 指定namespace
labels: # 可選,標(biāo)簽選擇器,一般用于過濾和區(qū)分Pod,根據(jù)業(yè)務(wù)自定義
app: nginx
role: frontend # 可以寫多個(gè)
annotations: # 可選,注釋列表,可以寫多個(gè)
app: nginx1.21 #可以注釋一些 Nginx版本
spec: # 必選,用于定義容器的詳細(xì)信息
nodeSelector:
kubernetes.io/hostname: k8s-node01
containers: # 必選,容器列表
- name: nginx # 必選,符合RFC 1035規(guī)范的容器名稱
image: daocloud.io/library/nginx:latest # 必選,容器所用的鏡像的地址
imagePullPolicy: IfNotPresent # 可選,鏡像拉取策略, IfNotPresent: 如果宿主機(jī)有這個(gè)鏡像,那就不需要拉取了. Always: 總是拉取, Never: 不管是否存儲(chǔ)都不拉去
command: # 可選,容器啟動(dòng)執(zhí)行的命令 ENTRYPOINT, arg --> cmd
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可選,容器的工作目錄
ports: # 可選,容器需要暴露的端口號(hào)列表
- name: http # 端口名稱
containerPort: 80 # 端口號(hào)
protocol: TCP # 端口協(xié)議,默認(rèn)TCP
env: # 可選,環(huán)境變量配置列表
- name: TZ # 變量名
value: Asia/Shanghai # 變量的值
- name: LANG
value: en_US.utf8
#"---------------------------------------------------------------------------"
readinessProbe: # 可選,健康檢查。注意三種檢查方式同時(shí)只能使用一種。
httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
path: /a.html # 檢查路徑,該路徑不存在
port: 80 # 監(jiān)控端口
#"---------------------------------------------------------------------------"
initialDelaySeconds: 3 # 初始化時(shí)間
timeoutSeconds: 2 # 超時(shí)時(shí)間
periodSeconds: 2 # 檢測(cè)間隔
successThreshold: 1 # 檢查成功為2次表示就緒
failureThreshold: 2 # 檢測(cè)失敗1次表示未就緒
preStop: #容器關(guān)閉之前執(zhí)行的命令
restartPolicy: Always
[root@k8s-master01 k8s-day01]# vim nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80 # 映射端口,nginx服務(wù)為80端口,如果mysql就3306
nodePort: 30080 # 映射到外部的端口,可以在外部瀏覽器訪問 Node-IP:30080
- name: https # SSL
port: 443
targetPort: 443
nodePort: 30443
selector: # 上方的Nginx設(shè)置的 Labels
app: nginx
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
[root@k8s-master01 k8s-day01]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 0/1 Running 0 5m7s 172.17.125.11 k8s-node01
[root@k8s-master01 k8s-day01]# kubectl apply -f nginx-svc.yaml
service/nginx-svc configured
[root@k8s-master01 k8s-day01]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d20h
nginx-svc NodePort 10.106.106.114 <none> 80:30080/TCP,443:30443/TCP 3d15h
# 10.106.106.114:80 -> 192.168.178.54:30080
(部署Pod的Node-IP)
查看報(bào)錯(cuò)日志信息:
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Event"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m24s default-scheduler Successfully assigned default/nginx to k8s-node01
Normal Pulled 3m24s kubelet Container image "daocloud.io/library/nginx:latest" already present on machine
Normal Created 3m24s kubelet Created container nginx
Normal Started 3m24s kubelet Started container nginx
Warning Unhealthy 2m39s (x22 over 3m21s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
2、使用容器內(nèi)部進(jìn)行訪問,可以看到訪問成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I localhost:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:07:30 GMT
# curl -I 172.17.125.11:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:15:05 GMT
3、使用外部、集群IP進(jìn)行訪問進(jìn)行訪問,訪問失敗,進(jìn)出流量限制:
[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
curl: (7) Failed connect to 10.106.106.114:80; Connection refused
[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:30080
curl: (7) Failed connect to 192.168.178.54:30080; Connection refused
2、正確演示
#找到并修改
readinessProbe:
httpGet:
path: /index.html # 修改此處即可
port: 80
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Event"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m24s default-scheduler Successfully assigned default/nginx to k8s-node01
Normal Pulled 3m24s kubelet Container image "daocloud.io/library/nginx:latest" already present on machine
Normal Created 3m24s kubelet Created container nginx
Normal Started 3m24s kubelet Started container nginx
Warning Unhealthy 2m39s (x22 over 3m21s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
2、使用容器內(nèi)部進(jìn)行訪問,可以看到訪問成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I localhost:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:07:30 GMT
# curl -I 172.17.125.11:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:15:05 GMT
3、使用外部、集群IP進(jìn)行訪問進(jìn)行訪問,訪問失敗,進(jìn)出流量限制:
[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
curl: (7) Failed connect to 10.106.106.114:80; Connection refused
[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:80
curl: (7) Failed connect to 192.168.178.54:80; Connection refused
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
[root@k8s-master01 k8s-day01]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 18s 172.17.125.12 k8s-node01
1、使用容器內(nèi)部訪問,訪問成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I 172.17.125.12:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:40:58 GMT
2、使用容器Cluster-IP、NodePort訪問,成功:
[root@k8s-master01 k8s-day01]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d20h
nginx-svc NodePort 10.106.106.114 <none> 80:30080/TCP,443:30443/TCP 3d15h
[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:42:17 GMT
[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:30080
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:42:37 GMT
7、Pod 優(yōu)雅關(guān)閉
??:零宕機(jī)下線應(yīng)用
-
合理使用 proStop,進(jìn)行容器退出時(shí)執(zhí)行的命令
1、Pod優(yōu)雅關(guān)閉
模式:
-
postStart
-
容器在啟動(dòng)之前做的一系列指定操作,比如 提前創(chuàng)建 目錄、文件、執(zhí)行腳本等。
-
-
preStop
-
容器關(guān)閉之后,執(zhí)行的命令
-
通常我們會(huì)使用該參數(shù)進(jìn)行 Pod 的優(yōu)雅關(guān)閉,實(shí)現(xiàn) 零宕機(jī) 下線服務(wù)
-
spec:
terminationGracePeriods: 90s
containers:
lifecycle:
preStop: #容器關(guān)閉之前執(zhí)行的命令
exec:
command:
- sh
- -c
- sleep 90;kill `pgrep nginx`
-
可以看到下方的 yaml 配置 ,nginx 在退出時(shí),執(zhí)行了睡眠操作,保證容器中的服務(wù) 有足夠的時(shí)間進(jìn)行下線操作(處理服務(wù)關(guān)閉之前,接收的服務(wù)未進(jìn)行處理,等待處理完成后,關(guān)閉服務(wù),保證數(shù)據(jù)的完整性)
??注意:
-
我們往往會(huì)忽視一個(gè)參數(shù),terminationGracePeriodSeconds (容器優(yōu)雅的關(guān)閉的時(shí)間間隔)
-
這參數(shù)默認(rèn)為30秒,就算你不設(shè)置, terminationGracePeriodSeconds: 30
?再次注意:
-
如果你想使 容器 進(jìn)行 90s 的優(yōu)雅關(guān)閉時(shí)長(zhǎng),那你的參數(shù)應(yīng)該為 terminationGracePeriodSeconds: 90
-
加入你設(shè)置的 sleep 時(shí)長(zhǎng)為 90s ,你的參數(shù)為 terminationGracePeriodSeconds: 30,那肯定容器只等待30s左右就會(huì)關(guān)閉,你應(yīng)該設(shè)置參數(shù)為 50s,才能保證 sleep 50 運(yùn)行成功
-
-
所以我們?cè)谶M(jìn)行容器優(yōu)雅下線時(shí),要合理使用 preStop 與 該參數(shù)
2、效果演示
1??默認(rèn)情況:terminationGracePeriodSeconds: 30文章來源:http://www.zghlxwxcb.cn/news/detail-782308.html
apiVersion: v1 # 必選,API的版本號(hào)
kind: Pod # 必選,類型Pod
metadata: # 必選,元數(shù)據(jù)
name: nginx # 必選,符合RFC 1035規(guī)范的Pod名稱
# namespace: default # 可選,Pod所在的命名空間,不指定默認(rèn)為default,可以使用-n 指定namespace
labels: # 可選,標(biāo)簽選擇器,一般用于過濾和區(qū)分Pod,根據(jù)業(yè)務(wù)自定義
app: nginx
role: frontend # 可以寫多個(gè)
annotations: # 可選,注釋列表,可以寫多個(gè)
app: nginx1.21 #可以注釋一些 Nginx版本
spec: # 必選,用于定義容器的詳細(xì)信息
nodeSelector:
kubernetes.io/hostname: k8s-node01
containers: # 必選,容器列表
- name: nginx # 必選,符合RFC 1035規(guī)范的容器名稱
image: daocloud.io/library/nginx:latest # 必選,容器所用的鏡像的地址
imagePullPolicy: IfNotPresent # 可選,鏡像拉取策略, IfNotPresent: 如果宿主機(jī)有這個(gè)鏡像,那就不需要拉取了. Always: 總是拉取, Never: 不管是否存儲(chǔ)都不拉去
command: # 可選,容器啟動(dòng)執(zhí)行的命令 ENTRYPOINT, arg --> cmd
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可選,容器的工作目錄
ports: # 可選,容器需要暴露的端口號(hào)列表
- name: http # 端口名稱
containerPort: 80 # 端口號(hào)
protocol: TCP # 端口協(xié)議,默認(rèn)TCP
env: # 可選,環(huán)境變量配置列表
- name: TZ # 變量名
value: Asia/Shanghai # 變量的值
- name: LANG
value: en_US.utf8
startupProbe: # 可選,檢測(cè)容器內(nèi)進(jìn)程是否完成啟動(dòng)。注意三種檢查方式同時(shí)只能使用一種。
tcpSocket:
port: 80
readinessProbe: # 可選,健康檢查。注意三種檢查方式同時(shí)只能使用一種。
httpGet: # httpGet檢測(cè)方式,生產(chǎn)環(huán)境建議使用httpGet實(shí)現(xiàn)接口級(jí)健康檢查,健康檢查由應(yīng)用程序提供。
path: / # 檢查路徑
port: 80 # 監(jiān)控端口
livenessProbe: # 可選,健康檢查
httpGet: # httpGet檢測(cè)方式
path: /index.html # 檢查路徑
port: 80
initialDelaySeconds: 3 # 初始化時(shí)間
timeoutSeconds: 2 # 超時(shí)時(shí)間
periodSeconds: 2 # 檢測(cè)間隔
successThreshold: 1 # 檢查成功為2次表示就緒
failureThreshold: 2 # 檢測(cè)失敗1次表示未就緒
lifecycle:
preStop: #容器關(guān)閉之前執(zhí)行的命令
exec:
command:
- sh
- -c
#"----------------------------------------------------------------------"
- sleep 90;kill `pgrep nginx` #設(shè)置 90 秒關(guān)閉 容器
#"----------------------------------------------------------------------"
restartPolicy: Always
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
[root@k8s-master01 k8s-day01]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 15s
[root@k8s-master01 k8s-day01]# time kubectl delete -f pod-Probe.yaml
pod "nginx" deleted
real 0m36.076s
user 0m0.051s
sys 0m0.031s
#這里可以看到,容器并沒有 90 秒退出,默認(rèn)的 terminationGracePeriodSeconds 為30s
2??修改:terminationGracePeriodSeconds: 90s文章來源地址http://www.zghlxwxcb.cn/news/detail-782308.html
spec: # 必選,用于定義容器的詳細(xì)信 息
nodeSelector:
kubernetes.io/hostname: k8s-node01
# "----------------------------------------------------------------------"
terminationGracePeriodSeconds: 90 #添加此行,為 90s 進(jìn)行優(yōu)雅關(guān)閉容器
# "-----------------------------------------------------------------------"
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml
pod/nginx created
[root@k8s-master01 k8s-day01]# time kubectl delete -f pod-Probe.yaml
pod "nginx" deleted
real 1m32.343s #可以看到 關(guān)閉時(shí)長(zhǎng)為 90s
user 0m0.057s
sys 0m0.022s
到了這里,關(guān)于k8s Pod簡(jiǎn)介與探針實(shí)現(xiàn)零宕機(jī)發(fā)布的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!