Skip to content

Kubernetes 工作负载与发布方式 ​

Kubernetes 工作负载 ​

下文 YAML 是独立结构示例,未执行;demo/observability 命名空间、registry.example.com 镜像和 fast-rwo StorageClass 需由目标平台实际提供或替换,代码块不能串成部署项目。完整源码与资源见单副本计数项目。

控制器选型 ​

对象适用场景不适用场景
Pod最小调度单元、短期调试直接管理长期服务
Deployment无状态长期服务、滚动发布稳定网络身份或有序存储
StatefulSet数据库、队列等需要稳定身份/存储的应用普通无状态 API
DaemonSet每节点日志、网络、存储代理固定副本数的业务服务
Job有完成语义的批处理常驻进程
CronJob周期性创建 Job严格实时调度或仅执行一次
ReplicaSetDeployment 的下层实现通常不应直接创建

Pod:生命周期边界 ​

Pod 中容器共享网络命名空间,可通过 localhost 通信;也可共享声明的 Volume。Pod 是短暂对象,重建后 UID 和 IP 可变化。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: web
  namespace: demo
  labels:
    app: web
spec:
  containers:
    - name: web
      image: nginx:1.29.0
      ports:
        - name: http
          containerPort: 80
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          memory: 256Mi

Pod phase(Pending、Running、Succeeded、Failed、Unknown)是粗粒度摘要,不能代替容器状态和 Conditions。Running Pod 也可能未 Ready 或持续重启。

Init Container 与 Sidecar ​

  • Init Container 按顺序运行并成功退出后,普通容器才开始。
  • 使用 restartPolicy: Always 的原生 Sidecar Init Container 可先启动并伴随 Pod 生命周期运行。
  • Sidecar 适合代理、适配和辅助功能,但会增加资源、启动/终止顺序与排障复杂度。
  • 不要用 Init Container 无限等待脆弱依赖;为等待逻辑设置超时并让失败可见。

Deployment ​

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: demo
spec:
  replicas: 3
  revisionHistoryLimit: 5
  minReadySeconds: 10
  progressDeadlineSeconds: 600
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      terminationGracePeriodSeconds: 30
      containers:
        - name: web
          image: registry.example.com/web:2.4.1
          ports:
            - name: http
              containerPort: 8080
          readinessProbe:
            httpGet:
              path: /readyz
              port: http
          resources:
            requests:
              cpu: 200m
              memory: 256Mi
            limits:
              memory: 512Mi

maxUnavailable: 0 不代表绝对零中断:节点故障、应用错误、容量不足和连接终止仍可能造成中断。需结合多副本、反亲和/拓扑分布、PDB、探针和优雅关闭。

bash
kubectl -n demo apply -f deployment.yaml
kubectl -n demo rollout status deployment/web --timeout=5m
kubectl -n demo rollout history deployment/web

Recreate 与 RollingUpdate ​

  • RollingUpdate:新旧 ReplicaSet 并存一段时间,应用和数据库必须兼容滚动窗口。
  • Recreate:先删旧 Pod 再建新 Pod,会中断服务,适合无法并行运行的少数应用。
  • 蓝绿/金丝雀通常需要多个 Deployment 配合 Service、Gateway/Ingress 或渐进交付控制器,原生 Deployment 不提供按比例流量管理。

StatefulSet ​

StatefulSet 提供稳定序号、网络身份和 volumeClaimTemplates:

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
  namespace: demo
spec:
  serviceName: db-headless
  replicas: 3
  podManagementPolicy: OrderedReady
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: db
          image: registry.example.com/db:16.4
          volumeMounts:
            - name: data
              mountPath: /var/lib/db
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              memory: 2Gi
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ReadWriteOnce]
        storageClassName: fast-rwo
        resources:
          requests:
            storage: 100Gi

还需同名 Headless Service(clusterIP: None)。删除或缩容 StatefulSet 默认不会自动删除 PVC,以保护数据;必须规划保留策略、备份和回收。

partition 可分段更新,但操作不当会让版本长期分裂。数据库升级还要遵循数据库自身的成员、复制和 Schema 规则,不能只依赖 StatefulSet 顺序。

