容器怎么知道自己叫什么、跑在哪个节点、有多少 CPU?环境变量和卷里的 Downward API 有什么区别?改了标签,容器里能看到吗?没写 limits 会得到什么?这篇把所有支持的写法和拒绝的写法都跑一遍。
POD_NAME = me POD_NS = k105 POD_UID = 11ee8209-ac71-4533-a7e5-5e83b29c2681 NODE_NAME = kx-main-worker SA_NAME = default POD_IP = 10.244.1.149 HOST_IP = 172.18.0.2 LABEL_APP = demo ANN_OWNER = team-a 对照 Pod 对象:uid=11ee8209-ac71-4533-a7e5-5e83b29c2681;podIP=10.244.1.149;hostIP=172.18.0.2
能直接读的:metadata.name → POD_NAME=me、metadata.namespace → k105、metadata.uid(与 Pod 对象一致)、spec.nodeName → kx-main-worker、spec.serviceAccountName → default、status.podIP → 10.244.1.149、status.hostIP → 172.18.0.2;单个标签和注解也可以:metadata.labels['app'] → demo、metadata.annotations['owner'] → team-a。全程不用调 API Server,也不需要 RBAC 和令牌。
CPU_LIMIT = 1 (limits.cpu(默认 divisor 1,向上取整成核)) CPU_LIMIT_M = 500 (limits.cpu, divisor: 1m) MEM_LIMIT = 134217728 (limits.memory(默认字节)) MEM_LIMIT_MI = 128 (limits.memory, divisor: 1Mi) MEM_REQ_MI = 64 (requests.memory, divisor: 1Mi) 没有写 limits 的容器:CPU_LIMIT_M=10000、MEM_LIMIT_MI=7935——退回节点的 allocatable(节点 cpu=10 核、memory=8124516Ki),不是 0 或空
容器 limits.cpu 是 500m:默认 divisor 下 CPU_LIMIT=1(向上取整成核),divisor: 1m 时 CPU_LIMIT_M=500;limits.memory 是 128Mi:默认 MEM_LIMIT=134217728(字节),divisor: 1Mi 时 MEM_LIMIT_MI=128,requests.memory 的 MEM_REQ_MI=64。没有写 limits 的容器:CPU_LIMIT_M=10000、MEM_LIMIT_MI=7935,正好是节点的 allocatable(10 核、8124516Ki),不是 0 或空——所以应用按这个数字调线程数时,没设 limit 的容器会把整个节点当成自己的。
/etc/podinfo/labels:['app="demo"', 'tier="web"'];annotations:['owner="team-a"'];cpu_limit=500 用 kubectl label 把 tier 改成 db 并新增 extra=yes:文件 1 秒后变化:['app="demo"', 'extra="yes"', 'tier="db"'] 同一时刻环境变量 LABEL_TIER 仍是 'web'(创建时的值),而文件里已经是 tier="db"——环境变量在容器启动时一次性取值;要看到变化就得读卷里的文件 文件路径是符号链接:annotations -> ..data/annotations;cpu_limit -> ..data/cpu_limit;labels -> ..data/labels(同 ConfigMap 的 ..data 原子切换)
downwardAPI 卷里的文件:labels 是 app="demo"、tier="web" 每行一个,annotations 里有 owner="team-a",cpu_limit 是 500。用 kubectl label 把 tier 改成 db 并新增 extra=yes:文件 1 秒后变成 app="demo"、extra="yes"、tier="db";而环境变量 LABEL_TIER 仍是创建时的 web。文件路径是 ..data 下的符号链接,更新是原子切换。与 ConfigMap 挂载常见的 60~90 秒延迟(见 k56)不同,这里约 1 秒就同步了。
环境变量 fieldPath: metadata.labels(整个 map,环境变量里):退出码 1;The Pod "bad" is invalid: spec.containers[0].env[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.hostIPs", "status.podIP", "status.podIPs" 环境变量 fieldPath: status.phase:退出码 1;The Pod "bad" is invalid: spec.containers[0].env[0].valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.hostIPs", "status.podIP", "status.podIPs" 环境变量 fieldPath: spec.containers[0].name:退出码 1;The Pod "bad" is invalid: spec.containers[0].env[0].valueFrom.fieldRef.fieldPath: Invalid value: "spec.containers[0].name": error converting fieldPath: field label not supported: spec.containers[0].name 环境变量 fieldPath: metadata.name 拼写错 metadata.nam:退出码 1;The Pod "bad" is invalid: spec.containers[0].env[0].valueFrom.fieldRef.fieldPath: Invalid value: "metadata.nam": error converting fieldPath: field label not supported: metadata.nam 卷里写 status.phase:退出码 1;* spec.volumes[0].downwardAPI.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.annotations", "metadata.labels", "metadata.name", "metadata.namespace", "metadata.uid"
不支持的写法在创建时就被拒:环境变量 fieldPath: metadata.labels(整个 map)→ Unsupported value,supported values 只有 metadata.name、metadata.namespace、metadata.uid、spec.nodeName、spec.serviceAccountName、status.hostIP(s)、status.podIP(s);status.phase 同样被拒;spec.containers[0].name、拼错的 metadata.nam 报 field label not supported。卷里支持的 fieldPath 是另一张表:metadata.annotations、metadata.labels、metadata.name、metadata.namespace、metadata.uid,写 status.phase 被拒。要别的信息,还得调 API Server(并配 RBAC)。