k8s-Pod狀態和探針
阿新 • • 發佈:2021-10-04
Pod狀態
第一階段:
Pending:
#正在建立Pod但是Pod中的容器還沒有全部被建立完成,處於此狀態的Pod應該檢查Pod依賴的儲存是否有許可權掛載、映象是否可以下載、排程是否正常等。
Failed
#Pod中有容器啟動失敗而導致pod工作異常。檢查事件
Unknown
#由於某種原因無法獲得pod的當前狀態,通常是由於與pod所在的node節點通訊錯誤。
Succeeded
#Pod中的所有容器都被成功終止即pod裡所有的containers均已terminated。
第二階段:
Unschedulable: #Pod不能被排程,kube-scheduler沒有匹配到合適的node節點 PodScheduled #pod正處於排程中,在kube-scheduler剛開始排程的時候,還沒有將pod分配到指定的node,在篩選出合適的 節點後就會更新etcd資料,將pod分配到指定的node Initialized #所有pod中的初始化容器已經完成了 ImagePullBackOff: #Pod所在的node節點下載映象失敗 Running #Pod內部的容器已經被建立並且啟動。 Ready #表示pod中的容器已經可以提供訪問服務
範例:其他狀態
Error: #pod 啟動過程中發生錯誤 NodeLost: #Pod 所在節點失聯 Unkown: #Pod 所在節點失聯或其它未知異常 Waiting: #Pod 等待啟動 Pending: #Pod 等待被排程 Terminating: #Pod 正在被銷燬 CrashLoopBackOff:#pod,但是kubelet正在將它重啟 InvalidImageName:#node節點無法解析映象名稱導致的映象無法下載 ImageInspectError:#無法校驗映象,映象不完整導致 ErrImageNeverPull:#策略禁止拉取映象,映象中心許可權是私有等 ImagePullBackOff:#映象拉取失敗,但是正在重新拉取 RegistryUnavailable:#映象伺服器不可用,網路原因或harbor宕機 ErrImagePull:#映象拉取出錯,超時或下載被強制終止 CreateContainerConfigError:#不能建立kubelet使用的容器配置 CreateContainerError:#建立容器失敗 PreStartContainer: #執行preStart hook報錯,Pod hook(鉤子)是由 Kubernetes 管理的 kubelet 發 起的,當容器中的程序啟動前或者容器中的程序終止之前執行,比如容器建立完成後裡面的服務啟動之前可以檢查一下 依賴的其它服務是否啟動,或者容器退出之前可以把容器中的服務先通過命令停止。 PostStartHookError:#執行 postStart hook 報錯 RunContainerError:#pod執行失敗,容器中沒有初始化PID為1的守護程序等 ContainersNotInitialized:#pod沒有初始化完畢 ContainersNotReady:#pod沒有準備完畢 ContainerCreating:#pod正在建立中 PodInitializing:#pod正在初始化中 DockerDaemonNotReady:#node節點docker服務沒有啟動 NetworkPluginNotReady:#網路外掛還沒有完全啟動
探針(保證k8s中服務的可用性)
探針 是由 kubelet 對容器執行的定期診斷,以保證Pod的狀態始終處於執行狀態,要執行診斷,kubelet 呼叫由容
兩種都是檢查通過就什麼都不做
器實現的Handler(處理程式),有三種類型的處理程式:
ExecAction #在容器內執行指定命令,如果命令退出時返回碼為0則認為診斷成功。 TCPSocketAction #對指定埠上的容器的IP地址進行TCP檢查,如果埠開啟,則診斷被認為是成功的。 HTTPGetAction #對指定的埠和路徑上的容器的IP地址執行HTTPGet請求,如果響應的狀態碼大於等於200且小於 400,則診斷被認為是成功的。
每次探測都將獲得以下三種結果之一:
成功:容器通過了診斷。
失敗:容器未通過診斷。
未知:診斷失敗,因此不會採取任何行動。
探針型別:
livenessProbe(檢查不通過,就重啟;基於映象還原)
#存活探針,檢測容器容器是否正在執行,如果存活探測失敗,則kubelet會殺死容器,並且容器將受到其重啟策略的影響,如果容器不提供存活探針,則預設狀態為 Success,livenessProbe用於控制是否重啟pod。
readinessProbe(檢查不通過,不會新增到ep,反之)
#就緒探針,如果就緒探測失敗,端點控制器將從與Pod匹配的所有Service的端點中刪除該Pod的IP地址,初始延遲之前的就緒狀態預設為Failure(失敗),如果容器不提供就緒探針,則預設狀態為 Success,readinessProbe用於控制pod是否新增至service。
探針有很多配置欄位,可以使用這些欄位精確的控制存活和就緒檢測的行為:
initialDelaySeconds: 120
#初始化延遲時間,告訴kubelet在執行第一次探測前應該等待多少秒,預設是0秒,最小值是0
periodSeconds: 60
#探測週期間隔時間,指定了kubelet應該每多少秒秒執行一次存活探測,預設是 10 秒。最小值是 1
timeoutSeconds: 5
#單次探測超時時間,探測的超時後等待多少秒,預設值是1秒,最小值是1。
successThreshold: 1
#從失敗轉為成功的重試次數,探測器在失敗後,被視為成功的最小連續成功數,預設值是1,存活探測的這個值必須是1,最小值是 1。
failureThreshold: 3
#從成功轉為失敗的重試次數,當Pod啟動了並且探測到失敗,Kubernetes的重試次數,存活探測情況下的放棄就意味著重新啟動容器,就緒探測情況下的放棄Pod 會被打上未就緒的標籤,預設值是3,最小值是1。
HTTP 探測器可以在 httpGet 上配置額外的欄位:
host:
#連線使用的主機名,預設是Pod的 IP,也可以在HTTP頭中設定 “Host” 來代替。
scheme: http
#用於設定連線主機的方式(HTTP 還是 HTTPS),預設是 HTTP。
path: /monitor/index.html
#訪問 HTTP 服務的路徑。
httpHeaders:
#請求中自定義的 HTTP 頭,HTTP 頭欄位允許重複。
port: 80
#訪問容器的埠號或者埠名,如果數字必須在 1 ~ 65535 之間。
livenessProbe和readinessProbe的對比:
配置引數一樣
livenessProbe #連續探測失敗會重啟、重建pod,readinessProbe不會執行重啟或者重建Pod操作
livenessProbe #連續檢測指定次數失敗後會將容器置於(Crash Loop BackOff)且不可用,readinessProbe不會
readinessProbe #連續探測失敗會從service的endpointd中刪除該Pod,livenessProbe不具備此功能,但是會將容器掛起livenessProbe
livenessProbe使用者控制是否重啟pod,readinessProbe用於控制pod是否新增至service
建議:
兩個探針都配置
這裡都是存活探針的案例
HTTP探針示例:(這是正確的)
[root@k8s-server1 case2]# cat case1.yaml
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: ng-deploy-80
#matchExpressions:
# - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: harbor.longxuan.net/n520/nginx:1.18.0
ports:
- containerPort: 80
#readinessProbe:
livenessProbe:
httpGet:
#path: /montic/montic.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy-80
spec:
ports:
- name: http
port: 86
targetPort: 80
nodePort: 30025
protocol: TCP
type: NodePort
selector:
app: ng-deploy-80
執行
[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66
deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged
當開啟不存在的url時,pod將會一直重啟
TCP探針示例
建立(正確的)
[root@k8s-server1 case2]# cat case2.yaml
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: ng-deploy-80
#matchExpressions:
# - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: harbor.longxuan.net/n520/nginx:1.18.0
ports:
- containerPort: 80
#readinessProbe:
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy-80
spec:
ports:
- name: http
port: 86
targetPort: 80
nodePort: 30026
protocol: TCP
type: NodePort
selector:
app: ng-deploy-80
執行
[root@k8s-server1 case2]# kubectl apply -f case2.yaml -n linux66
deployment.apps/nginx-deployment created
service/ng-deploy-80 created
當yaml檔案寫錯埠,pod就會被一直重啟,同時服務也訪問不了
[root@k8s-server1 case2]# kubectl get pod -n linux66
NAME READY STATUS RESTARTS AGE
0 41h
nginx-deployment-69bd984878-nttnp 0/1 CrashLoopBackOff 3 60s
ExecAction探針:
可以基於指定的命令對Pod進行特定的狀態檢查。
# 這是正確的
[root@k8s-server1 case2]# cat case3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis-deploy-6379
template:
metadata:
labels:
app: redis-deploy-6379
spec:
containers:
- name: redis-deploy-6379
image: harbor.longxuan.net/n520/redis:v1
ports:
- containerPort: 80
livenessProbe:
#readinessProbe:
exec:
command:
#- /app/redis/bin/redis-cli
- /usr/local/bin/redis-cli
- quit
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: redis-deploy-6379
spec:
ports:
- name: http
port: 6379
targetPort: 6379
nodePort: 30679
protocol: TCP
type: NodePort
selector:
app: redis-deploy-6379
執行
[root@k8s-server1 case2]# kubectl apply -f case3.yaml -n linux66
deployment.apps/redis-deployment created
service/redis-deploy-6379 created
如果是錯誤的,pod就會重啟三次,但名字不會變,如果埠檢測連續超過指定的三次都沒有通過,則Pod狀態如下:
[root@k8s-server1 case2]# kubectl get pod -n linux66
NAME READY STATUS RESTARTS AGE
redis-deployment-574f795dcd-gx9v4 0/1 CrashLoopBackOff 3 109s
就緒探針
當路徑不存在時,檢視ep(用來記錄一個service對應的所有pod的訪問地址。)是不會新增進去,同時pod是不會重啟
# 這是正確的
[root@k8s-server1 case2]# cat case1.yaml
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: ng-deploy-80
#matchExpressions:
# - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: harbor.longxuan.net/n520/nginx:1.18.0
ports:
- containerPort: 80
readinessProbe:
#livenessProbe:
httpGet:
#path: /montic/montic.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy-80
spec:
ports:
- name: http
port: 86
targetPort: 80
nodePort: 30025
protocol: TCP
type: NodePort
selector:
app: ng-deploy-80
執行
[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66
deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged
檢視ep
[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME ENDPOINTS AGE
linux66-nginx-service 10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more... 42h
ng-deploy-80 10.100.5.15:80 36m
redis-deploy-6379 16m
不正確的,檢視ep結果如下:
[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME ENDPOINTS AGE
linux66-nginx-service 10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more... 42h
ng-deploy-80 3s
redis-deploy-6379 18m
組合使用
[root@k8s-server1 case2]# cat case1.yaml
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels: #rs or deployment
app: ng-deploy-80
#matchExpressions:
# - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: harbor.longxuan.net/n520/nginx:1.18.0
ports:
- containerPort: 80
readinessProbe:
httpGet:
#path: /montic/montic.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
#path: /montic/montic.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy-80
spec:
ports:
- name: http
port: 86
targetPort: 80
nodePort: 30025
protocol: TCP
type: NodePort
selector:
app: ng-deploy-80
執行
[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66
deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged
當路徑不存在時,檢視ep如下資訊
[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME ENDPOINTS AGE
linux66-nginx-service 10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more... 42h
ng-deploy-80 10.100.2.14:80 8m51s
redis-deploy-6379 26m
檢視pod時,資訊如下,探測到失敗就已經重啟
[root@k8s-server1 case2]# kubectl get pod -n linux66
nginx-deployment-5454b65b59-nxxjz 1/1 Running 1 2m37s
再檢視ep,如下資訊
[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME ENDPOINTS AGE
linux66-nginx-service 10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more... 42h
ng-deploy-80 10.100.2.14:80,10.100.5.17:80 9m7s
redis-deploy-6379 27m
Pod重啟策略:
k8s在Pod出現異常的時候會自動將Pod重啟以恢復Pod中的服務。
restartPolicy:
Always:當容器異常時,k8s自動重啟該容器,ReplicationController/Replicaset/Deployment。
OnFailure:當容器失敗時(容器停止執行且退出碼不為0),k8s自動重啟該容器。
Never:不論容器執行狀態如何都不會重啟該容器,Job或CronJob。
映象拉取策略:
imagePullPolicy: IfNotPresent #node節點沒有此映象就去指定的映象倉庫拉取,node有就使用node本地映象。
imagePullPolicy: Always #每次重建pod都會重新拉取映象
imagePullPolicy: Never #從不到映象中心拉取映象,只使用本地映象