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 #從不到鏡像中心拉取鏡像,只使用本地鏡像