边车容器

功能状态: Kubernetes v1.29 [测试版]

边车容器是与主应用程序容器在同一个 Pod 中运行的辅助容器。这些容器用于通过提供额外的服务或功能(如日志记录、监控、安全或数据同步)来增强或扩展主要 *应用程序容器* 的功能,而无需直接更改主要应用程序代码。

通常,一个 Pod 中只有一个应用程序容器。例如,如果你有一个需要本地 Web 服务器的 Web 应用程序,则本地 Web 服务器是边车,而 Web 应用程序本身是应用程序容器。

Kubernetes 中的边车容器

Kubernetes 将边车容器实现为 初始化容器 的一种特殊情况;边车容器在 Pod 启动后继续运行。本文档使用术语 *常规初始化容器* 来明确指代仅在 Pod 启动期间运行的容器。

如果你的集群启用了 SidecarContainers 功能门控(该功能自 Kubernetes v1.29 起默认启用),则可以为 Pod 的 initContainers 字段中列出的容器指定 restartPolicy。这些可重启的 *边车* 容器独立于同一 Pod 中的其他初始化容器和主应用程序容器。这些容器可以启动、停止或重启,而不会影响主应用程序容器和其他初始化容器。

你还可以运行一个 Pod,其中包含多个未标记为初始化容器或边车容器的容器。如果 Pod 中的容器是 Pod 整体工作所必需的,但你不需要控制哪些容器先启动或停止,则此方法适用。如果你需要支持不支持容器级 restartPolicy 字段的旧版 Kubernetes,你也可以这样做。

示例应用程序

下面是一个包含两个容器的 Deployment 示例,其中一个是边车

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: alpine:latest
          command: ['sh', '-c', 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done']
          volumeMounts:
            - name: data
              mountPath: /opt
      initContainers:
        - name: logshipper
          image: alpine:latest
          restartPolicy: Always
          command: ['sh', '-c', 'tail -F /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      volumes:
        - name: data
          emptyDir: {}

边车容器和 Pod 生命周期

如果初始化容器在创建时将其 restartPolicy 设置为 Always,则它将在 Pod 的整个生命周期内启动并保持运行。这对于运行与主应用程序容器分离的支持服务非常有用。

如果为此初始化容器指定了 readinessProbe,则其结果将用于确定 Pod 的 ready 状态。

由于这些容器被定义为初始化容器,因此它们受益于与常规初始化容器相同的排序和顺序保证,允许你将边车容器与常规初始化容器混合使用,以实现复杂的 Pod 初始化流程。

与常规初始化容器相比,在 initContainers 中定义的边车在启动后会继续运行。当 Pod 的 .spec.initContainers 中有多个条目时,这一点很重要。在边车式初始化容器运行后(kubelet 已将该初始化容器的 started 状态设置为 true),kubelet 会从有序的 .spec.initContainers 列表中启动下一个初始化容器。该状态变为 true,要么是因为容器中有一个进程正在运行并且没有定义启动探针,要么是因为其 startupProbe 成功。

使用边车容器的作业

如果你使用 Kubernetes 风格的初始化容器定义了一个使用边车的作业,则每个 Pod 中的边车容器不会阻止作业在主容器完成后完成。

下面是一个包含两个容器的作业示例,其中一个是边车

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    spec:
      containers:
        - name: myjob
          image: alpine:latest
          command: ['sh', '-c', 'echo "logging" > /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      initContainers:
        - name: logshipper
          image: alpine:latest
          restartPolicy: Always
          command: ['sh', '-c', 'tail -F /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      restartPolicy: Never
      volumes:
        - name: data
          emptyDir: {}

与应用程序容器的区别

边车容器与 *应用程序容器* 在同一个 Pod 中运行。但是,它们不执行主要的应用程序逻辑;相反,它们为主应用程序提供支持功能。

边车容器有自己独立的生命周期。它们可以独立于应用程序容器启动、停止和重启。这意味着你可以更新、扩展或维护边车容器,而不会影响主应用程序。

边车容器与主容器共享相同的网络和存储命名空间。这种共置允许它们紧密交互并共享资源。

与初始化容器的区别

边车容器与主容器一起工作,扩展其功能并提供额外的服务。

边车容器与主应用程序容器并发运行。它们在 Pod 的整个生命周期中都处于活动状态,并且可以独立于主容器启动和停止。与 初始化容器 不同,边车容器支持 探针 来控制其生命周期。

边车容器可以直接与主应用程序容器交互,因为与初始化容器一样,它们始终共享相同的网络,并且可以选择也共享卷(文件系统)。

初始化容器在主容器启动之前停止,因此初始化容器无法与 Pod 中的应用程序容器交换消息。任何数据传递都是单向的(例如,初始化容器可以将信息放入 emptyDir 卷中)。

容器内的资源共享

鉴于初始化容器、边车容器和应用程序容器的执行顺序,以下资源使用规则适用

  • 所有初始化容器上定义的任何特定资源请求或限制中的最高者为 *有效初始化请求/限制*。如果任何资源没有指定资源限制,则将其视为最高限制。
  • Pod 对资源的 *有效请求/限制* 是 Pod 开销 与以下两者中较高者之和
    • 所有非初始化容器(应用程序容器和边车容器)对资源的请求/限制之和
    • 资源的有效初始化请求/限制
  • 调度是根据有效请求/限制进行的,这意味着初始化容器可以为初始化保留在 Pod 的生命周期内未使用的资源。
  • Pod 的 *有效 QoS 层* 的 QoS(服务质量)层级与所有初始化容器、边车容器和应用程序容器的 QoS 层级相同。

配额和限制是根据有效的 Pod 请求和限制应用的。

边车容器和 Linux cgroups

在 Linux 上,Pod 级控制组 (cgroup) 的资源分配基于有效的 Pod 请求和限制,与调度器相同。

下一步

上次修改时间:2024 年 3 月 26 日下午 12:17 PST:更新 sidecar-containers.md (1808b6277e)