自愈是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退出后被重启。
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)查看资源
3)测试
4)删除其中一个POD的index.html文件并跟踪POD状态,可以看到POD被重启了一次,重启了之后index.html就又生成了,所以不会再次重启。
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)查看详情
3)测试
4)登录最后一个容器,删除index.html文件
5)持续跟踪POD状态,可以看到检测失败的POD以及不是READY的了
6)再测试,可以看到流量已经不会被调度到不健康的POD上了。
7)查看endpoint ,可以看到service已经将不健康的endpoint删除。
0x04 总结
Liveness 和 Readiness即可以检测HTTP,还可以检测端口、文件等,在生产中我们一定要对不同业务的POD指定不同的健康检测,保障业务正常运行。
总的来说这两种检测机制的配置几乎是一样的,而且这两种检测机制也可以配合使用,比如Readiness现将POD流量切断,再用Liveness将POD重启,避免直接重启导致服务暂时不可用的情况。