前言

本文聚焦 Kubernetes Pod 管理核心要点,详解资源限制、健康检查、Pod 状态及容器生命周期,助力实现容器化应用稳定调度与高效运维。


一、资源限制

1、概述

在 Kubernetes 中,为了合理管理集群中的资源,容器的 CPU 和内存资源都可以设置请求值(requests)和限制值(limits)。这些设置确保了容器的资源分配和限制,避免资源争用和过度使用。
资源请求与限制(Request & Limit):
请求(request):当容器启动时,Kubernetes 会根据容器的资源请求来决定容器应该调度到哪个节点上。这个值表示容器在运行时最少需要的资源。
限制(limit):容器在运行时可以使用的最大资源量。如果容器超过了这个限制,Kubernetes 会采取措施来控制容器的资源使用,防止过度消耗。
针对资源限制的示例,可以从官网获取
https://kubernetes.io/docs/concepts/configuration/manage-compute-resourcescontainer/

# Pod 和 容器 的资源请求和限制
spec.containers[].resources.requests.cpu //定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory //定义创建容器时预分配的内存资源
spec.containers[].resources.limits.cpu //定义 cpu 的资源上限
spec.containers[].resources.limits.memory //定义内存的资源上限

2、cpu资源单位

2.1、cpu资源单位

在 Kubernetes 中,CPU 的单位表示方式如下:

  • 1 CPU = 1 vCPU(或 1 核心超线程)
  • CPU 请求和限制使用 “m”(毫核)作为单位。
    例如: 500m 表示半个 CPU, 100m 表示 0.1 个 CPU, 1 表示一个完整的 CPU。
  • 带小数的 CPU 也是支持的,表示容器能获得的 CPU 时间片。例如, 0.25 表示该容器最多可以使用一个 CPU的四分之一。

2.2、内存资源单位

内存的单位有两种表示方式:
十进制单位:如 1Gi , 1Mi , 1Ki ,分别为 1024Mi , 1024Ki 。Kubernetes 的内存限制通常使用这些基于 2 的指数单位。
十进制单位:如 1GB , 1MB 等,表示为以 10 为底的单位。
需要注意的是,在存储设备中,标示的单位(如GB)是基于十进制,而操作系统通常使用二进制单位(如GiB)。因此,1 GiB 的内存比 1 GB 多出大约 73MB。

2.3、Pod示例

示例 1:资源请求和限制配置
需求如下:

  • 每个容器的 请求资源 是: 0.25 CPU 和 64Mi 内存。
  • 每个容器的 限制资源 是: 0.5 CPU 和 128Mi 内存。
  • 该 Pod 的 总请求资源 为 0.5 CPU 和 128Mi 内存。
  • 该 Pod 的 总限制资源 为 1 CPU 和 256Mi 内存。
apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: n1
    image: nginx:1.14
    # 添加启动命令,让nginx前台运行
    command: ["/usr/sbin/nginx", "-g", "daemon off;"]
    resources:
      requests:
        memory: "64Mi" # 最少 64Mi 内存
        cpu: "250m" # 最少 0.25 CPU
      limits: 
        memory: "128Mi" # 最大 128Mi 内存
        cpu: "500m" # 最大 0.5 CPU

查看容器设置的限制:
kubectl describe pod frontend
在这里插入图片描述

2.4、调度和资源分配

当 Kubernetes 调度 Pod 时,它会根据容器的资源请求( requests )来选择适合的节点。调度器会尝试确保节点有足够的资源来满足这些请求。如果节点上的资源不够,调度器会将 Pod 调度到其他可用节点。

# 创建容器
kubectl apply -f test.yaml
kubectl describe pod frontend
# 查看Pod分配资源情况
kubectl get pods -o wide
# 查看节点资源:
kubectl describe nodes node01

此命令展示了节点的资源使用情况。你可以看到该节点上各个 Pod 的请求与限制占用了多少资源,以及节点剩余的资源。
在这里插入图片描述

2.5、小结

1)资源请求与限制:
requests 是容器启动时最少需要的资源,调度器依据该值选择节点。
limits 是容器能够使用的最大资源值,超出该值的资源请求会被限制。
2)自动匹配:
如果未设置 requests ,Kubernetes 会自动将其设置为与 limits 相同。
3)资源的分配
Pod 中多个容器的资源请求与限制会被加总,以便监控和调整节点的资源分配。
4)资源单位:
CPU 使用 m (毫核)表示,例如: 500m 表示 0.5 个 CPU。
内存 使用标准的字节单位表示,通常推荐使用基于 2 的指数单位,如 Gi , Mi 等。

二、健康检查(Probe)

探针是由kubelet对容器执行的定期诊断。

1、探针的三种规则

  • livenessProbe :判断容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据restartPolicy 来设置 Pod 状态。 如果容器不提供存活探针,则默认状态为Success。
  • readinessProbe :判断容器是否准备好接受请求。如果探测失败,端点控制器将从与 Pod 匹配的所有 service 址endpoints 中剔除删除该Pod的IP地。 初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。
  • startupProbe(这个1.17版本增加的):判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。如果配置了 startupProbe 探测,在则在 startupProbe 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。 如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe, 则默认状态为 Success。

注意:以上规则可以同时定义。在readinessProbe检测成功之前,Pod的running状态是不会变成ready状态的。

2、 Probe支持三种检查方法

  • exec :在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
  • tcpSocket :对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的。
  • httpGet :对指定的端口和路径上的容器的IP地址执行HTTPGet请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的

3、 每次探测都将获得以下三种结果之一

  • 成功:容器通过了诊断。
  • 失败:容器未通过诊断。
  • 未知:诊断失败,因此不会采取任何行动

4、探针测试实战

4.1、探针示例官网地址

官方示例地址如下:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

4.2、livenessProbe的exec方式

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
      - /bin/sh
      - -c
      - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
    livenessProbe:
      exec:
        command: 
        - cat
        - /tmp/healthy
      failureThreshold: 1
      initialDelaySeconds: 5
      periodSeconds: 5

4.3、readinessProbe的httpGet方式

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
    initialDelaySeconds: 1
    periodSeconds: 3
  livenessProbe:
    httpGet:
      port: http
        path: /index.html
    initialDelaySeconds: 1
    periodSeconds: 3
    timeoutSeconds: 10

三、pod状态

1、pending:pod已经被系统认可了,但是内部的container还没有创建出来。这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。
2、Running:pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。–这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。
3、Succeeded:这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。
4、Failed:pod中的所有容器都被terminated,至少一个container是非正常终止的。(退出的时候返回了一个非0的值或者是被系统直接终止)
5、unknown:由于某些原因pod的状态获取不到,有可能是由于通信问题。 一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态

四、Container生命周期

1、Waiting:启动到运行中间的一个等待状态。
2、Running:运行状态。
3、Terminated:终止状态。
如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。 但如果长时间处于Waiting状态,container会有一个字段reason表明它所处的状态和原因,如果这个原因很容易能标识这个容器再也无法启动起来时,例如ContainerCannotRun,整个服务启动就会迅速返回。(这里是一个失败状态返回的特性,不详细阐述)


总结

本文系统梳理 K8s Pod 资源管控、健康探测、状态监控及生命周期管理要点,为容器部署优化与故障排查提供实操指引。

更多推荐