容器生命周期钩子
容器启动后触发(PostStart)
容器启动时,会执行这个钩子函数
# yaml描述文件
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
labels:
app: myapp-hook
spec:
containers:
- name: nginx-hook
image: nginx:alpine
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: [/bin/sh,-c,'echo k8s 666 >> /uuuuusr/share/nginx/html/index.html']
restartPolicy: OnFailure
# 创建资源访问测试
kubectl apply -f start-test.yaml
pod/nginx-hook created
# 查看该pod的ip地址
kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-hook 1/1 Running 0 4s 172.20.139.188 10.0.0.203 <none> <none>
# 访问测试
curl 172.20.139.188
k8s 666
# 主动修改错误的钩子命令,演示,钩子,命令执行失败的话,会一直重启容器
command: [/bin/sh,-c,'echo k8s 666 >> /uuuuuuusr/share/nginx/html/index.html']
# 此时容器状态未成功运行
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hook 0/1 Completed 0 63s
重启策略 | 说明 |
---|---|
Always | 当容器失效时,由kubelet自动重启该容器 |
OnFailure | 当容器终止运行且退出码不为0时,由kubelet自动重启该容器 |
Never | 不论容器运行状态如何,kubelet都不会重启该容器 |
容器停止前触发(PreStop)
容器退出前,会执行这个钩子函数
# 创建了挂载目录,当pod删除后数据将持久化保留在宿主机上
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
labels:
app: myapp-hook
spec:
volumes:
- name: nginxlog
hostPath:
path: /nginx_log/
restartPolicy: OnFailure
containers:
- name: nginx-hook
image: nginx:alpine
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: [/bin/sh,-c,'echo k8s 666 > /usr/share/nginx/html/index.html']
preStop:
exec:
command: [/bin/sh,-c,'echo 再见! >> /var/log/nginx/prestop-test.log']
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx/
# 删除pod
kubectl delete pods nginx-hook
pod "nginx-hook" deleted
# 容器退出后,查看宿主机上的文件
cat /nginx_log/prestop-test.log
再见!
Pod健康探针
存活探针 liveness
nginx运行后,得先curl -I 确保状态码是2xx,才得知nginx这个进程是正确运行了
livenessprobe探针,cat命令执行失败,文件路径不存在,导致健康探针失败
如果存活探针失败,Kubernetes 将会根据定义的重启策略自动重启容器,以尝试恢复应用程序的健康状态
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
labels:
app: myapp-hook
spec:
volumes:
- name: nginx-html
hostPath:
path: /nginx-html
restartPolicy: OnFailure
containers:
- name: nginx-hook
image: nginx:alpine
ports:
- containerPort: 80
livenessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/index.html
initialDelaySeconds: 3 # 3秒后探针
periodSeconds: 5 # 隔5秒探一次
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html
# 创建pod
kubectl create -f start-test.yaml
pod/nginx-hook created
# 由于宿主机上文件路径不存在,导致健康探针不正确,kill,重启容器
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hook 0/1 Completed 3 76s
# 由于设置的重启策略为OnFailure,终止运行且退出码不为0时才会重启
kubectl get pods nginx-hook -oyaml | grep -i restart
restartPolicy: OnFailure
restartCount: 3
# 在宿主机上创建该文件再次查看pod
cat /nginx-html/index.html
66
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hook 1/1 Running 0 3s
# 此时访问pod的ip等于访问宿主机的映射目录的index.html
curl 172.20.139.134
66
就绪探针 Readiness
httpGet:返回的状态码为2xx,3xx则为成功
需要定义好/read文件,确保nginx可以读取到即可正常running
如果就绪探针失败,Kubernetes 将会从服务负载均衡的池中剔除该容器,不会将流量路由到该容器,直到探测成功
# 创建readiness,生成pod
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
labels:
app: myapp-hook
spec:
volumes:
- name: nginx-html
hostPath:
path: /nginx-html
restartPolicy: OnFailure
containers:
- name: nginx-hook
image: nginx:alpine
livenessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 3 # 3秒后探针
periodSeconds: 5 # 隔5秒探一次
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html
readinessProbe:
httpGet:
path: /read
port: 80
initialDelaySeconds: 10 # 容器启动后多久开始探测
timeoutSeconds: 2 # 表示容器必须在2s内做出相应反馈给probe,否则视为探测失败
periodSeconds: 30 # 探测周期,每30s探测一次
successThreshold: 1 # 连续探测1次成功表示成功
failureThreshold: 3 # 连续探测3次失败表示失败
# 此时pod的流量被断开,这时候即使服务出错,对外界来说也是感知不到的
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-hook 0/1 Running 0 75s
# 让pod正常运行,提供访问
# 在宿主机映射目录内添加yaml文件中定义的read即可
cat /nginx-html/read
read read test
# 再次查看pod状态并访问测试
kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-hook 1/1 Running 0 6m53s 172.20.139.135 10.0.0.203 <none> <none>
# 访问测试
curl 172.20.139.135/read
read read test
liveness和readiness的区别
这两种检测的配置方法完全一样,支持的配置参数也一样。不同之处在于检测失败后的行为:Liveness 检测是重启容器;Readiness 检测则是将容器设置为不可用,不接收 Service 转发的请求