K8s入门基础篇:资源对象Pod的基本用法

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测可视化 Grafana 版,10个用户账号 1个月
简介: K8s入门基础篇:资源对象Pod的基本用法

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
        HttpHeaders:        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式         port: number
       initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒       timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒       periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次       successThreshold: 0 #成功多少次,任务他成功了       failureThreshold: 0 #失败多少次,任务他失败了       securityContext: #安全上下文         privileged: false  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  
      items:           - key: string
        path: string
    configMap:         #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部      name: string
      items:      - key: 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启动流程

  1. APIServer将pod信息存入etcd,通知Scheduler。
  2. Scheduler根据调度算法,为pod选择一个节点,然后向APIServer发送更新spec.nodeName。
  3. APIServer更新完毕,通知对应节点的kubelet。
  4. kubelet发现pod调度到本节点,创建并运行pod的容器。

3、容器重启策略

容器重启策略是指在容器出现故障或终止后,Kubernetes 如何处理容器的重新启动。以下是 Kubernetes 中常见的容器重启策略:

  1. Always(始终重启): 当容器终止或出现故障时,Kubernetes 会立即重启该容器。这是默认的重启策略。使用这种策略时,Kubernetes 将尝试持续重启容器,直到其成功运行或手动删除。
  2. OnFailure(仅在故障时重启): 当容器终止并以非零退出代码结束时,Kubernetes 会重启该容器。如果容器正常终止(退出代码为零),则不会进行重启。这种策略适用于需要故障恢复的容器。
  3. 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的全新调度策略。目前有两种节点节点亲和性表达:

  1. RequiredDuringSchedulingIgnoredDuringExecution:必须满足制定的规则才可以调度pode到Node上。相当于硬限制
  2. PreferredDuringSchedulingIgnoreDuringExecution:强调优先满足制定规则,调度器会尝试调度pod到Node上,但并不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义执行的先后顺序。

下面的例子设置了NodeAffinity调度的如下规则:

  1. RequiredDuringSchedulingIgnoredDuringExecution 要求只运行在amd64的节点上
  2. PreferredDuringSchedulingIgnoreDuringExecution 要求尽量运行在磁盘类型为ssd的节点上
apiVersion: v1
kind: Pod
metadata:  name: with-node-affinity
spec:  affinity:    nodeAffinity:      requiredDuringSchedulingIgnoredDuringExecution:        nodeSelectorTerms:        - matchExpressions:          - key: beta.kubernetes.io/arch
            operator: In
            values:            - amd64
      preferredDuringSchedulingIgnoredDuringExecution:      - weight: 1        preference:          matchExpressions:          - key: disk-type
            operator: In
            values:            - ssd
  containers:  - name: 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 的调度行为。以下是关于污点和容忍的一些要点:

  1. 污点(Taints):
  • 污点是在节点上设置的属性,用于标记节点上的限制或问题。
  • 污点可以包括键值对,例如 key=value。
  • 节点可以设置多个污点。
  • 污点可以设置为三种效果:NoSchedule、PreferNoSchedule 和 NoExecute。
  • NoSchedule 表示调度器不会将新的非容忍 Pod 调度到带有该污点的节点上。
  • PreferNoSchedule 表示调度器会尽量避免将非容忍 Pod 调度到带有该污点的节点上,但可以容忍一定程度的违规。
  • NoExecute 表示如果节点上已有 Pod 不容忍该污点,则会驱逐该节点上的 Pod。
  1. 容忍(Tolerations):
  • 容忍是在 Pod 上设置的属性,用于声明该 Pod 可以容忍某些污点。
  • 容忍可以包括键值对,例如 key=value。
  • Pod 可以声明多个容忍规则,每个规则可以指定容忍的污点和效果。
  • 容忍规则可以设置为三种效果:NoSchedule、PreferNoSchedule 和 NoExecute,与污点的效果相对应

通过设置污点和容忍,可以实现以下场景和需求:

  • 防止特定类型的 Pod 被调度到特定的节点上(例如,将高消耗资源的任务限制在专用节点上)。
  • 将一组相关的 Pod 调度到特定的节点上,以提供局部性和高性能(例如,将数据库 Pod 调度到专用节点上)。
  • 在维护或升级节点时,驱逐节点上的 Pod,以确保其他节点上有足够的资源来容纳这些 Pod。

