当前位置:首页 > 技术 > 正文内容

Kubernetes 容器资源配置与状态诊断探针深度解析

访客 技术 2026年8月28日 1

容器计算资源配额管理

请求与约束的核心概念

在 Kubernetes 中,Pod 的资源管理依赖于 requests(请求量)和 limits(上限量)两个核心维度。调度器依据 requests 决定 Pod 的目标节点,而 kubelet 则依据 limits 确保容器运行时资源消耗不越界,同时为容器预留 requests 定义的基础资源。

若节点资源充裕,容器实际消耗可以超过 requests,但绝对无法突破 limits 的天花板。此外,Kubernetes 具备默认资源填充机制:若仅设定了 limits 而漏配 requests,系统会自动将 limits 的值同步给 requests。

资源单位解析

  • CPU:以核(Core)为基准单位,1 Core 相当于物理机的 1 个超线程(vCPU)。支持小数表示,如 0.5 代表半核,亦可用毫核表示,如 500m
  • Memory:以字节为基准。支持以10为底的指数单位(K, M, G)和以2为底的指数单位(Ki, Mi, Gi)。其中 1Ki = 1024B,而 1K = 1000B,这在存储容量换算时需特别注意。
  • HugePages:巨页资源(v1.14+ 支持),属于不可超卖资源,一旦分配超限将直接失败。

资源配置实战

以下为一个包含网关与日志收集器的 Pod 资源清单示例:

apiVersion: v1
kind: Pod
metadata:
  name: api-gateway
spec:
  containers:
  - name: gateway-core
    image: registry.example.com/gateway:v2
    resources:
      requests:
        memory: "32Mi"
        cpu: "200m"
      limits:
        memory: "64Mi"
        cpu: "400m"
  - name: sidecar-logger
    image: registry.example.com/logger:v1
    resources:
      requests:
        memory: "32Mi"
        cpu: "200m"
      limits:
        memory: "64Mi"
        cpu: "400m"

OOM 异常排查与调优

当运行内存敏感型应用(如数据库)时,资源上限设置不当极易触发 OOMKilled。部署如下清单:

apiVersion: v1
kind: Pod
metadata:
  name: web-app-pod
spec:
  containers:
  - name: frontend-server
    image: nginx
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: backend-db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "securePass"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

通过 kubectl get pod -o wide -w 监控,会发现 Pod 不断重启,状态在 Running 与 OOMKilled 间震荡。这是因为 128Mi 内存无法满足 MySQL 启动需求。可通过 kubectl describe pod 查看具体事件确认。

在排查内存不足时,常会用到 drop_caches 手动释放系统缓存,但生产环境中强烈不建议随意修改此内核参数。稳定运行的系统 free 内存看似较小,实则是被 Buffer/Cache 高效利用,盲目清空仅能掩盖应用层面的内存泄漏或容量规划问题。

修正方案为提升数据库容器的 limits 阈值:

  - name: backend-db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "securePass"
    resources:
      requests:
        memory: "512Mi"
        cpu: "0.5"
      limits:
        memory: "1Gi"
        cpu: "1"

重新部署后,观察 Node 资源分配占比,若节点总容量为 2C2G,此时 CPU requests 占比约 37%,Limits 占比 75%,内存 requests 占比约 30%,Limits 占比 61%,均在合理范围内。

运行状态诊断探针

探针分类

  • livenessProbe(存活探针):检测容器进程是否存活。失败时 kubelet 将依据重启策略重启容器。
  • readinessProbe(就绪探针):检测服务是否已准备好接收流量。失败时,该 Pod 将从关联 Service 的 Endpoints 列表中剔除。
  • startupProbe(启动探针):用于慢启动应用,在其成功之前,其余两类探针均被屏蔽。若最终失败,容器将被重启。

探测机制与参数

探针支持三种动作:exec(执行命令,返回0为健康)、httpGet(HTTP请求,状态码在200-399区间为健康)、tcpSocket(建立TCP连接成功即为健康)。

