首页 > 数据库 > 数据库开发技术 > Pod高级用法:如何管理pod生命周期

Pod高级用法:node节点选择器我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node节点,怎么办呢?可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点1、nodeName:指定pod节点运行在哪个具体node上~]# cat pod.yamlapiVersion: v1kind: Podmetadata:name: demo-podnamespace: defaultlabels:app: myappenv: devspec:nodeName: node2containers:name: tomcat-pod-javaports:containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentname: busyboximage: busybox:latestcommand:"/bin/sh""-c""sleep 3600"2、nodeSelector:指定pod调度到具有哪些标签的node节点上#给node节点打标签,打个具有disk=ceph的标签~]# kubectl label nodes node1 disk=cephlabeled#定义pod的时候指定要调度到具有disk=ceph标签的node上~]# cat pod.yamlapiVersion: v1kind: Podmetadata:name: demo-podnamespace: defaultlabels:app: myappenv: devspec:nodeSelector:disk: cephcontainers:name: tomcat-pod-javaports:containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentPod高级用法:污点和容忍度node节点亲和性node节点亲和性调度:nodeAffinity~]# kubectl explain pods.spec.affinityKIND: PodVERSION: v1RESOURCE: affinity <Object>DESCRIPTION:If specified, the pod's scheduling constraintsAffinity is a group of affinity scheduling rules.FIELDS:nodeAffinity <Object>podAffinity <Object>podAntiAffinity <Object>~]# kubectl explain pods.spec.affinity.nodeAffinityKIND: PodVERSION: v1RESOURCE: nodeAffinity <Object>DESCRIPTION:Describes node affinity scheduling rules for the pod.Node affinity is a group of node affinity scheduling rules.FIELDS:preferredDuringSchedulingIgnoredDuringExecution <[]Object>requiredDuringSchedulingIgnoredDuringExecution <Object>prefered表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性require表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecutionKIND: PodVERSION: v1RESOURCE: requiredDuringSchedulingIgnoredDuringExecution <Object>DESCRIPTION:FIELDS:nodeSelectorTerms <[]Object> -required-A list of node selector terms. The terms are ORed.~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTermsKIND: PodVERSION: v1RESOURCE: nodeSelectorTerms <[]Object>DESCRIPTION:A list of node selector terms. The terms are ORed.A null or empty node selector term matches no objects. The requirements ofthem are ANDed. The TopologySelectorTerm type implements a subset of theNodeSelectorTerm.FIELDS:matchExpressions <[]Object>matchFields <[]Object>matchExpressions:匹配表达式的匹配字段的~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchFieldsKIND: PodVERSION: v1RESOURCE: matchFields <[]Object>DESCRIPTION:FIELDS:key <string> -required-values <[]string>~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressionsKIND: PodVERSION: v1RESOURCE: matchExpressions <[]Object>DESCRIPTION:FIELDS:key <string> -required-operator <string> -required-values <[]string>key:检查labeloperator:做等值选则还是不等值选则values:给定值例1:使用requiredDuringSchedulingIgnoredDuringExecution硬亲和性~]# cat pod-nodeaffinity-demo.yamlapiVersion: v1kind: Podmetadata:name: pod-node-affinity-demonamespace: defaultlabels:app: myapptier: frontendspec:containers:name: myappimage: ikubernetes/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:matchExpressions:key: zoneoperator: Invalues:foobar我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上kubectl apply -f pod-nodeaffinity-demo.yaml~]# kubectl get pods -o wide | grep pod-node0/1 Pending 0 node2status的状态是pending,上面说明没有完成调度,因为没有一个拥有zone的标签的值是foo或者bar,而且使用的是硬亲和性,必须满足条件才能完成调度kubectl label nodes node2 zone=foo 给这个node2节点打上标签zone=foo,在查看kubectl get pods -o wide 显示如下:1/1 Running 0 node2例2:使用preferredDuringSchedulingIgnoredDuringExecution软亲和性~]# cat pod-nodeaffinity-demo-2.yamlapiVersion: v1kind: Podmetadata:name: pod-node-affinity-demo-2namespace: defaultlabels:app: myapptier: frontendspec:containers:name: myappimage: ikubernetes/myapp:v1affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:preference:matchExpressions:key: zone1operator: Invalues:foo1bar1weight: 60~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml~]# kubectl get pods -o wide |grep demo-21/1 Running 0 node2上面说明软亲和性是可以运行这个pod的,尽管没有运行这个pod的节点定义的zone1标签Pod节点亲和性pod自身的亲和性调度有两种表示形式podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响;我们通过节点亲和性也可以来定义pod之间的亲和性,一般来讲我们用户必须为pod指定节点标签,这样就可以通过节点亲和性来控制pod亲和性;那么为什么还要定义pod亲和性呢,因为通过节点亲和性来控制pod亲和性并不是最优的选则,我们必须确定节点和pod双方向可以完全匹配到,还需要精心布局节点是如何打标签的才能达到目的,这种方式难度较大;定义pod亲和性最理想的方式:第一个pod随机选则一个节点,做为评判后续的pod能否到达这个pod所在的节点上的运行方式,这就称为pod亲和性;我们怎么判定哪些节点是相同位置的,哪些节点是不同位置的;我们在定义pod亲和性时需要有一个前提,哪些pod在同一个位置,哪些pod不在同一个位置,这个位置是怎么定义的,标准是什么?以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置。~]# kubectl explain pods.spec.affinity.podAffinityKIND: PodVERSION: v1RESOURCE: podAffinity <Object>DESCRIPTION:Describes pod affinity scheduling rules (e.g. co-locate this pod in thesame node, zone, etc. as some other pod(s)).Pod affinity is a group of inter pod affinity scheduling rules.FIELDS:preferredDuringSchedulingIgnoredDuringExecution <[]Object>requiredDuringSchedulingIgnoredDuringExecution <[]Object>硬亲和性preferredDuringSchedulingIgnoredDuringExecution:软亲和性~]# kubectl explain pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecutionKIND: PodVERSION: v1RESOURCE: requiredDuringSchedulingIgnoredDuringExecution <[]Object>DESCRIPTION:FIELDS:labelSelector <Object>namespaces <[]string>topologyKey <string> -required-topologyKey:位置拓扑的键,这个是必须字段怎么判断是不是同一个位置:rack=rack1row=row1使用rack的键是同一个位置使用row的键是同一个位置labelSelector:我们要判断pod跟别的pod亲和,跟哪个pod亲和,需要靠labelSelector,通过labelSelector选则一组能作为亲和对象的pod资源namespace:labelSelector需要选则一组资源,那么这组资源是在哪个名称空间中呢,通过namespace指定,如果不指定namespaces,那么就是当前创建pod的名称空间~]# kubectl explain pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.labelSelectorKIND: PodVERSION: v1RESOURCE: labelSelector <Object>DESCRIPTION:A label query over a set of resources, in this case pods.A label selector is a label query over a set of resources. The result ofmatchLabels and matchExpressions are ANDed. An empty label selector matchesall objects. A null label selector matches no objects.FIELDS:matchExpressions <[]Object>matchLabels <map[string]string>例1:pod节点亲和性定义两个pod,第一个pod做为基准,第二个pod跟着它走~]# cat pod-required-affinity-demo.yamlapiVersion: v1kind: Podmetadata:name: pod-firstlabels:app: myapptier: frontendspec:containers:name: myappimage: ikubernetes/myapp:v1---apiVersion: v1kind: Podmetadata:name: pod-secondlabels:app: backendtier: dbspec:containers:name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:labelSelector:matchExpressions:{key: app, operator: In, values: ["myapp"]}topologyKey: kubernetes.io/hostname#上面表示创建的pod必须与拥有app=myapp标签的pod在一个节点上kubectl apply -f pod-required-affinity-demo.yamlkubectl get pods -o wide 显示如下:running node2running node2上面说明第一个pod调度到哪,第二个pod也调度到哪,这就是pod节点亲和性kubectl delete -f pod-required-affinity-demo.yaml例2:pod节点反亲和性定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反~]# cat pod-required-anti-affinity-demo.yamlapiVersion: v1kind: Podmetadata:name: pod-firstlabels:app: myapptier: frontendspec:containers:name: myappimage: ikubernetes/myapp:v1---apiVersion: v1kind: Podmetadata:name: pod-secondlabels:app: backendtier: dbspec:containers:name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:labelSelector:matchExpressions:{key: app, operator: In, values: ["myapp"]}topologyKey: kubernetes.io/hostnamekubectl apply -f pod-required-anti-affinity-demo.yamlkubectl get pods -o wide 显示两个pod不在一个node节点上,这就是pod节点反亲和性running node2running node1kubectl delete -f pod-required-anti-affinity-demo.yaml例3:换一个topologykeykubectl label nodes node1 zone=fookubectl label nodes node2 zone=foo~]# cat pod-required-anti-affinity-demo-1.yamlapiVersion: v1kind: Podmetadata:name: pod-firstlabels:app: myapptier: frontendspec:containers:name: myappimage: ikubernetes/myapp:v1---apiVersion: v1kind: Podmetadata:name: pod-secondlabels:app: backendtier: dbspec:containers:name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:labelSelector:matchExpressions:{key: app, operator: In, values: ["myapp"]}topologyKey: zonekubectl apply -f pod-required-anti-affinity-demo.yamlkubectl get pods -o wide 显示如下:running node2pending <none>第二个节点现是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了,而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成preferred,那么也会运行。podaffinity:pod节点亲和性,pod倾向于哪个podnodeaffinity:node节点亲和性,pod倾向于哪个node污点、容忍度给了节点选则的主动权,我们打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以定决定拒绝那些pod;taints是键值数据,用在节点上,定义容忍度;tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点节点亲和性是pod属性,pod亲和性也是pod属性;但是污点是节点的属性,污点定义在nodeSelector上kubectl get nodes node1 -o yaml~]# kubectl explain node.spec.taintsKIND: NodeVERSION: v1RESOURCE: taints <[]Object>DESCRIPTION:If specified, the node's taints.The node this Taint is attached to has the "effect" on any pod that doesnot tolerate the Taint.FIELDS:effect <string> -required-key <string> -required-timeAdded <string>value <string>taints的effect用来定义对pod对象的排斥等级(效果):NoSchedule:仅影响调度过程,当pod能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的pod不能容忍了,那这个pod会怎么处理,对现存的pod对象不产生影响NoExecute:既影响调度过程,又影响现存的pod对象,如果现存的pod不能容忍节点后来加的污点,这个pod就会被驱逐PreferNoSchedule:最好不,也可以,是NoSchedule的柔性版本在pod对象定义容忍度的时候支持两种操作:1.等值密钥:key和value上完全匹配2.存在性判断:key和effect必须同时匹配,value可以是空在pod上定义的容忍度可能不止一个,在节点上定义的污点可能多个,需要琢个检查容忍度和污点能否匹配,每一个污点都能被容忍,才能完成调度,如果不能容忍怎么办,那就需要看pod的容忍度了kubectl describe nodes master1查看master这个节点是否有污点,显示如下:上面可以看到master这个节点的污点是Noschedule所以我们创建的pod都不会调度到master上,因为我们创建的pod没有容忍度kubectl describe pods kube-apiserver-master -n kube-system 显示如下:可以看到这个pod的容忍度是NoExecute,则可以调度到master1上管理节点污点kubectl taints --help例1:把node1当成是生产环境专用的,其他node是测试的kubectl taint node node1 node-type=production:NoSchedule (给node1打污点,pod如果不能容忍就不会调度过来)kubectl apply -f deploy-demo.yamlkubectl get pods -o wide显示如下:running node2running node2running node2可以看到都被调度到node1上了,因为node1这个节点打了污点,而我们在创建pod的时候没有容忍度,所以node1上不会有pod调度上去的例2:给node2也打上污点kubectl taint node node2 node-type=dev:NoExecutekubectl get pods -o wide 显示如下:pendingpendingpending上面可以看到已经存在的pod节点都被撵走了~]# cat deploy-demo-1.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: myapp-deploynamespace: defaultspec:replicas: 3selector:matchLabels:app: myapprelease: canarytemplate:metadata:labels:app: myapprelease: canaryspec:containers:name: myappimage: ikubernetes/myapp:v1ports:name: httpcontainerPort: 80tolerations:key: "node-type"operator: "Equal"value: "production"effect: "NoExecute"tolerationSeconds: 3600kubectl apply -f deploy-demo-1.yamlkubectl get pods -o wide: "NoSchedule"成这个;tolerationSeconds: 3600这行去掉kubectl apply -f deploy-demo-1.yamlkubectl get pods -o wide 显示如下:running node1running node1running node1上面就可以调度到node1上了,因为在pod中定义的容忍度能容忍node节点上的污点例3:再次修改修改如下部分:tolerations:key: "node-type"operator: "Exists"value: ""effect: "NoSchedule"只要对应的键是存在的,exists,其值被自动定义成通配符kubectl apply -f deploy-demo-1.yamlkubectl get pods -o wide 显示如下:running node1running node1running node1发现还是调度到node1上再次修改:tolerations:key: "node-type"operator: "Exists"value: ""effect: ""有一个node-type的键,不管值是什么,不管是什么效果,都能容忍kubectl apply -f deploy-demo-1.yamlkubectl get pods -o wide 显示如下:running node1running node2running node1可以看到node1和node2节点上都有pod被调度Pod高级用法:Pod状态和重启策略常见的pod状态phase 可能的值,也就是pod常见的状态:中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。中的所有容器都被成功终止,并且不会再重启。中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。未知(Unknown):未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown扩展:还有其他状态,如下:Evicted状态:出现这种情况,多见于系统内存或硬盘资源不足,可df-h查看docker存储所在目录的资源使用情况,如果百分比大于85%,就要及时清理下资源,尤其是一些大文件、docker镜像。CrashLoopBackOff:容器曾经启动了,但可能又异常退出了Error 状态:Pod 启动过程中发生了错误pod重启策略RestartPolicy 的设置来进行相应的操作。Always、OnFailure和Never,默认值为Always。Always:当容器失败时,由kubelet自动重启该容器。OnFailure:当容器终止运行且退出码不为0时,有kubelet自动重启该容器。Never:不论容器运行状态如何,kubelet都不会重启该容器。kubelet 以五分钟为上限的指数退避延迟(10秒,20秒,40秒…)重新启动,并在成功执行十分钟后重置。~]# vim pod.yamlapiVersion: v1kind: Podmetadata:name: demo-podnamespace: defaultlabels:app: myappspec:restartPolicy: Alwayscontainers:name: tomcat-pod-javaports:containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentPod高级用法:Pod生命周期Init容器Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建Pod时候,Pod 中可以有一个或多个先于主容器启动的Init容器,这个init容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器1,在执行初始化容器2等,等初始化容器执行完初始化就退出了,然后再执行主容器,主容器一退出,pod就结束了,主容器退出的时间点就是pod的结束点,它俩时间轴是一致的;Container里产生的数据可以被主容器使用到,Init Container可以在多种K8S资源里被使用到,如Deployment、DaemonSet, StatefulSet、Job等,但都是在Pod启动时,在主容器启动前执行,做初始化工作。:容器不支持 Readiness,因为它们必须在Pod就绪之前运行完成2、每个Init容器必须运行成功,下一个才能够运行Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,然而,如果Pod对应的restartPolicy值为 Never,它不会重新启动。主容器1、容器钩子start hook(容器启动后钩子)和pre stop hook(容器结束前钩子),无论启动后还是结束前所做的事我们可以把它放两个钩子,这个钩子就表示用户可以用它来钩住一些命令,来执行它,做开场前的预设,结束前的清理,如awk有begin,end,和这个效果类似;handler执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器,这个钩子不需要传递任何参数。handler必须在删除该容器的请求发送给Docker daemon之前完成。在该钩子对应的hook handler完成后不论执行的结果如何,Docker daemon会发送一个SGTERN信号量给Docker daemon来删除该容器,这个钩子不需要传递任何参数。在k8s中支持两类对pod的检测,第一类叫做livenessprobe(pod存活性探测):restartPolicy来判断Pod 是否要进行重启操作,如果容器配置中没有配置 livenessProbe,Kubelet 将认为存活探针探测一直为成功状态。第二类是状态检readinessprobe(pod就绪性探测):用于判断容器中应用是否启动完成,当探测成功后才使Pod对外提供网络访问,设置容器Ready状态为true,如果探测失败,则设置容器的Ready状态为false。创建pod需要经过哪些阶段?当用户创建pod时,这个请求给apiserver,apiserver把创建请求的目标状态保存在etcd中;接下来apiserver会请求scheduler来完成调度,如果调度成功,会把调度的结果(如调度到哪个节点上了,运行在哪个节点上了,把它更新到etcd的pod资源状态中)保存在etcd中,一旦存到etcd中并且完成更新以后,那么目标节点,如调度到node2上,那么node2节点上的kubelet通过apiserver当中的状态变化知道有一些任务被执行了,所以此时此kubelet会拿到用户创建时所提交的清单,这个清单会在当前节点上运行或者启动这个pod,如果创建成功或者失败会有一个当前状态,当前这个状态会发给apiserver,apiserver在存到etcd中;在这个过程中,etcd和apiserver一直在打交道,不停的交互,scheduler也参与其中,负责调度pod到合适的node节点上,这个就是pod的创建过程pod在整个生命周期中有非常多的用户行为:1、初始化容器完成初始化2、主容器启动后可以做启动后钩子3、主容器结束前可以做结束前钩子probe,readness probePod高级用法:Pod容器探测深度讲解容器钩子:postStart和preStoppostStart:容器创建成功后,运行前的任务,用于资源部署、环境准备等。preStop:在容器被终止前的任务,用于优雅关闭应用程序、通知其他系统等。演示postStart和preStop用法......containers:image: sample:v2name: warlifecycle:postStart:exec:command:“cp”“/sample.war”“/app”prestop:httpGet:host: monitor.compsth: /waringport: 8080scheme: HTTP......://monitor.com:8080/waring,即向监控系统发送警告。优雅的删除资源对象当用户请求删除含有pod的资源对象时(如RC、deployment等),K8S为了让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软件),K8S提供两种信息通知:stop命令,docker会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30s),会继续发送SIGKILL的系统信号强行kill掉进程。2)、使用pod生命周期(利用PreStop回调函数),它执行在发送终止信号之前。delete命令支持--grace-period=的选项,以运行用户来修改默认值。0表示删除立即执行,并且立即从API中删除pod,这样一个新的pod会在同时被创建。在节点上,被设置了立即结束的的pod,仍然会给一个很短的优雅退出时间段,才会开始被强制杀死。如下:kind: Deploymentmetadata:name: nginx-demolabels:app: nginx-demospec:replicas: 1template:metadata:labels:app: nginx-demospec:containers:name: nginx-demoimage: centos:nginxlifecycle:preStop:exec:# nginx -s quit gracefully terminate while SIGTERM triggers a quick exitcommand: ["/usr/local/nginx/sbin/nginx","-s","quit"]ports:name: httpcontainerPort: 80探测:livenessProbe和readinessProbelivenessProbe:存活性探测readinessProbe:就绪性探测boot应用,默认的actuator带有/health接口,可以用来进行启动成功的判断。目前LivenessProbe和ReadinessProbe两种探针都支持下面三种探测方法:0 则探测成功。IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康探针探测结果有以下值:1、Success:表示通过检测。2、Failure:表示未通过检测。3、Unknown:表示检测没有正常进行。Pod探针相关的属性:探针(Probe)有许多可选字段,可以用来更加精确的控制Liveness和Readiness两种探针的行为Pod启动后首次进行检查的等待时间,单位“秒”。检查的间隔时间,默认为10s,单位“秒”。探针执行检测请求后,等待响应的超时时间,默认为1s,单位“秒”。探针检测失败后认为成功的最小连接成功次数,默认为 1s,在 Liveness 探针中必须为1s,最小值为1s。探测失败的重试次数,重试一定次数后将认为失败,在 readiness 探针中,Pod会被标记为未就绪,默认为 3s,最小值为 1s。两种探针区别:ReadinessProbe 和 livenessProbe 可以使用相同探测方式,只是对 Pod 的处置方式不同:readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。Pod探针使用示例:探针使用示例(1)、通过exec方式做健康探测liveness-exec.yamlapiVersion: v1kind: Podmetadata:name: liveness-execlabels:app: livenessspec:containers:name: livenessimage: busyboxargs: #创建测试探针探测的文件/bin/sh-ctouch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600livenessProbe:initialDelaySeconds: 10 #延迟检测时间periodSeconds: 5 #检测时间间隔exec:command:cat/tmp/healthy容器启动设置执行的命令:-c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"/tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令,存活探针就认为探测成功,否则探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。(2)、通过HTTP方式做健康探测liveness-http.yamlapiVersion: v1kind: Podmetadata:name: liveness-httplabels:test: livenessspec:containers:name: livenessimage: mydlqclub/springboot-helloworld:0.0.1livenessProbe:initialDelaySeconds: 20 #延迟加载时间periodSeconds: 5 #重试时间间隔timeoutSeconds: 10 #超时时间设置httpGet:scheme: HTTPport: 8081path: /actuator/healthPod 中启动的容器是一个 SpringBoot 应用,其中引用了 Actuator 组件,提供了 /actuator/health 健康检查地址,存活探针可以使用 HTTPGet 方式向服务发起请求,请求 8081 端口的 /actuator/health 路径来进行存活判断:任何大于或等于200且小于400的代码表示探测成功。任何其他代码表示失败。Pod 进行重启操作。:scheme: 用于连接host的协议,默认为HTTP。IP,可以在http request head中设置host头部。port:容器上要访问端口号或名称。path:http服务器上的访问URI。httpHeaders:自定义HTTP请求headers,HTTP允许重复headers。(3)、通过TCP方式做健康探测liveness-tcp.yamlapiVersion: v1kind: Podmetadata:name: liveness-tcplabels:app: livenessspec:containers:name: livenessimage: nginxlivenessProbe:initialDelaySeconds: 15periodSeconds: 20tcpSocket:port: 80TCP 检查方式和 HTTP 检查方式非常相似,在容器启动 initialDelaySeconds 参数设定的时间后,kubelet 将发送第一个 livenessProbe 探针,尝试连接容器的 80 端口,如果连接失败则将杀死 Pod 重启容器。探针使用示例Pod 的ReadinessProbe 探针使用方式和 LivenessProbe 探针探测方法一样,也是支持三种,只是一个是用于探测应用的存活,一个是判断是否对外提供流量的条件。这里用一个 Springboot 项目,设置 ReadinessProbe 探测 SpringBoot 项目的 8081 端口下的 /actuator/health 接口,如果探测成功则代表内部程序以及启动,就开放对外提供接口访问,否则内部应用没有成功启动,暂不对外提供访问,直到就绪探针探测成功。readiness-exec.yamlapiVersion: v1kind: Servicemetadata:name: springbootlabels:app: springbootspec:type: NodePortports:name: serverport: 8080targetPort: 8080nodePort: 31180name: managementport: 8081targetPort: 8081nodePort: 31181selector:app: springboot---apiVersion: v1kind: Podmetadata:name: springbootlabels:app: springbootspec:containers:name: springbootimage: mydlqclub/springboot-helloworld:0.0.1ports:name: servercontainerPort: 8080name: managementcontainerPort: 8081readinessProbe:initialDelaySeconds: 20periodSeconds: 5timeoutSeconds: 10httpGet:scheme: HTTPport: 8081path: /actuator/health+ LivenessProbe 配合使用示例SpringBoot 项目的 Deployment 例子。apiVersion: v1kind: Servicemetadata:name: springbootlabels:app: springbootspec:type: NodePortports:name: serverport: 8080targetPort: 8080nodePort: 31180name: managementport: 8081targetPort: 8081nodePort: 31181selector:app: springboot---apiVersion: apps/v1kind: Deploymentmetadata:name: springbootlabels:app: springbootspec:replicas: 1selector:matchLabels:app: springboottemplate:metadata:name: springbootlabels:app: springbootspec:containers:name: readinessimage: mydlqclub/springboot-helloworld:0.0.1ports:name: servercontainerPort: 8080name: managementcontainerPort: 8081readinessProbe:initialDelaySeconds: 20periodSeconds: 5timeoutSeconds: 10httpGet:scheme: HTTPport: 8081path: /actuator/healthlivenessProbe:initialDelaySeconds: 30periodSeconds: 10timeoutSeconds: 5httpGet:scheme: HTTPport: 8081: /actuator/health
公众号后台回复 [ 加群 ],加入linux+docker+k8s+devops技术交流群,一起进步、一起成长!
精彩文章推荐
安装kubernetes集群-灵活安装k8s各个版本高可用集群
Prometheus+Grafana+Alertmanager搭建全方位的监控告警系统-超详细文档
k8s+jenkins+SonarQube+harbor构建DevOps自动化容器云平台
K8s自动扩缩容工具KEDA发布2.0版本,全面升级应用扩展能力
k8s控制器Statefulset详细介绍:资源清单编写技巧

公众号后台回复 [ 加群 ],加入linux+docker+k8s+devops技术交流群,一起进步、一起成长!
原文作者:DevOps和k8s全栈技术;如有侵权,请联系管理员删除。