1、定义
Pod是kubernetes中你可以创建和部署的最小也是最简的单位。Pod代表着集群中运行的进程。
Pod 是一组紧密关联的容器集合,它们共享 IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
1.1 Pod 的特征
- 包含多个共享 IPC、Network 和 UTC namespace 的容器,可直接通过 localhost 通信
- 所有 Pod 内容器都可以访问共享的 Volume,可以访问共享数据
- 无容错性:直接创建的 Pod 一旦被调度后就跟 Node 绑定,即使 Node 挂掉也不会被重新调度(而是被自动删除),因此推荐使用 Deployment、Daemonset 等控制器来容错
- 优雅终止:Pod 删除的时候先给其内的进程发送 SIGTERM,等待一段时间(grace period)后才强制停止依然还在运行的进程
- 特权容器(通过 SecurityContext 配置)具有改变系统配置的权限(在网络插件中大量应用)
1.2 Pod运行多个容器
Pod中可以同时运行多个进程(作为容器运行)协同工作。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境和依赖,它们总是被同时调度。
注意:
在一个Pod中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个"sidecar”容器来从远端获取资源更新这些文件,如下图所示:
1.3、定义Pod
下面是Pod的资源清单:kubectl explain pods
apiVersion v1 #必选,版本号,例如v1kind Pod #必选,资源类型,例如 Podmetadata#必选,元数据 name string #必选,Pod名称 namespace string #Pod所属的命名空间,默认为"default" labels#自定义标签列表name string spec#必选,Pod中容器的详细定义 containers#必选,Pod中容器列表name string #必选,容器名称 image string #必选,容器的镜像名称 imagePullPolicy Always|Never|IfNotPresent #获取镜像的策略 ,IfNotPresent没有容器的时候去拉 command string#容器的启动命令列表,如不指定,使用打包时使用的启动命令 args string#容器的启动命令参数列表 workingDir string #容器的工作目录 volumeMounts#挂载到容器内部的存储卷配置name string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名 mountPath string #存储卷在容器内mount的绝对路径,应少于512字符 readOnly boolean #是否为只读模式 ports#需要暴露的端口库号列表name string #端口的名称 containerPort int #容器需要监听的端口号 hostPort int #容器所在主机需要监听的端口号,默认与Container相同 protocol string #端口协议,支持TCP和UDP,默认TCP env#容器运行前需设置的环境变量列表name string #环境变量名称 value string #环境变量的值 resources#资源限制和请求的设置 limits#资源限制的设置 cpu string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数,能够使用几核cpu memory string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数 requests#资源请求的设置 cpu string #Cpu请求,容器启动的初始可用数量 memory string #内存请求,容器启动的初始可用数量 lifecycle#生命周期钩子,能活多久 postStart#容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启 preStop#容器终止前执行此钩子,无论结果如何,容器都会终止 livenessProbe#对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器 exec#对Pod容器内检查方式设置为exec方式 command string#exec方式需要制定的命令或脚本 httpGet#对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port path string port number host string scheme string HttpHeadersname string value string tcpSocket#对Pod内个容器健康检查方式设置为tcpSocket方式 port number initialDelaySeconds 0 #容器启动完成后首次探测的时间,单位为秒 timeoutSeconds 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒 periodSeconds 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次 successThreshold 0 #成功多少次,任务他成功了 failureThreshold 0 #失败多少次,任务他失败了 securityContext#安全上下文 privilegedfalse restartPolicy Always | Never | OnFailure#Pod的重启策略 nodeName <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上,指定位置 nodeSelector obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上 imagePullSecrets#Pull镜像时使用的secret名称,以key:secretkey格式指定name string hostNetwork false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络(真机网络) volumes#在该pod上定义共享存储卷列表name string #共享存储卷名称 (volumes类型有很多种) emptyDir#类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值 hostPath string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录 path string #Pod所在宿主机的目录,将被用于同期中mount的目录 secret#类型为secret的存储卷,挂载集群与定义的secret对象到容器内部 scretname string itemskey string path string configMap#类型为configMap的存储卷,挂载预定义的configMap对象到容器内部 name string itemskey string path string
提示
在这里,可通过一个命令来查看每种资源的可配置项
kubectl explain 资源类型 查看某种资源可以配置的一级属性
kubectl explain 资源类型.属性 查看属性的子属性
2、生命周期
Kubernetes 以 PodStatus.Phase 抽象 Pod 的状态(但并不直接反映所有容器的状态)。可能的 Phase 包括
- Pending: API Server已经创建该Pod,但一个或多个容器还没有被创建,包括通过网络下载镜像的过程。
- Running: Pod中的所有容器都已经被创建且已经调度到 Node 上面,但至少有一个容器还在运行或者正在启动。
- Succeeded: Pod 调度到 Node 上面后均成功运行结束,并且不会重启。
- Failed: Pod中的所有容器都被终止了,但至少有一个容器退出失败(即退出码不为 0 或者被系统终止)。
- Unknonwn: 状态未知,因为一些原因Pod无法被正常获取,通常是由于 apiserver 无法与 kubelet 通信导致。
下图是Pod的生命周期示意图,从图中可以看到Pod状态的变化。
2.1、Pod启动流程
- APIServer将pod信息存入etcd,通知Scheduler。
- Scheduler根据调度算法,为pod选择一个节点,然后向APIServer发送更新spec.nodeName。
- APIServer更新完毕,通知对应节点的kubelet。
- kubelet发现pod调度到本节点,创建并运行pod的容器。
3、容器重启策略
容器重启策略是指在容器出现故障或终止后,Kubernetes 如何处理容器的重新启动。以下是 Kubernetes 中常见的容器重启策略:
- Always(始终重启): 当容器终止或出现故障时,Kubernetes 会立即重启该容器。这是默认的重启策略。使用这种策略时,Kubernetes 将尝试持续重启容器,直到其成功运行或手动删除。
- OnFailure(仅在故障时重启): 当容器终止并以非零退出代码结束时,Kubernetes 会重启该容器。如果容器正常终止(退出代码为零),则不会进行重启。这种策略适用于需要故障恢复的容器。
- Never(永不重启): 当容器终止时,Kubernetes 不会自动重启该容器。容器的终止将被视为最终状态。这种策略适用于一次性任务或不需要自动恢复的容器。
重启策略适用于pod对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长为10s,20s,40s,80s,160s,300s,300s是最大延迟时长
4、调度和亲和性
Pod 的调度由 Kubernetes 的调度器负责。调度器根据集群资源和策略将 Pod 分配给适当的节点。此外,可以使用亲和性和反亲和性来指定 Pod 与特定节点或其他 Pod 之间的关系,以满足特定的部署需求。
4.1、 Pod调度
在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。在实际使用中,想控制某些Pod到达某些节点上,kubernetes提供了四大类调度方式:
- 自动调度:运行在哪个节点上完全由Scheduler(调度器)经过一系列的算法计算得出
- 定向调度:NodeName、NodeSelector(用节点选择器通过标签来选择需要到那些有标签的节点上运行)
- 亲和性调度:NodeAffinity(我期望在哪个节点上运行,那个节点不能跑选次一级)、PodAffinity(期望和另外一个pod在同一节点上运行)、PodAntiAffinity(不期望在哪个节点上运行)
- 污点(容忍)调度:Taints(打污点)、Toleration(容忍)
4.1.1、定向调度
指的是利用在pod上声明nodeName或者nodeSelector,以此将Pod调度到期望的node节点上。
注意:
这里的调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已。
4.1.2、亲和性调度
亲和性调度(Affinity Scheduling)是 Kubernetes 中一种调度策略,用于指定 Pod 与节点或其他 Pod 之间的关系,以便更好地满足特定的部署需求和约束条件。通过亲和性调度,可以将 Pod 调度到具有特定标签的节点上,或者将多个相关的 Pod 调度到同一个节点上。
在 Kubernetes 中,亲和性调度通过以下方式实现:
- nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题
- podAffinity(pod亲和性) : 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
- podAntiAffinity(pod反亲和性): 以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题
使用场景的说明
- 亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。(在内部通信)
- 反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性。(不能在一个节点上跑相同的内容,让他们分散,达到高可用)
nodeAffinity
NodeAffinity意为Node亲和性调度策略。是用于替换NodeSelector的全新调度策略。目前有两种节点节点亲和性表达:
- RequiredDuringSchedulingIgnoredDuringExecution:必须满足制定的规则才可以调度pode到Node上。相当于硬限制
- PreferredDuringSchedulingIgnoreDuringExecution:强调优先满足制定规则,调度器会尝试调度pod到Node上,但并不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义执行的先后顺序。
下面的例子设置了NodeAffinity调度的如下规则:
- RequiredDuringSchedulingIgnoredDuringExecution 要求只运行在amd64的节点上
- PreferredDuringSchedulingIgnoreDuringExecution 要求尽量运行在磁盘类型为ssd的节点上
apiVersion v1 kind Pod metadata name with-node-affinity spec affinity nodeAffinity requiredDuringSchedulingIgnoredDuringExecution nodeSelectorTermsmatchExpressionskey beta.kubernetes.io/arch operator In values amd64 preferredDuringSchedulingIgnoredDuringExecutionweight1 preference matchExpressionskey disk-type operator In values ssd containersname with-node-affinity image google/pause
NodeAffinity规则设置的注意事项如下:
- 如果同时定义了nodeSelector和nodeAffinity,name必须两个条件都得到满足,pod才能最终运行在指定的node上。
- 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可。
- 如果在nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有matchExpressions才能运行该pod。
支持一下逻辑运算:
- Exists: 存在
- DoesNotExist:不存在
- In:在
- NotIn:不在
- Gt:大于
- Lt :小于
PodAffinity
PodAffinity主要实现以运行的Pod为参照,实现让新创建的Pod跟参照pod在一个区域的功能。
pod.spec.affinity.podAffinity requiredDuringSchedulingIgnoredDuringExecution 硬限制 namespaces 指定参照pod的namespace topologyKey 指定调度作用域 labelSelector 标签选择器 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist. matchLabels 指多个matchExpressions映射的内容 preferredDuringSchedulingIgnoredDuringExecution 软限制 podAffinityTerm 选项 namespaces topologyKey labelSelector matchExpressions key 键 values 值 operator matchLabels weight 倾向权重,在范围1-100
topologyKey用于指定调度时作用域,例如:
- 如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围
- 如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分
4.2、污点和容忍
在 Kubernetes 中,"污点"(Taints)是一种节点级别的属性,用于标记节点上可能存在的问题或限制。通过给节点添加污点,可以通知调度器不要将新的 Pod 调度到被标记的节点上,除非 Pod 显式声明容忍该污点。
"容忍"(Tolerations)是 Pod 级别的属性,用于告诉调度器该 Pod 是可以容忍某些污点的。当一个节点上存在被 Pod 容忍的污点时,调度器可以将 Pod 调度到该节点上,即使该节点被标记为有污点。
通过污点和容忍的机制,Kubernetes 提供了一种灵活的方式来控制 Pod 的调度行为。以下是关于污点和容忍的一些要点:
- 污点(Taints):
- 污点是在节点上设置的属性,用于标记节点上的限制或问题。
- 污点可以包括键值对,例如 key=value。
- 节点可以设置多个污点。
- 污点可以设置为三种效果:NoSchedule、PreferNoSchedule 和 NoExecute。
- NoSchedule 表示调度器不会将新的非容忍 Pod 调度到带有该污点的节点上。
- PreferNoSchedule 表示调度器会尽量避免将非容忍 Pod 调度到带有该污点的节点上,但可以容忍一定程度的违规。
- NoExecute 表示如果节点上已有 Pod 不容忍该污点,则会驱逐该节点上的 Pod。
- 容忍(Tolerations):
- 容忍是在 Pod 上设置的属性,用于声明该 Pod 可以容忍某些污点。
- 容忍可以包括键值对,例如 key=value。
- Pod 可以声明多个容忍规则,每个规则可以指定容忍的污点和效果。
- 容忍规则可以设置为三种效果:NoSchedule、PreferNoSchedule 和 NoExecute,与污点的效果相对应
通过设置污点和容忍,可以实现以下场景和需求:
- 防止特定类型的 Pod 被调度到特定的节点上(例如,将高消耗资源的任务限制在专用节点上)。
- 将一组相关的 Pod 调度到特定的节点上,以提供局部性和高性能(例如,将数据库 Pod 调度到专用节点上)。
- 在维护或升级节点时,驱逐节点上的 Pod,以确保其他节点上有足够的资源来容纳这些 Pod。
自我理解:
- 污点和容忍度是相互匹配的关系,我们在node上定义一个污点,pod上定义容忍度
- 如果pod能容忍这个污点,就会被调度到拥有这个污点的节点上
- 如果pod不能容忍这个污点,就不会被调度到拥有这个污点的节点上
- 如果node节点上没有定义污点,那么任何pod都会调度到这个节点上
- 我们可以给node节点打一个污点,pod如果不能容忍这个节点上定义的污点,那就调度不到这个节点上
- taints:污点
- 定义在节点上,是键值数据
- tolerations:容忍度
- 定义在pod上,可以定义能容忍哪些污点
- NoSchedule:
仅影响 pod 调度过程,当 pod 能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的 pod 不能容忍了,那这个 pod 会怎么处理,对现存的 pod 对象不产生影响
- NoExecute
既影响调度过程,又影响现存的 pod 对象,如果现存的 pod 不能容忍节点后来加的污点,这个 pod 就会被驱逐
- PreferNoSchedule
最好不,也可以,是 NoSchedule 的柔性版本,如果没有定义容忍度会到这里
使用kubectl设置和去除污点的命令示例如下
# 设置污点kubectl taint nodes node1 key=value:effect # 去除污点kubectl taint nodes node1 key:effect- # 去除所有污点kubectl taint nodes node1 key-
演示
假如现在想对node1的服务器进行下线维护,具体要怎么操作呢?
root@master ~ # kubectl get pod -A -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-flannel kube-flannel-ds-2hknc 1/1 Running 3 (66s ago) 4d23h 192.168.18.100 master <none> <none> kube-flannel kube-flannel-ds-mzbp2 1/1 Running 3 (58s ago) 4d23h 192.168.18.102 node2 <none> <none> kube-flannel kube-flannel-ds-sk284 1/1 Running 3 (62s ago) 4d23h 192.168.18.101 node1 <none> <none> kube-system coredns-7bdc4cb885-7lgxf 1/1 Running 3 (58s ago) 3d22h 10.244.2.19 node2 <none> <none> kube-system coredns-7bdc4cb885-p5v6m 1/1 Running 6 (66s ago) 3d22h 10.244.0.7 master <none> <none> kube-system etcd-master 1/1 Running 3 (66s ago) 4d17h 192.168.18.100 master <none> <none> kube-system kube-apiserver-master 1/1 Running 3 (66s ago) 5d11h 192.168.18.100 master <none> <none> kube-system kube-controller-manager-master 1/1 Running 4 (66s ago) 5d11h 192.168.18.100 master <none> <none> kube-system kube-proxy-94t2t 1/1 Running 2 (62s ago) 3d22h 192.168.18.101 node1 <none> <none> kube-system kube-proxy-9tdsf 1/1 Running 3 (58s ago) 3d22h 192.168.18.102 node2 <none> <none> kube-system kube-proxy-xrvxr 1/1 Running 3 (66s ago) 3d22h 192.168.18.100 master <none> <none> kube-system kube-scheduler-master 1/1 Running 4 (66s ago) 5d11h 192.168.18.100 master <none> <none> kube-system metrics-server-7d8bcdcdb7-t6chm 1/1 Running 2 (62s ago) 3d20h 10.244.1.13 node1 <none> <none> probe nginx-live 1/1 Running 1 (58s ago) 16h 10.244.2.18 node2 <none> <none> probe nginx-ready 0/1 Running 1 (62s ago) 16h 10.244.1.12 node1 <none> <none> probe nginx-start-up 1/1 Running 1 (58s ago) 16h 10.244.2.17 node2 <none> <none>
通过执行kubectl get pod -A -o wide
发现node1上面有pod在上面运行,所以我们不能直接关机下线,需要先把pod迁移走。
kubectl taint node node1 nodetype=production:NoExecute
执行了这句命令之后,node1上的pod会迁移到其他的node上。新建的pod也不会调度到这个node1上。这样就可以安全的下线服务器进行维护
root@master ~ # kubectl get pod -o wide -A NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-flannel kube-flannel-ds-2hknc 1/1 Running 3 (9m59s ago) 4d23h 192.168.18.100 master <none> <none> kube-flannel kube-flannel-ds-mzbp2 1/1 Running 3 (9m51s ago) 4d23h 192.168.18.102 node2 <none> <none> kube-system coredns-7bdc4cb885-7lgxf 1/1 Running 3 (9m51s ago) 3d22h 10.244.2.19 node2 <none> <none> kube-system coredns-7bdc4cb885-p5v6m 1/1 Running 6 (9m59s ago) 3d22h 10.244.0.7 master <none> <none> kube-system etcd-master 1/1 Running 3 (9m59s ago) 4d17h 192.168.18.100 master <none> <none> kube-system kube-apiserver-master 1/1 Running 3 (9m59s ago) 5d11h 192.168.18.100 master <none> <none> kube-system kube-controller-manager-master 1/1 Running 4 (9m59s ago) 5d11h 192.168.18.100 master <none> <none> kube-system kube-proxy-94t2t 1/1 Running 2 (9m55s ago) 3d22h 192.168.18.101 node1 <none> <none> kube-system kube-proxy-9tdsf 1/1 Running 3 (9m51s ago) 3d22h 192.168.18.102 node2 <none> <none> kube-system kube-proxy-xrvxr 1/1 Running 3 (9m59s ago) 3d22h 192.168.18.100 master <none> <none> kube-system kube-scheduler-master 1/1 Running 4 (9m59s ago) 5d11h 192.168.18.100 master <none> <none> kube-system metrics-server-7d8bcdcdb7-g4j4g 1/1 Running 0 85s 10.244.2.20 node2 <none> <none> probe nginx-live 1/1 Running 1 (9m51s ago) 16h 10.244.2.18 node2 <none> <none> probe nginx-start-up 1/1 Running 1 (9m51s ago) 16h 10.244.2.17 node2 <none> <none>
为什么 kube-proxy还能存在node1?
通过执行 kubectl describe pod kube-proxy-94t2t -n kube-system
,发现它的Tolerations
设置了op=Exists
,当容忍规则设置为 op=Exists
时,表示该容忍规则会匹配任何具有指定键的污点。换句话说,只要节点上存在指定键的污点,该容忍规则就会生效。
当node1设备维护好,重新上线时,可以执行如下命令删除污点,这样新建的pod会重新调度到这个node1上
kubectl taint nodes node1 nodetype:NoExecute-
5、容器探针
容器探针(Container Probes)是 Kubernetes 中用于监测和管理容器健康状态的机制。通过使用容器探针,Kubernetes 可以检测容器的活跃性和可用性,并根据探针的结果采取相应的操作,如重启容器、停止服务流量等。
5.1、检查机制
使用探针来检查容器有四种不同的方法。 每个探针都必须准确定义为这四种机制中的一种:
- exec
在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
- grpc
使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC 健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。 gRPC 探针是一个 Alpha 特性,只有在你启用了 “GRPCContainerProbe” 特性门控时才能使用。
- httpGet
对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
- tcpSocket
对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。
每次探测都将获得以下三种结果之一:
- 成功:容器通过了诊断。
- 失败:容器未通过诊断。
- 未知:诊断失败,因此不会采取任何行动。
5.2、探测类型
在 Kubernetes 中,有三种类型的容器探针:
- Liveness Probe(活跃性探针): 活跃性探针用于检测容器是否仍然运行,并且在容器正常运行时返回成功状态。如果活跃性探针失败(即返回失败状态或超过指定的超时时间),Kubernetes 将认为容器不再正常工作,并根据容器重启策略采取相应的操作。
- Readiness Probe(就绪性探针): 就绪性探针用于检测容器是否准备好接收流量。当容器准备好处理请求时,就绪性探针返回成功状态,以指示容器可以开始接收服务流量。如果就绪性探针失败(即返回失败状态或超过指定的超时时间),Kubernetes 将不会将流量路由到该容器,直到探针返回成功状态。
- Startup Probe(启动探针): 启动探针用于检测容器是否已经启动完成。与活跃性和就绪性探针不同,启动探针只在容器启动时运行一次,并且只有在启动探针成功后,Kubernetes 才会考虑容器是活跃和就绪的。启动探针对于那些启动时间较长的容器非常有用,可以确保容器在接收流量之前已经完成了启动过程。
容器探针通常使用 HTTP 请求或 TCP 套接字连接来进行检测。可以指定路径、端口和其他参数来配置探针的行为。探针可以通过设置以下参数进行定义:
- initialDelaySeconds:容器启动后等待开始执行探测的时间。
- periodSeconds:执行连续探测之间的时间间隔。
- timeoutSeconds:探测的超时时间。
- successThreshold:探测成功所需的连续成功次数。
- failureThreshold:探测失败所需的连续失败次数。
5.3、该什么时候使用存活(liveness)和就绪(readiness)探针?
如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据 Pod 的restartPolicy自动执行正确的操作。
如果您希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定restartPolicy为 Always 或 OnFailure。
如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
如果您希望容器能够自行维护,您可以指定一个就绪探针,该探针检查与存活探针不同的端点。
注意:
如果您只想在 Pod 被删除时能够排除请求,则不一定需要使用就绪探针;在删除 Pod 时,Pod 会自动将自身置于未完成状态,无论就绪探针是否存在。当等待 Pod 中的容器停止时,Pod 仍处于未完成状态。
5.4、探针使用介绍
启用探针
apiVersion v1 kind Pod metadata name nginx-start-up namespace probe spec containersname nginx-start-up image nginx latest portscontainerPort80 startupProbe failureThreshold 3 #失败三次算探针失败 exec command'/bin/sh''-c''echo Hello World' initialDelaySeconds 20 #延迟20s后进行第一次探针 periodSeconds 3 #间隔3s进行一次探针 successThreshold 1 #成功一次算探针ok timeoutSeconds 2 #超时2s算失败一次
- nitialDelaySeconds:表示在容器启动后,延时多少秒才开始探测
- periodSeconds:定义的是每间隔多少秒检测一次
[root@master probe]# kubectl get pod -n probeNAME READY STATUS RESTARTS AGE nginx-start-up 1/1 Running 0 43s
就绪探针
apiVersion v1 kind Pod metadata name nginx-ready namespace probe labels app nginx-ready #验证就绪探针的关键参数spec containersname nginx-ready image nginx latest portscontainerPort80 readinessProbe failureThreshold3 tcpSocket port80 initialDelaySeconds20 periodSeconds3 successThreshold1 timeoutSeconds2
[root@master probe]# kubectl get pod -n probe -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ready 1/1 Running 0 2m13s 10.244.1.10 node1 <none> <none> nginx-start-up 1/1 Running 0 6m36s 10.244.2.15 node2 <none> <none>
写一个nodeport类型进行流量验证
apiVersion v1 kind Service metadata name ready-nodeport labels name ready-nodeport namespace probe spec type NodePort portsport88 protocol TCP targetPort80 nodePort30880 selector app nginx-ready
模拟流量结果正常
[root@master probe]# kubectl apply -f ready-nodeport-server.ymlservice/ready-nodeport created [root@master probe]# kubectl get pod,svc -n probeNAME READY STATUS RESTARTS AGE pod/nginx-ready 1/1 Running 0 3m9s pod/nginx-start-up 1/1 Running 0 7m32s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ready-nodeport NodePort 10.96.165.98 <none> 88:30880/TCP 10s [root@master probe]# curl 192.168.18.100:30880<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>
现在修改下就绪探针tcpSocket检测方式的端口为81模拟下探针失败,流量会不会走到该pod
[root@master probe]# kubectl describe nginx-ready -n probe..... Warning Unhealthy 3s (x16 over 48s) kubelet Readiness probe failed: dial tcp 10.244.1.11:81: connect: connection refused [root@master probe]# kubectl get pod -n probeNAME READY STATUS RESTARTS AGE nginx-ready 0/1 Running 0 2m23s nginx-start-up 1/1 Running 0 13m [root@master probe]# curl 192.168.18.100:30880curl: (7) Failed connect to 192.168.18.100:30880; 拒绝连接
存活探针
生成一个nodeport类型service
apiVersion v1 kind Pod metadata name nginx-live namespace probe labels app nginx-live spec containersname nginx-live image nginx latest portscontainerPort80 livenessProbe failureThreshold3 httpGet path / port80 scheme HTTP initialDelaySeconds20 periodSeconds3 successThreshold1 timeoutSeconds2
[root@master probe]# kubectl get pod,svc -n probeNAME READY STATUS RESTARTS AGE pod/nginx-live 1/1 Running 0 2m8s pod/nginx-ready 0/1 Running 0 6m24s pod/nginx-start-up 1/1 Running 0 17m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/live-nodeport NodePort 10.98.147.240 <none> 89:30810/TCP 11s service/ready-nodeport NodePort 10.96.165.98 <none> 88:30880/TCP 10m [root@master probe]# curl 192.168.18.100:30810<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>