Pod 总结


生命周期

pod-lifecycle

Pause 容器

每个 pod 都会有一个 pause 容器,完成对 pod 内容器的一些资源共享,主要有 2 个功能:

  1. 初始化网络栈
  2. 共享存储卷

initC (初始化容器)

initC 与 mainC 使用的字段一样,但是 initC 没有 lifecycle,readinessProbe, livenessProbe, startupProbe 每个 Pod 的 initC 可以是 0 个,理论上也可以是无数个, initC 是依次顺序完成初始化的,我们可以利用 initC 将一些任务分步实现,如:

  1. initC1 可以执行 git clone
  2. initC2 可以安装一些与 mainC 无关的软件,包括一些编译软件
  3. initC3 可以完成对软件的构建,比如前端 webpack,后端可执行文件的编译
  4. initC4 可以完成一些 delay 或 until 的前置条件,因为 mainC 要想启动,必须要等 initC 完成
  5. initC5 可以运行在一个不同于 mainC 的文件系统视图,因此完成对 Secrets 的访问
  6. initC6 可以安全地运行一些工具,来一定程度上提高 mainC 运行的安全性
  7. … 等等

mainC (主容器)

每个 pod 必须至少有一个容器,否则 pod 无法存活,理论上来说每个 pod 的容器数量也可以是无数个,且所有的 mainC 都是同时执行的,mainC 中,有 hook,也有探针

  • hook: exec,httpGet,tcpSocket

    • lifecycle.postHook
    • lifecycle.preStop
  • 探针 probe

    • startupProbe: 启动探针
    • livenessProbe:存活探针
    • readinessProbe:就绪探针

Sidecar Container

不同于普通的 initC 按序启动,Sidecar Container 是活跃在整个 pod 的生命周期中的,也就是从 pause 容器完成初始化,一直到 pod 死亡,通过设置 restartPolicy=Always,可在 initContainers 添加一个 Sidecar Container,支持 *Probe 检测,支持 lifecycle.*,并共享容器的 CPU,Memory,网路与存储等资源,但是并不会影响 mainC,还有一点,就是因为 Sidecar 也属于 initC,所以 mainC 要想启动,同样要等 Sidecar 正常运行才行

  • 日志采集
  • 监控
  • 数据同步

Ephemeral Container

主要用与调试容器,字段同 Container,不允许使用,ports,lifecycle,*Probe,resources,除此以外可以执行任意命令

Quality of Service Class

被用于 pod 的 evict 中,当一个 node 资源过载的时候,根据下面的顺序,依次 evict

  • BestEffort: 优先被 evict,默认的 QoS
  • Burstable: 仅次于 BestEffort
  • Guaranteed: 最不容易被 evict

Downward API

用于将 pod 的一些 metadata.*,通过 volume 的方式映射到容器内部

Disruptions

非自愿干扰(Involuntary Disruptions)

  1. 节点物理机的硬件故障
  2. 集群管理员错误地删除实例
  3. 云提供商或虚拟机管理程序中的故障导致虚拟机消失
  4. 内核错误
  5. 节点由于集群网络隔离从集群中消失
  6. 由于节点资源不足导致 Pod 被驱逐

自愿干扰(Voluntary Disruptions)

  1. 删除 Deployment 等控制器
  2. 更新 Deployment 等控制器模版导致 Pod 重启
  3. 直接删除 Pod
  4. 排空(drain)节点进行修复或升级操作
  5. 从集群中 drain 节点以缩小集群
  6. 从节点中移除一个 Pod,以允许其他 Pod 使用该节点

可以创建PodDisruptionBudgets来一定程度上缓解自愿干扰,但是不能够保证,调度器只是尽力去做。

处理干扰 [TBD]

干扰预算 (PodDisruptionBudgets) [TBD]

干扰状况 [TBD]

Pod 开销

Pod 中的资源申请是包含容器运行时的开销的,关于容器运行时的开销,管理员可以在准入控制部分预先设置,也可以由具体的 Pod 指定。

还可以通过spec.overhead由 Pod 自己定义,这个字段的优先级更高。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata-fc
handler: runc # 此处是部署kubernetes集群时设置的容器运行时
overhead:
  podFixed:
    memory: "120Mi"
    cpu: "250m"
---
apiVersion: v1
kind: Pod
...
spec:
  runtimeClassName: kata-fc # 如果不设置的话,集群会根据不同的容器运行时,设置相应的
  containers:
  - resources:
      limits:
        cpu: 500m
        memory: 100Mi
    ...
  - resources:
      limits:
        cpu: 1500m
        memory: 100Mi
    ...

如果.spec.runtimeClassName指定了上述定义的 kata-fc RuntimeClass,则 Pod 总的资源申请会包含上述overhead(因为容器运行时在内的一部分开销),如下所示:

  Namespace    Name       CPU Requests  CPU Limits   Memory Requests  Memory Limits  AGE
  ---------    ----       ------------  ----------   ---------------  -------------  ---
  default      test-pod   2250m (56%)   2250m (56%)  320Mi (1%)       320Mi (1%)     36m