【kubernetes】-4 pod资源详解

文章目录

  • pod资源详解
  • 1、pod探针
    • 1.1 pod探针是什么
    • 1.2 我们为什么要用pod探针
    • 1.3 pod探针的种类
      • 1.3.1 startProbe (启动探针)
      • 1.3.2 livenessProbe(存活探针)
      • 1.3.3 redinessProbe(就绪探针)
  • 2、探针实现的方式
    • 2.1 exec方式
    • 2.2 httpGet方式
    • 2.3 tcpSocket方式
    • 2.4 三种方式的区别
    • 2.5 pod节点自愈功能的实现
  • 3、探针的具体实现
    • 3.1 exec方式
    • 3.2 http方式
  • 4、pod容器的资源限制Pod
    • 4.1容器的资源限制
    • 4.2 示例
    • 4.3 QoS服务质量等级
  • 5、生命周期钩子
      • postStart
      • preStop

pod资源详解


1、pod探针

1.1 pod探针是什么

Kubernetes(K8s)集群内的 Pod 探针(Probe)是一种健康检查机制,用于监控容器的运行状态并据此执行相应操作,确保应用的可用性和稳定性。探针通过执行指定的检查(如命令执行、HTTP 请求或 TCP 连接)来评估容器的健康状况。

1.2 我们为什么要用pod探针

使用 Kubernetes(K8s)的 Pod 探针能带来多方面的好处,显著提升应用的可靠性、可用性和运维效率。此外,探针的自定义配置能力(如调整检查周期、超时时间)使运维团队能够根据应用特性定制监控策略,实现精细化管理。通过自动化的健康检查和恢复机制,Pod 探针降低了系统故障概率,提高了资源利用率,是构建弹性云原生应用的重要基石。
当然,我们最终都只有一个目的,就是让提供服务的pod节点,能够稳定,健康,按照正常的轨迹运行下去,让用户在访问的时候尽量减少因为pod的突然出错而影响了正常的体验。

1.3 pod探针的种类

1.3.1 startProbe (启动探针)

startupProbe(启动探针)是为解决长启动时间应用的监控难题而设计的。对于一些需要加载大量数据、执行复杂初始化或依赖外部资源的应用(如数据仓库、机器学习模型服务),传统的存活探针可能会在应用尚未完全启动时就误判为失败,导致容器频繁重启。启动探针通过设置较长的超时时间和重试机制,专门监控应用的启动过程,在此期间会暂时禁用存活探针和就绪探针。一旦启动探针检测到应用成功启动(如特定端口开始接受连接、健康检查接口返回200状态码),后续监控工作将交由其他探针接管。这种分阶段监控策略有效避免了对启动缓慢应用的误杀,确保资源合理利用,提升了系统的稳定性和可靠性。

1.3.2 livenessProbe(存活探针)

livenessProbe(存活探针)是保障容器持续运行的核心机制。它通过定期执行指定的检查(如执行容器内命令、发送HTTP请求或尝试TCP连接)来验证容器是否处于健康状态。当探测失败(如命令返回非零退出码、HTTP请求超时、TCP连接拒绝)时,Kubernetes会自动重启容器,就像自动医生一样,及时发现并处理应用程序内部的故障(如死锁、无限循环),确保服务始终可用。这种自动化恢复机制大大减少了人工干预,特别适合长时间运行且需要高可用性的服务,如数据库、消息队列等。例如,对于一个Node.js应用,存活探针可以定期向应用的健康检查端点发送HTTP请求,若连续多次失败,则触发容器重启,避免服务中断。

1.3.3 redinessProbe(就绪探针)

readinessProbe(就绪探针)负责控制流量分发的精确性。它的核心作用是判断容器是否已经完全准备好接收用户请求,只有当探针检测成功时,Kubernetes才会将该容器添加到Service的负载均衡池中。这在应用启动、升级或依赖服务故障恢复等场景中尤为重要。例如,一个微服务应用启动时需要连接数据库、加载配置文件等操作,就绪探针可以在这些初始化步骤完成后才允许流量进入,避免用户请求被转发到未完全初始化的容器,从而提高整体服务质量。当容器因资源不足或临时故障导致处理能力下降时,就绪探针也能及时将其从流量池中移除,保护系统稳定性。

2、探针实现的方式

Kubernetes(K8s)的Pod探针(Probe)支持三种实现方式,分别是exechttpGettcpSocket,每种方式针对不同的监控场景提供了差异化的检测手段:

2.1 exec方式

exec方式通过在容器内部执行指定命令来判断容器状态。当命令返回状态码为0时,表示容器健康;非零状态码则视为失败。这种方式的优势在于灵活性高,可以执行任何容器内可用的脚本或命令,适合自定义检查逻辑(如验证应用内部状态、检查文件完整性)。例如,通过执行curl localhost:8080/health命令检查应用健康端点,或使用ps -ef | grep myapp验证进程是否运行。但exec方式依赖容器内环境的完整性,若基础工具缺失(如curlbash)可能导致误判,且需要在容器镜像中额外安装监控工具,增加了镜像复杂度。

2.2 httpGet方式

