Downward API 是什么
Downward API 让容器在不访问 API Server、不持有任何 RBAC 权限的情况下拿到自己的运行上下文:Pod 名、命名空间、Pod IP、节点名、容器资源 requests 与 limits 等。它有两种暴露形式,环境变量(fieldRef、resourceFieldRef)与卷文件(downwardAPI volume),前者在容器启动时固化,后者会周期性同步。
典型使用场景
- 日志打标:用 metadata.name 与 metadata.namespace 给每行日志加来源,日志平台按 Pod 名聚合时不需额外解析
- 服务自注册:启动脚本把 status.podIP 与容器端口写入注册中心,避免硬编码地址
- 就地感知配额:用 resourceFieldRef 读到本容器的 limits.cpu,据此计算线程池或堆大小
- 区分环境:用 metadata.labels 里的 env 值决定加载哪份配置,同一镜像跨环境复用
- 拓扑提示:用 spec.nodeName 记录 Pod 落在哪台机器,便于排查节点级问题
环境变量形式
环境变量形式
env:
- name: MY_POD_NAME
valueFrom:
fieldRef: {fieldPath: metadata.name} # Pod 名
- name: MY_POD_IP
valueFrom:
fieldRef: {fieldPath: status.podIP} # Pod IP,非容器 IP
- name: MY_NODE_NAME
valueFrom:
fieldRef: {fieldPath: spec.nodeName} # 所在节点名
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: app # 必须指定容器名
resource: limits.cpu # 必须带 limits. 或 requests. 前缀
divisor: '1m' # 可选:换算单位常用 fieldPath
| 字段 | 含义 | 备注 |
|---|---|---|
| metadata.name | Pod 名称 | 与 hostname 一致,日志打标最常用 |
| metadata.namespace | Pod 所在命名空间 | 跨命名空间聚合日志时必需 |
| metadata.labels['app'] | 指定标签的值 | 标签不存在且未标 optional 时容器启动失败 |
| metadata.annotations['x'] | 指定注解的值 | 适合传发布版本号等附加信息 |
| status.podIP | Pod IP | 重建后会变化,不要持久化 |
| status.hostIP | 节点 IP | 排查节点网络时有用 |
卷形式(会周期性更新)
卷形式(会周期性更新)
volumes:
- name: podinfo
downwardAPI:
items:
- path: labels
fieldRef: {fieldPath: metadata.labels}
- path: cpu_limit
resourceFieldRef: {containerName: app, resource: limits.cpu}两种形式对比
| 维度 | 环境变量 | 卷文件 |
|---|---|---|
| 取值时机 | 容器启动时一次性固化 | 创建后周期刷新(kubelet 同步) |
| 标签/注解变化 | 不会反映 | 会反映到文件内容 |
| 重启需求 | 需要重建 Pod 才能拿到新值 | 通常不需要重启即可读到 |
| 读取方式 | 进程读环境变量即可 | 应用需实现文件监听或重读 |
resourceFieldRef 必须写 containerName 与 requests. 或 limits. 前缀,缺任一项都会被 API Server 直接拒绝;divisor 用于把 CPU 从核转换成 milli、把内存从字节转换成 Mi/Gi,写错会得到量级完全不同的值。