一、Pod 常用内置字段有哪些¶
Pod 里有一类非常实用的“内置字段”,经常用于动态注入运行信息。
1. metadata 相关¶
最常见的是:
metadata.namemetadata.namespacemetadata.uidmetadata.labelsmetadata.annotations
这些字段通常用于:
- 日志与监控标识
- 多环境区分
- Service 筛选和版本标记
- 构建信息透传
2. spec 相关¶
例如:
spec.nodeNamespec.serviceAccountName
这类字段更偏运行和权限控制,例如:
- 把 Pod 固定到某台节点
- 指定访问 API Server 所使用的服务账号
3. status 相关¶
例如:
status.hostIPstatus.hostIPsstatus.podIPstatus.podIPs
它们在日志采集、节点关联和双栈网络场景里都很实用。
二、如何给 Pod 配置环境变量¶
除了手工写死环境变量,Pod 还支持通过 fieldRef 动态注入自身信息。
示例:
apiVersion: v1
kind: Pod
metadata:
name: pod-env
labels:
run: pod-env
environment: test
annotations:
build-info: "commit=abc123"
monitor/path: "/metrics"
spec:
nodeName: k8s-node02
serviceAccountName: pod-sa
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
name: pod-env
env:
- name: ENV
value: test
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
先准备 ServiceAccount:
kubectl create serviceaccount pod-sa
再应用 YAML:
kubectl apply -f pod-env.yaml
进入 Pod 验证:
kubectl exec pod-env -- env
这类能力本质上就是 Downward API:把 Pod 自己的元数据和运行态信息注入给容器。
三、镜像拉取策略为什么经常被忽略¶
Pod 常见的 imagePullPolicy 有三种:
AlwaysIfNotPresentNever
默认行为通常是:
- 如果镜像标签是
latest,往往倾向于Always - 如果标签是明确版本,默认通常是
IfNotPresent
示例:
imagePullPolicy: Always
然后可以通过:
kubectl describe po nginx
查看实际拉取情况。
四、为什么“节点上明明有镜像”,Pod 还是拉不到¶
这类问题在 Kubernetes 里非常常见,通常有四种原因。
1. 镜像只在单个节点存在¶
如果镜像只导入到了某一台节点,而 Pod 被调度到了别的节点,就会出现“明明有镜像却拉不到”的现象。
2. Docker 和 Containerd 的镜像存储隔离¶
即使你用 docker load 导入成功,也不代表 kubelet 能用到这份镜像。因为很多 Kubernetes 集群实际用的是 Containerd:
- Docker 镜像常在
/var/lib/docker - Containerd 镜像常在
/var/lib/containerd
所以常见处理方式是:
docker save myimage:tag > myimage.tar
ctr -n=k8s.io images import myimage.tar
3. Containerd 命名空间不对¶
Kubernetes 默认只会读取 k8s.io 命名空间里的镜像。
错误做法:
ctr images import image.tar
正确做法:
ctr -n=k8s.io images import image.tar
排查时可以对比:
ctr -n=k8s.io images ls
ctr -n=default images ls
4. Always 导致强制远程拉取¶
即使本地有镜像,只要策略是 Always,仍可能继续尝试从远端仓库拉取。如果私有仓库认证失败或网络不通,Pod 依然会报错。
这也是为什么很多生产环境更倾向于固定版本标签加 IfNotPresent。
五、Pod 的重启策略怎么理解¶
Pod 的 restartPolicy 常见有三种:
AlwaysOnFailureNever
含义分别是:
Always:默认策略,容器退出就尝试拉起OnFailure:只有非 0 退出码才重启Never:无论什么情况都不自动重启
示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
command: ["sleep","4"]
imagePullPolicy: Always
restartPolicy: OnFailure
如果命令正常结束,Pod 往往会显示 Completed,而不会像 Always 那样循环重启。
六、重启策略和镜像拉取策略不要混淆¶
这两个词很像,但控制的完全不是一回事:
restartPolicy决定“容器退出后要不要重启”imagePullPolicy决定“容器启动前要不要重新拉镜像”
一个控制运行时行为,一个控制拉取镜像行为。
七、这部分配置最常见的实战建议¶
如果把这一篇内容收敛成几条实战建议,大概就是:
- 环境变量优先用 YAML 明确管理,不要大量写死在镜像里
- 需要读取 Pod 自身信息时,优先考虑
fieldRef - 生产环境尽量使用明确镜像版本,不要滥用
latest - 使用 Containerd 的集群,导入镜像时注意
k8s.io命名空间 - 分清
restartPolicy和imagePullPolicy,排障时不要混为一谈
这样做能避免很多“看起来像容器问题,实际是配置问题”的低级坑。