一、先看懂 Pod YAML 的基本骨架

一个 Pod 最核心的结构通常长这样:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.23

这里最重要的三个层次是:

  • apiVersion:指定资源所属的 API 版本
  • kind:指定资源类型,这里是 Pod
  • metadataspec:前者描述身份信息,后者描述期望运行方式

二、基础元数据怎么写

metadata 的核心作用,是告诉 Kubernetes“这个对象是谁,归谁管,怎么被识别”。

最常用的字段包括:

  • name:Pod 名称,在同一命名空间内必须唯一
  • namespace:Pod 所属命名空间,默认是 default
  • labels:标签,用于筛选、分组和被 Service、Deployment 等对象关联
  • annotations:注解,适合放监控、构建信息或其他非识别性元数据

示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
  labels:
    app: nginx
    env: prod
  annotations:
    monitor: "true"

如果只记一个原则:labels 负责“筛选和关联”,annotations 负责“补充说明”。

三、容器配置是 Pod 最核心的部分

真正决定 Pod 如何运行的核心,在 spec.containers

1. image

用来指定容器镜像地址,例如:

image: nginx:1.23

2. commandargs

它们用来覆盖镜像的默认启动命令和参数:

  • command 类似 Docker 的 ENTRYPOINT
  • args 类似 Docker 的 CMD

例如:

command: ["/bin/sh", "-c"]
args: ["nginx -g 'daemon off;'"]

3. ports

它只是声明容器暴露的端口,方便理解和文档化,不等于自动对外发布流量。真正的服务访问,通常还需要 Service

ports:
- containerPort: 80
  protocol: TCP

4. env

用于定义环境变量,可以写死,也可以从 ConfigMap 或其他来源注入:

env:
- name: ENV_MODE
  value: "production"
- name: DB_HOST
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: db.host

5. resources

它决定调度和运行时资源边界:

resources:
  requests:
    cpu: "100m"
    memory: "256Mi"
  limits:
    cpu: "500m"
    memory: "1Gi"

其中:

  • requests 是调度依据,表示至少要给我多少资源
  • limits 是运行上限,表示最多只能用多少资源

6. livenessProbereadinessProbe

健康检查字段虽然写在容器配置里,但它们影响的是 Pod 能否稳定运行和接入流量:

  • livenessProbe 失败后会触发重启
  • readinessProbe 失败后会从 Service 后端摘除

示例:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10
readinessProbe:
  exec:
    command: ["/bin/sh", "-c", "curl localhost:8080/ready"]

四、存储和卷挂载怎么配

Pod 级存储的核心是 volumes,容器内挂载的核心是 volumeMounts

volumes:
- name: app-data
  persistentVolumeClaim:
    claimName: pvc-app-data

containers:
- name: app
  volumeMounts:
  - name: app-data
    mountPath: /var/data

可以把它理解为:

  • volumes 负责先声明“Pod 有哪些存储资源”
  • volumeMounts 负责再声明“某个容器把哪个卷挂到哪里”

五、调度到哪台节点,也能在 YAML 里控制

Pod 并不是完全随机调度的,常见调度控制方式有三种。

1. nodeSelector

通过节点标签直接选节点:

nodeSelector:
  disktype: ssd
  region: east

2. tolerations

允许 Pod 调度到带特定污点的节点:

tolerations:
- key: "gpu"
  operator: "Exists"
  effect: "NoSchedule"

3. affinity

用于更复杂的亲和性和反亲和性策略:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values: [east-1]

如果 nodeSelector 是“简单过滤”,那 affinity 更像“高级调度规则”。

六、生命周期、安全和重启策略也很关键

除了运行参数,Pod 还有几组很关键但常被忽略的字段。

1. lifecycle

可以在容器启动后或退出前执行钩子:

lifecycle:
  postStart:
    exec:
      command: ["/bin/sh", "-c", "echo started > /tmp/status"]
  preStop:
    httpGet:
      path: /graceful-shutdown
      port: 8080

2. restartPolicy

控制容器退出后的重启策略,常见值有:

  • Always
  • OnFailure
  • Never

3. securityContext

用于控制 Pod 或容器的安全权限边界:

securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000

七、写 Pod YAML 时最实用的思路

如果把 Pod YAML 拆成一句话来记,可以理解成:

  • metadata 解决“我是谁”
  • containers 解决“我要怎么跑”
  • volumes 解决“数据放哪里”
  • nodeSelectoraffinitytolerations 解决“我要去哪跑”
  • resourcesprobessecurityContext 解决“我要怎么稳定、安全地跑”

当你按这个顺序去读 YAML,Pod 配置会比死记字段名容易得多。