3.Pod控制器应用进阶
源自:《k8s实践(五):容器探针(liveness and readiness probe):https://cloud.tencent.com/developer/article/1501403?from=15425》
一、Pod的生命周期
init container -- Post start -- running -- pre stop -- main container
创建Pod经历的过程:->apiServer->etcd保存->scheculer->etcd调度结果->当前节点运行pod(把状态发回apiServer)->etcd保存
Pod的状态:Pending Running Failed Succeeded Unkown
Pod生命周期中的重要行为:
1、初始化行为(init container)
2、容器探测:
如何保持Pod健康
只要将pod调度到某个节点,Kubelet就会运行pod的容器,如果该pod的容器有一个或者所有的都终止运行(容器的主进程崩溃),Kubelet将重启容器,所以即使应用程序本身没有做任何特殊的事,在Kubemetes中运行也能自动获得自我修复的能力。
自动重启容器以保证应用的正常运行,这是使用Kubernetes的优势,不过在某些情况,即使进程没有崩溃,有时应用程序运行也会出错。默认情况下Kubernetes只是检查Pod容器是否正常运行,但容器正常运行并不一定代表应用健康,在以下两种情况下Kubernetes将不会重启容器:
- 1.访问Web服务器时显示500内部错误:该报错可能是系统超载,也可能是资源死锁,不过此时httpd进程依旧运行,重启容器可能是最直接有效的办法。
- 2.具有内存泄漏的Java应用程序将开始抛出OutOfMemoryErrors:此时JVM进程会一直运行,Kubernetes也不会重启容器,但此时对应用来讲是异常的。
此时可以考虑从外部检查应用程序的运行状况:
- Kubemetes可以通过存活探针(liveness probe)检查容器是否还在运行;
- 通过就绪探针(readiness probe)保证只有准备好了请求的Pod才能接收客户端请求。
LivenessProbe:Kubemetes可以通过存活探针(liveness probe)检查容器是否还在运行。用于判断容器是否健康,如果不包含此探针,则默认Success,决定Pod状态。可以为pod中的每个容器单独指定存活探针。如果探测失败,Kubemetes将定期执行探针并重新启动容器。
ReadinessProbe:用于容器的自定义准备状态检查。容器中服务是否正常,是否能够提供服务,用于判断容器是否启动完成并准备接收请求。 如果ReadinessProbe检查失败,Kubernetes会将该Pod从服务代理的分发后端去除,不再分发请求给该Pod。
Kubernetes 支持三种方式来执行探针:
- exec:在容器中执行一个命令,如果命令退出码返回0则表示探测成功,否则表示失败
- tcpSocket:对指定的容IP及端口执行一个TCP检查,如果端口是开放的则表示探测成功,否则表示失败
- httpGet:对指定的容器IP、端口及路径执行一个HTTP Get请求,如果返回的状态码在 [200,400)之间则表示探测成功,否则表示失败
就绪性探测与service调度性存在重要关系。如果不做就绪性探测,只要标签匹配上,pod一旦创建就被绑定为service的后端, service直接将用户请求调度到已存活但未就绪的pod上,那么在一段时间内用户请求可能是失败的。
3、容器的重启策略:
pod.spec.restartPolicy <string> # 容器的重启策略字段
pod.spec.restartPolicy:#容器的重启策略。有三种,Always(只要退出就重启,默认),OnFailure(当容器终止运行且退出码不为0时, 由kubelet自动重启该容器),Never(只要退出就不重启)。kubelet重新启动的已退出容器将以指数退避延迟(10秒,20秒,40秒......)重新启动,上限为300s,并在成功执行十分钟后重置。
# Pod一旦调度成功,就永远在已调度的节点上,不会重新调度,除非节点挂了或pod被删除了,才会被重新调度。
4、lifecycle
启动后钩子(spec.containers.lifecycle.postStart):容器创建后立即执行,如果执行失败,容器终止,重启与否取决于重启策略。
终止前钩子(spec.containers.lifecycle.preStop):exec httpGet tcpSocket
Tips:容器的command比lifecycle的postStart exec command先执行。
二、常用命令
# kubectl logs #获取pod 中的日志 # kubectl get pods --show-labels #展示所有pod的标签 # kubectl get pods -L app #显示有app标签的标签值 # kubectl get pods -l app,release #过滤出有标签app,release标签的pod资源 # kubectl label --help #给资源对象打标签 # kubectl get pods –l release=canary,app=myapp #等值标签选择器,“与” # kubectl label nodes node1 disktype=ssd #给node1打标,disktype=ssd
# 许多资源支持内嵌字段,matchLabels或matchExpressions来定义标签选择器
matchLabels:直接给定键值
matchExpressions:基于给定的表达式来定义使用的标签选择器
{key:”KEY”,operator:”OPERATOR” ,values:[VALUE1,VALUE2,VALUE3]} #操作符一般是逻辑表达式,(In、 NotIn),values的值必须为非空列表,(Exists、NotExists),values的值必须为空列表等。