背景
在kubernates上使用Deployment部署了一个web应用的多个结点。并通过service的方式,将服务提供给外部使用。
但是通过指令修改应用镜像版本,来对应用滚动升级时。
kubectl set image deploy go-nifty-web-deployment go-nifty-web-containers=going/go-nifty-web:${latest_image_versions} --record
e
通过浏览器访问应用时,发现应用会在较长一段时间内无法响应请求。后面通过查阅kubernates官方文档及相关文档。了解到应用的滚动更新,对应的控制器需要监听pod的运行状态,当新的rs正常启动以后,新的pod状态就为running了,如果不做其它的检查,控制器就会认为老的rs控制的老的pod就可以更换掉了。其实一般应用在pod进入running状态以后,只是表明容器已经成功分配到了资源开始正常运行了。但应用本身这时还没有进行到可服务的状态,比如:tomcat这里还在加载对应的web应用,应用还要通过spring初始化应用等等等等。
解决方式
优化配置
根据文档,需要对容器对象配置readiness属性,来对容器中的服务进行健康检查。当应用进行可服务状态的时候,再通过控制器更新替换。
在阅读文档的同时了解到了容器的liveness属性,是用来检测服务中的应用健康状态检查的。这个配置在实际应用中还是很有用。比如当我们的web应用内存堆栈溢出了,从实际上来说,该容器已经处于不可使用的状态了,但容器还是处于running状态(大概是因为进程还在)。所以容器不会根据重启策略去重启服务。所以同时将这个属性也配置上。
优化以后的配置如下所示:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: go-nifty-web-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
tier: go-nifty-web
template:
metadata:
labels:
tier: go-nifty-web
spec:
containers:
- name: go-nifty-web-containers
image: going/go-nifty-web:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
- containerPort: 443
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
......
其中具体参数请查阅相关文档。
验证
修改更新配置以后,就可以在滚动更新中查看状态
kubectl rollout status deployment go-nifty-web-deployment
或更新完成后查看相关日志看到效果了。
kubectl describe deployment go-nifty-web-deployment