httpGet方式向容器内的指定HTTP路径发送GET请求,根据响应状态码判断健康状态。当返回200-399之间的状态码时视为成功,否则为失败。这种方式的优势在于直接验证应用层响应,无需额外工具,与Web应用天然契合,广泛用于REST API服务的健康检查。例如,向Spring Boot应用的/actuator/health端点发送请求,或检查Nginx服务器的/status页面。此外,httpGet支持自定义请求头(如添加认证信息)和TLS配置,适用于安全要求较高的场景。但它仅能检测HTTP服务,对于非HTTP应用(如TCP服务器、数据库)则不适用。

2.3 tcpSocket方式

tcpSocket方式通过尝试与容器内的指定端口建立TCP连接来判断容器状态。若连接成功建立,探针视为成功;否则失败。这种方式适用于任何基于TCP协议的服务(如MySQL、Redis、SSH),无需应用层提供专门的健康检查接口,只需服务监听在指定端口即可。例如,检查MySQL服务是否正常可通过尝试连接3306端口实现。tcpSocket的优势在于实现简单、开销小,不依赖应用内部逻辑,但它只能验证端口可达性,无法检测服务内部状态(如数据库是否可正常执行查询)。

2.4 三种方式的区别

三种实现方式的核心区别在于检测层次和适用场景:exec基于命令执行结果,适合自定义脚本检查;httpGet聚焦于HTTP应用层响应,直接验证业务逻辑;tcpSocket则关注底层网络连接,适用于所有TCP服务。在实际应用中,需根据容器内运行的应用类型选择合适的探针方式,必要时可组合使用多种方式以实现更全面的监控。

2.5 pod节点自愈功能的实现

在本模块中,我们将集中探讨启动探针与存活探针的搭配使用,以实现pod节点的自愈功能

3、探针的具体实现

3.1 exec方式

  • 1、启动探针
    启动探针yaml文件
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: mytest1
  labels:
    app: nginx1
spec: 
  replicas: 1
  selector: 
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - name: centos7
        image: centos:7
        command: ["/bin/bash","-c","touch /tmp/live;sleep 3600"]
        startupProbe:
          exec:
            command: ["/bin/bash","-c","test -e /tmp/live"]
          #initialDelaySeconds: 1
#表示容器启动之后多少秒之内开启探测
          #periodSeconds: 3
#表示探针执行的间隔时间,即多少秒执行一次
          #failureThreshold: 3
#在pod被标记为不健康时,探测运行的失败次数
          #timeoutSeconds: 3
#探测的超时时间,在多少秒内必须完成探测
          #successThreshold: 1
#判断成功几次任务容器就已就绪

实现的效果,先用命令创建一个live文件,然后用启动探针去检测它,检测成功则能正常启动,检测失败则不能正常启动,检测失败之后经过一定时间会重启pod

  • 2、存活探针
    我们使用启动探针和存活探针搭配使用来实现pod的自愈机制,以下是实现自愈机制的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: mytest1
  labels:
    app: nginx1
spec: 
  replicas: 1
  selector: 
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - name: centos7
        image: centos:7
        command: ["/bin/bash","-c","touch /tmp/live;sleep 3600"]
        startupProbe:
          exec:
            command: ["/bin/bash","-c","test -e /tmp/live"]
        livenessProbe:
          exec:
            command: ["/bin/bash","-c","test -e /tmp/live"]
          initialDelaySeconds: 1
#表示容器启动之后多少秒之内开启探测
          periodSeconds: 3
#表示探针执行的间隔时间,即多少秒执行一次
          failureThreshold: 3
#在pod被标记为不健康时,探测运行的失败次数
          timeoutSeconds: 3
#探测的超时时间,在多少秒内必须完成探测
          successThreshold: 1
#判断成功几次任务容器就已就绪

通过启动探针和存活探针检测命令相同可以实现pod的自愈机制,存活探针检测失败会重启pod,从而重新生成配置文件

3.2 http方式

我们通过存活探针来检验一下,yaml文件如下

apiVersion: apps/v1
kind: Deployment
metadata: 
  name: mytest1
  labels:
    app: nginx1
spec: 
  replicas: 1
  selector: 
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /index.html
          initialDelaySeconds: 1
#表示容器启动之后多少秒之内开启探测
          periodSeconds: 3
#表示探针执行的间隔时间,即多少秒执行一次
          failureThreshold: 3
#在pod被标记为不健康时,探测运行的失败次数
          timeoutSeconds: 3
#探测的超时时间,在多少秒内必须完成探测
          successThreshold: 1
#判断成功几次任务容器就已就绪

检验操作:我们进入容器中删除index.html文件,观察pod容器是否会重启,以及是否会重新生成nginx的index.html的配置文件。

至于就绪探针的实现我们把它放在下一个模块即pod节点服务的高可用中讲解

4、pod容器的资源限制Pod

4.1容器的资源限制

通过 resources.requestsresources.limits 配置资源分配:

  • requests:定义 Pod 容器启动时需预留的资源量。
  • limits:定义 Pod 容器可使用的最大资源量。