自我理解

  • 污点和容忍度是相互匹配的关系,我们在node上定义一个污点,pod上定义容忍度
  1. 如果pod能容忍这个污点,就会被调度到拥有这个污点的节点上
  2. 如果pod不能容忍这个污点,就不会被调度到拥有这个污点的节点上
  • 如果node节点上没有定义污点,那么任何pod都会调度到这个节点上
  • 我们可以给node节点打一个污点,pod如果不能容忍这个节点上定义的污点,那就调度不到这个节点上
  • taints:污点
  1. 定义在节点上,是键值数据
  • tolerations:容忍度
  1. 定义在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 中,有三种类型的容器探针:

  1. Liveness Probe(活跃性探针): 活跃性探针用于检测容器是否仍然运行,并且在容器正常运行时返回成功状态。如果活跃性探针失败(即返回失败状态或超过指定的超时时间),Kubernetes 将认为容器不再正常工作,并根据容器重启策略采取相应的操作。
  2. Readiness Probe(就绪性探针): 就绪性探针用于检测容器是否准备好接收流量。当容器准备好处理请求时,就绪性探针返回成功状态,以指示容器可以开始接收服务流量。如果就绪性探针失败(即返回失败状态或超过指定的超时时间),Kubernetes 将不会将流量路由到该容器,直到探针返回成功状态。
  3. 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:  containers:  - name: nginx-start-up
    image: nginx:latest
    ports:    - containerPort: 80    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:  containers:  - name: nginx-ready
    image: nginx:latest
    ports:    - containerPort: 80    readinessProbe:      failureThreshold: 3      tcpSocket:        port: 80      initialDelaySeconds: 20      periodSeconds: 3      successThreshold: 1      timeoutSeconds: 2
[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
  ports:  - port: 88    protocol: TCP
    targetPort: 80    nodePort: 30880  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:  containers:  - name: nginx-live
    image: nginx:latest
    ports:    - containerPort: 80    livenessProbe:      failureThreshold: 3      httpGet:        path: /
        port: 80        scheme: HTTP
      initialDelaySeconds: 20      periodSeconds: 3      successThreshold: 1      timeoutSeconds: 2
[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>
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
7天前
|
运维 Kubernetes 监控
Kubernetes详解(十九)——Kubernetes Pod控制器
Kubernetes详解(十九)——Kubernetes Pod控制器
25 3
|
12天前
|
运维 Kubernetes 网络协议
Kubernetes详解(十六)——Pod容器探测
Kubernetes详解(十六)——Pod容器探测
41 1
|
13天前
|
运维 Kubernetes 网络协议
Kubernetes详解(十六)——Pod容器探测
Kubernetes详解(十六)——Pod容器探测
25 0
|
3天前
|
Kubernetes 算法 调度
k8s群集调度之 pod亲和 node亲和 标签指定
k8s群集调度之 pod亲和 node亲和 标签指定
|
12天前
|
运维 Kubernetes 网络协议
Kubernetes详解(十八)——Pod就绪性探针实战
Kubernetes详解(十八)——Pod就绪性探针实战
48 5
|
12天前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes详解(十七)——Pod存活性探针应用实战
Kubernetes详解(十七)——Pod存活性探针应用实战
31 4
|
13天前
|
运维 Kubernetes 网络协议
Kubernetes详解(十八)——Pod就绪性探针实战
Kubernetes详解(十八)——Pod就绪性探针实战
35 3
|
13天前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes详解(十七)——Pod存活性探针应用实战
Kubernetes详解(十七)——Pod存活性探针应用实战
29 3
|
14天前
|
Kubernetes API 调度
Kubernetes详解(十五)——Pod对象创建过程
Kubernetes详解(十五)——Pod对象创建过程
35 5
|
14天前
|
Kubernetes API 调度
Kubernetes详解(十四)——Pod对象生命周期
Kubernetes详解(十四)——Pod对象生命周期
26 2

相关产品

  • 容器服务Kubernetes版