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