自愈是​kubernetes​集群的重要功能,我们使用各种​controller​的目的就是为了让POD在我们预期的范围内运行,​kubernetes​默认的自愈功能是检测POD退出后重启POD,或者在创建、初始化POD出错的时候重新拉取POD,这远远不不能满足我们生产中的要求,比如常见的web服务,我们不但要求POD能够正常运行,还要求pod能正常响应用户请求。基于这种需求,​kubernetes​利用​Liveness​ 和 ​Readiness​检测机制来设置更为精细的健康检测指标实现。除此之外,​Liveness​ 和 ​Readiness​还可以实现零停机部署和更加安全地滚动升级,避免部署无效的服务镜像,可以利用​Liveness​ 和 ​Readiness​对新版本的POD进行检测,如检测异常则保留旧POD,新的POD不对外提供服务。


0x01 默认自愈机制

    kubernetes默认的自愈机制就是当POD退出时对POD进行重启。

    1)准备资源

[root@host21 health]# cat exit.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: busybox
name: busybox-exit0
spec:
selector:
matchLabels:
app: busybox
template:
metadata:
name: busybox-exit0
labels:
app: busybox
spec:
containers:
- image: harbor.od.com/public/busybox:latest
name: busybox-exit0
args:
- /bin/sh
- -c
- sleep 20

# 应用
kubectl apply -f exit.yaml

    3)跟踪POD状态,可以看到POD退出后被重启。

[kubernetes] POD健康检测和自愈_nginx


0x02 ​Liveness​ 

    Livceness可以制定检测规则,如果检测失败就会重启POD

    1)准备资源

[root@host21 health]# cat nginx-liveness.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
restartPolicy: Always # 重启策略

containers:
- image: harbor.od.com/public/nginx:v1.7.9
name: nginx
args:
- /bin/sh
- -c
- echo `hostname` > /usr/share/nginx/html/index.html;nginx -g "daemon off;"
livenessProbe: # 定义只有http检测容器80端口,如果请求返回是200-400表示正常
httpGet:
scheme: HTTP
path: /index.html
port: 80
initialDelaySeconds: 10 # 容器启动 10 秒之后开始探测
periodSeconds: 5 # 每5秒探测一次
timeoutSeconds: 5 # http检测请求的超时时间
successThreshold: 1 # 检测到有1次成功则认为服务是`就绪`
failureThreshold: 3 # 检测到有3次失败则认为服务是`未就绪`
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
# 应用
[root@host21 health]# kubectl apply -f nginx-liveness.yaml
deployment.extensions/nginx created
service/nginx-svc created

    Pod 的重启策略有 3 种,默认值为 Always。

  • Always :容器失效时,kubelet 自动重启该容器;

  • OnFailure :容器终止运行且退出码不为0时重启;

  • Never :不论状态为何, kubelet 都不重启该容器。

    2)查看资源

[kubernetes] POD健康检测和自愈_html_02

    3)测试

[kubernetes] POD健康检测和自愈_重启_03

    4)删除其中一个POD的index.html文件并跟踪POD状态,可以看到POD被重启了一次,重启了之后index.html就又生成了,所以不会再次重启。

[kubernetes] POD健康检测和自愈_重启_04


0x03 readiness

    readiness和Livceness不同的是,当readiness检测到POD异常,只切断流量入口,不会重启POD。

    1)准备资源

[root@host21 health]# cat nginx-readiness.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- image: harbor.od.com/public/nginx:v1.7.9
name: nginx
args:
- /bin/sh
- -c
- echo `hostname` > /usr/share/nginx/html/index.html;nginx -g "daemon off;"
readinessProbe: # 定义只有http检测容器80端口,如果请求返回是200-400表示正常
httpGet:
scheme: HTTP
path: /index.html
port: 80
initialDelaySeconds: 10 # 容器启动 10 秒之后开始探测
periodSeconds: 5 # 每5秒探测一次
timeoutSeconds: 5 # http检测请求的超时时间
successThreshold: 1 # 检测到有1次成功则认为服务是`就绪`
failureThreshold: 3 # 检测到有3次失败则认为服务是`未就绪`
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
# 应用
kubectl apply -f nginx-readiness.yaml

    2)查看详情

[kubernetes] POD健康检测和自愈_html_05

    3)测试

[kubernetes] POD健康检测和自愈_重启_06

    4)登录最后一个容器,删除index.html文件

[kubernetes] POD健康检测和自愈_html_07

    5)持续跟踪POD状态,可以看到检测失败的POD以及不是READY的了

[kubernetes] POD健康检测和自愈_html_08

    6)再测试,可以看到流量已经不会被调度到不健康的POD上了。

[kubernetes] POD健康检测和自愈_重启_09    7)查看endpoint ,可以看到service已经将不健康的endpoint删除。

[kubernetes] POD健康检测和自愈_重启_10


0x04 总结

    ​Liveness​ 和 ​Readiness​即可以检测HTTP,还可以检测端口、文件等,在生产中我们一定要对不同业务的POD指定不同的健康检测,保障业务正常运行。

    总的来说这两种检测机制的配置几乎是一样的,而且这两种检测机制也可以配合使用,比如Readiness现将POD流量切断,再用Liveness将POD重启,避免直接重启导致服务暂时不可用的情况。


[kubernetes] POD健康检测和自愈_nginx_11