关键控制参数:

  • initialDelaySeconds:容器启动后等待多少秒才开始首次探测。
  • periodSeconds:探测周期。
  • failureThreshold:连续失败多少次才认定为最终失败。
  • timeoutSeconds:单次探测超时时间。

Exec 探针实践

通过判断临时文件是否存在来模拟业务状态:

apiVersion: v1
kind: Pod
metadata:
  name: exec-check-pod
spec:
  containers:
  - name: checker
    image: busybox
    command: ["/bin/sh","-c","touch /tmp/health-status; sleep 30; rm -rf /tmp/health-status; sleep 3600"]
    livenessProbe:
      exec:
        command: ["ls", "/tmp/health-status"]
      initialDelaySeconds: 1
      periodSeconds: 3

该 Pod 启动后 30 秒内正常,随后文件被删除,探针失败,触发容器重启。

HTTPGet 探针实践

对 Nginx 默认页面进行存活性检测:

apiVersion: v1
kind: Pod
metadata:
  name: http-probe-pod
spec:
  containers:
  - name: web-server
    image: nginx
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10

当手动进入容器删除 /usr/share/nginx/html/index.html 后,HTTP 请求返回 404,存活探针失败导致 Pod 重启。因镜像本身包含该文件,重启后恢复正常。

TCPSocket 探针实践

以 TCP 端口连通性判断健康状态:

apiVersion: v1
kind: Pod
metadata:
  name: tcp-probe-pod
spec:
  containers:
  - name: web-server
    image: nginx
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 3

由于 Nginx 默认监听 80 端口,8080 端口探测将失败引发重启。将端口修正为 80 后,Pod 即可保持稳定运行。

Readiness 就绪探针与流量控制

就绪探针直接影响 Service 的流量转发。配置一个探测不存在的路径:

apiVersion: v1
kind: Pod
metadata:
  name: http-ready-check
spec:
  containers:
  - name: web-server
    image: nginx
    readinessProbe:
      httpGet:
        port: 80
        path: /ready.html
      initialDelaySeconds: 1
      periodSeconds: 3
    livenessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3

此时 Pod 处于 Running 但非 Ready 状态。使用 kubectl exec 创建对应文件后,就绪探针通过,Pod 进入 Ready 状态。

结合 Service 的多副本场景,更能体现就绪探针的价值:

apiVersion: v1
kind: Pod
metadata:
  name: web-a
  labels:
    app: web-cluster
spec:
  containers:
  - name: nginx
    image: nginx
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
---
# 省略 web-b, web-c 类似配置
---
apiVersion: v1
kind: Service
metadata:
  name: web-cluster-svc
spec:
  selector:
    app: web-cluster
  ports:
  - port: 80
    targetPort: 80

若删除 web-a 中的 /index.html,其就绪探针将失败,Service 会自动将 web-a 从 Endpoints 中剥离,停止向其分发请求,保证业务可用性。

容器生命周期钩子

Kubernetes 提供了 postStartpreStop 钩子,分别在容器创建后和终止前执行。结合 initContainers 可以观察执行顺序:

apiVersion: v1
kind: Pod
metadata:
  name: hook-demo-pod
spec:
  containers:
  - name: main-app
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","echo 'Hook postStart executed' >> /var/log/nginx/app.log"]
      preStop:
        exec:
          command: ["/bin/sh","-c","echo 'Hook preStop executed' >> /var/log/nginx/app.log"]
    volumeMounts:
    - name: app-logs
      mountPath: /var/log/nginx/
  initContainers:
  - name: init-setup
    image: nginx
    command: ["/bin/sh","-c","echo 'Init container setup' >> /var/log/nginx/app.log"]
    volumeMounts:
    - name: app-logs
      mountPath: /var/log/nginx/
  volumes:
  - name: app-logs
    hostPath:
      path: /data/volumes/app/log/
      type: DirectoryOrCreate

容器启动后查看日志,输出顺序为:Init container setup -> Hook postStart executed。当 Pod 被终止时,日志中会追加 Hook preStop executed。需注意,postStart 与容器入口点并行触发,若其阻塞过长,可能导致容器无法进入 Running 状态。

标签: Kubernetes

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。