DaemonSet ​

DaemonSet 保证符合选择条件的每个节点运行一个 Pod,常用于节点级代理:

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-agent
  namespace: observability
spec:
  selector:
    matchLabels:
      app: node-agent
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 10%
  template:
    metadata:
      labels:
        app: node-agent
    spec:
      containers:
        - name: agent
          image: registry.example.com/node-agent:1.8.0
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              memory: 256Mi

访问宿主机路径、PID/网络命名空间或特权模式会显著扩大攻击面。节点代理应使用最小挂载和权限,并单独审计。

Job ​

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: report-20260812
  namespace: demo
spec:
  backoffLimit: 3
  activeDeadlineSeconds: 1800
  ttlSecondsAfterFinished: 86400
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: report
          image: registry.example.com/report:4.2.0
          args: ["generate", "--date=2026-08-12"]
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
            limits:
              memory: 1Gi

Job 可能重试或在节点故障时产生重复执行,业务必须幂等。restartPolicy 只能是 Never 或 OnFailure。并行任务可使用 completions、parallelism 和 Indexed Job;对外部系统的唯一性不能仅依赖 Pod 名。

CronJob ​

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-report
  namespace: demo
spec:
  schedule: "15 2 * * *"
  timeZone: "Asia/Shanghai"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 900
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: 2
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: report
              image: registry.example.com/report:4.2.0
  • CronJob 调度是近似的,不保证严格一次;任务必须幂等。
  • Forbid 跳过重叠,Replace 会替换旧 Job,Allow 允许并发。
  • 明确 timeZone,避免控制面时区和夏令时歧义。
  • 临时暂停用 spec.suspend: true,恢复时关注错过的执行和 deadline。

PodDisruptionBudget ​

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web
  namespace: demo
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

PDB 只约束通过 Eviction API 的自愿中断,如 drain;不防节点宕机、Pod 崩溃或直接删除。minAvailable 太严格会阻塞节点维护,副本数、容量和 PDB 必须一起设计。

工作负载检查 ​

bash
kubectl -n demo get deployment,statefulset,daemonset,job,cronjob
kubectl -n demo get pods -o wide
kubectl -n demo get pod <pod> -o jsonpath='{.metadata.ownerReferences}{"\n"}'
kubectl -n demo get pdb

生产工作负载至少明确:镜像版本、资源请求、健康检查、终止时限、安全上下文、拓扑目标、可用性预算、日志方式和变更负责人。

识别 Pod 就绪与故障状态 ​

补充来源:jekyall_blog 的 Kubernetes Pod、Kubernetes Deployment 笔记(2023-11-24)。基础定义已合并到上文。

kubectl get pods 的 READY 列以 X/Y 显示已就绪与容器总数。例如 0/1 表示容器尚未就绪,2/2 表示两个容器均已就绪。Running 只是 Pod 阶段,仍需结合 Ready 条件、容器状态、事件和日志判断服务是否可接流量。

显示状态优先检查
Pending调度事件、requests、污点、亲和性和 PVC
ContainerCreating镜像、初始化、卷挂载和节点资源
ErrImagePull / ImagePullBackOff镜像名称、标签、仓库凭据和节点到仓库的网络
CrashLoopBackOff上次容器日志、退出码、入口命令、配置、探针和 OOM
Failed / Unknown容器终止原因、节点通信及控制面状态

CrashLoopBackOff、ContainerCreating 和 ImagePullBackOff 是常见显示状态,不是 Pod phase 的新增取值。完整诊断步骤见排障手册。

滚动、金丝雀与蓝绿发布 ​

方式核心过程
滚动发布分批替换实例,逐步完成版本更新
金丝雀发布先让少量实例或流量使用新版本,验证后扩大范围
蓝绿发布同时保留新旧环境,通过流量切换完成发布

Deployment 的 maxSurge 和 maxUnavailable 控制滚动更新时额外副本数与不可用副本数。原稿把固定值直接对应三种发布方式,缺少工作负载和容量条件;这些参数本身不能定义金丝雀流量分配或蓝绿环境切换。

继续阅读