资源类型

  • CPU:单位为 m(毫核,如 1000m=1核)或浮点数(如 0.5)。
  • 内存/存储:支持单位 KiMiGi(2 的幂次)或 kMG(10 的幂次),默认单位为字节。
  • GPU:需安装插件支持(如 nvidia.com/gpu)。

关键规则

  • 若容器内存使用超过 limits.memory,会触发 OOM(内存不足)错误,进程被终止。

4.2 示例

apiVersion: v1            # Kubernetes API版本
kind: Pod                # Kubernetes资源类型,这里是Pod
metadata:
  name: frontend         # Pod的名称
spec:
  containers:            # Pod中的容器列表
  - name: web            # 容器的名称
    image: nginx         # 容器使用的镜像
    env:                 # 容器内的环境变量列表
    - name: WEB_ROOT_PASSWORD
      value: "password"  # 环境变量的名称和值
    resources:           # 容器资源请求和限制
      requests:
        memory: "64Mi"   # 请求的内存量
        cpu: "250m"      # 请求的CPU量(250毫核)
      limits:
        memory: "128Mi"  # 限制的内存量
        cpu: "500m"      # 限制的CPU量(500毫核)
  - name: db             # 第二个容器的名称
    image: mysql         # 第二个容器使用的镜像
    env:                 # 第二个容器内的环境变量列表
    - name: MYSQL_ROOT_PASSWORD
      value: "abc123"    # 第二个环境变量的名称和值
    resources:           # 第二个容器的资源请求和限制
      requests:
        memory: "512Mi"  # 请求的内存量
        cpu: "0.5"       # 请求的CPU量(半个核)
      limits:
        memory: "1Gi"    # 限制的内存量
        cpu: "1"         # 限制的CPU量(一个核)
kubectl apply -f pod2.yaml  # 应用YAML文件中定义的Pod到Kubernetes集群
kubectl describe pod frontend  # 显示Pod的详细信息,包括状态、事件和资源使用情况
kubectl get pods -o wide  # 显示集群中所有Pod的详细信息,包括IP地址、所在节点等
# 输出示例:
NAME       READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
frontend   2/2     Running   5          15m   10.244.2.4   node02   <none>           <none>

kubectl describe nodes node02  # 显示指定节点的详细信息,包括资源分配情况
# 输出中的资源分配部分示例(已添加注释):
Namespace                  Name                           CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                           ------------  ----------  ---------------  -------------  ---
  default                    frontend                       500m (25%)    1 (50%)     128Mi (3%)       1024Mi (25%)  # 注意:这里的Memory Limits应为1Gi(1024Mi),可能是输出时的格式问题
  kube-system                kube-flannel-ds-amd64-f4pbp    100m (5%)     100m (5%)   50Mi (1%)        50Mi (1%)     19h
  kube-system                kube-proxy-pj4wp               0 (0%)        0 (0%)      0 (0%)           0 (0%)        19h
# 节点资源分配汇总(已添加注释):
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)  # 总限制可能超过100%,表示资源可能已过度分配
  Resource           Requests    Limits
  --------           --------    ------
  cpu                600m (30%)  1100m (55%)  # CPU请求和限制占总资源的百分比
  memory             178Mi (4%)  1076Mi (26%) # 注意:这里的Memory Limits应为306Mi(frontend的256Mi + 其他的小量)+ kube-flannel和kube-proxy的50Mi = 约306Mi,但frontend的Memory Limits应为1Gi,可能是输出时的汇总问题或格式调整
  ephemeral-storage  0 (0%)      0 (0%)       # 临时存储空间未使用

4.3 QoS服务质量等级

QoS 等级 条件 优先级
Guaranteed 所有容器均设置 requestslimits,且二者相等(如 CPU、内存)。 最高
Burstable 至少一个容器设置了 requests
BestEffort 所有容器均未设置 requestslimits 最低

驱逐顺序BestEffort > Burstable > Guaranteed

  • Guaranteed Pod 在资源不超限时不会被终止。
  • Burstable Pod 在资源紧张且超过 requests 时可能被终止。
  • BestEffort Pod 优先级最低,资源不足时优先被终止。

5、生命周期钩子

通过 lifecycle 配置容器启动和终止时的操作:

  • postStart:容器启动后执行(非主进程)。
  • preStop:容器终止前执行(常用于优雅关闭应用)。

postStart

  • 触发时机:当容器创建后且容器进程启动之前(即容器主进程开始运行但不一定完全准备好接收请求时)。
  • 用途:执行初始化任务,如资源部署、环境配置等。
  • 特点
    • 即使钩子执行失败,容器仍会被启动,Kubelet 不会因此重启容器。
    • 通过 spec.containers[*].lifecycle.postStart 字段配置。

preStop

  • 触发时机:当容器即将被 Kubelet 终止时。
  • 用途:优雅地关闭连接、保存状态或释放资源。
  • 特点
    • 与 SIGTERM 信号异步执行。如果钩子执行时间超过优雅终止期,Kubernetes 将强制终止 Pod。
    • 通过 spec.containers[*].lifecycle.preStop 字段配置。

你可能感兴趣的:(Kubernetes,kubernetes,容器,云原生)