文章目录
-
- 调度约束方法
-
- Pod调度流程
- pod生命周期
-
- pod生命周期流程
-
- 容器启动
- 容器终止
- 容器重启策略回顾
- 容器生命周期
- 健康检查
-
- 健康检查方式
- Probe探测方式
- 探测方式举例
-
- liveness-exec案例
- liveness-httpget案例
- readiness案例
- readiness+liveness综合案例
调度约束方法
- 默认情况下,一个pod在那个节点运行完全是由Scheduler组件的相关算法来完成的,这个过程不受人工干预,在实际使用场景中不一定符合我们的使用场景
- 为了解决这个问题,我们可以使用约束,将pod调用到指定的Node节点上面,常用的方式有以下两个
nodeName
- 用于将Pod调用到指定的Node上
- 编写yaml资源清单文件,将spec.nodeName指定成想要调度的节点
apiVersion: v1
kind: Pod
metadata:
name: nainx
spec:
nodeSelector: master1
containers:
- name: nginx
image: nginx
nodeSelector
- 用于将pod调用到匹配label的node上
- 编写yaml资源清单文件,将spec.nodeName指定成想要调度的节点
apiVersion: v1
kind: Pod
metadata:
name: nainx
spec:
nodeName:
env: dev
containers:
- name: nginx
image: nginx
Pod调度流程
- 通过 kubectl 命令应用资源清单文件,向APIServer发起一个创建Pod的请求
- APIServer收到创建pod请求之后,生成一个创建pod的资源清单文件
- APIServer 将资源清单文件中的数据写入到ETCD中
- Scheduler 组件,启动一个
watch apiServer
,获取spec.nodeName为空的pod,即判断pod.spec.Node == null? 若为null,表示这个Pod请求是新的,需要创建,因此先进行调度计算(共计2步:1、过滤不满足条件的,2、选择优先级高的),找到合适的node,然后将信息在etcd数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点)
- kubelet 通过watch etcd数据库(即不停地看etcd中的记录),发现有新的Node出现,如果这条记录中的Node与所在节点编号相同,即这个Pod由scheduler分配给自己,则调用node中的Container Runtime,进而创建container,并将创建后的结果返回到给api server用于更新etcd数据库中数据状态。
pod生命周期
生命周期概述
- pod从创建到终止的过程就是Pod的生命周期,在pod中主要有这两个情况
- pod启动后会一直存在,知道手动删除才会终止,常见于后台进程服务,如mysqld,hhtpd
- 执行完具体的计算任务之后就会终止,如定时任务等
pod生命周期流程
容器启动
- pod容器启动之前,会有初始化容器(initContainer)会先进行环境的初始化
- 初始化后主容器(main container)开始启动
- 主容器启动之后会有一个
post start
之类的(启动后钩子函数)操作
post start
执行之后就开始进行健康检查
容器终止
- 可以在容器终止之前,设置
pre stop
操作(终止前钩子函数)
- 当出现特殊情况不能正常销毁pod时,大概会等待30秒之后强制终止
- 终止后容器是否能重启,取决于容器重启策略
容器重启策略回顾
- Always:表示容器挂了总是重启,这是默认策略
- OnFailures:表示容器状态为错误时才重启,也就是容器正常终止时不重启
- Never:表示容器挂了不予重启
- 对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费资源的。所以Always重启策略是这么做的:第一次容器挂了立即重启,如果再挂了就要延时10s重启,第三次挂了就等20s重启… 依次类推
容器生命周期
apiVersion: v1
kind: Pod
metadata:
name: post-start-test
spec:
containers:
- name: poststart
image: nginx
lifecycle:
postStart:
exec:
command: ["mkdir", "-p", "/usr/share/nginx/post_start_test"]
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 1000000000"]
kubectl exec -it post-start-test -- ls -l /usr/share/nginx/
total 8
drwxr-xr-x 2 root root 4096 Dec 29 2021 html
drwxr-xr-x 2 root root 4096 Aug 22 05:09 post_start_test
kubectl delete -f lifecycle.yaml
pod "post-start-test" deleted
健康检查
健康检查方式
- Liveness Probe(存活状态探测):指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定。如果容器不提供存活探针, 则默认状态为
Success
。
- readiness Probe(就绪型探测):指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为
Failure
。 如果容器不提供就绪态探针,则默认状态为 Success
。注:检查后不健康,将容器设置为Notready;如果使用service来访问,流量不会转发给此种状态的pod
- startup Probe(启动探测):指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,
kubelet
将杀死容器,而容器依其进行重启。 如果容器没有提供启动探测,则默认状态为 Success
。
Probe探测方式
- Exec:执行命令
- HttpURL:http请求某一url路径
- TCP:TCP链接某一个端口
- gRPC:使用grpc执行一个远程过程调用,目标应该实现grpc的健康检查,如果响应状态为
SERVING
,则认为诊断成功。gRPC 探针是一个 alpha 特性,只有在你启用了 GRPCContainerProbe
特性门控时才能使用。
探测方式举例
liveness-exec案例
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- touch /tmp/health; sleep 30; rm -rf /tmp/health; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/health
initialDelaySeconds: 5
periodSeconds: 5
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 83s default-scheduler Successfully assigned default/liveness-exec to docker-desktop
Normal Pulling 82s kubelet Pulling image "busybox"
Normal Pulled 65s kubelet Successfully pulled image "busybox" in 17.1068002s
Normal Created 65s kubelet Created container liveness
Normal Started 65s kubelet Started container liveness
Warning Unhealthy 23s (x3 over 33s) kubelet Liveness probe failed: cat: can't open '/tmp/health': No such file or directory
Normal Killing 23s kubelet Container liveness failed liveness probe, will be restarted
liveness-httpget案例
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /indexhtml
initialDelaySeconds: 5
periodSeconds: 5
kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-httpget 0/1 ImagePullBackOff 0 44s
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 30s default-scheduler Successfully assigned default/liveness-httpget to docker-desktop
Normal Killing 11s kubelet Container nginx failed liveness probe, will be restarted
Normal Pulled 10s (x2 over 30s) kubelet Container image "nginx" already present on machine
Normal Created 10s (x2 over 30s) kubelet Created container nginx
Normal Started 10s (x2 over 30s) kubelet Started container nginx
Warning Unhealthy 1s (x4 over 21s) kubelet Liveness probe failed: HTTP probe
Normal Killing 9s (x2 over 29s) kubelet Container nginx failed liveness probe, will be restarted
Normal Created 8s (x3 over 48s) kubelet Created container nginx
Normal Started 8s (x3 over 48s) kubelet Started container nginx
failed with statuscode: 404
readiness案例
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget
spec:
containers:
- name: readiness
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 3
periodSeconds: 5
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m57s default-scheduler Successfully assigned default/readiness-httpget to docker-desktop
Normal Pulled 2m57s kubelet Container image "nginx" already present on machine
Normal Created 2m57s kubelet Created container readiness
Normal Started 2m57s kubelet Started container readiness
Warning Unhealthy 3s (x13 over 63s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
- 观察pod状态
readiness+liveness综合案例
apiVersion: v1
kind: Pod
metadata:
name: readiness-liveness-httpget
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 5
periodSeconds: 5
kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
- 验证