边车容器

特性状态: Kubernetes v1.29 [beta]

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

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

Kubernetes 中的边车容器

Kubernetes 将边车容器作为 Init 容器的一个特例来实现, Pod 启动后,边车容器仍保持运行状态。 本文档使用术语"常规 Init 容器"来明确指代仅在 Pod 启动期间运行的容器。

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

你还可以运行包含多个未标记为 Init 或边车容器的 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', 'echo "logging" > /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      initContainers:
        - name: logshipper
          image: alpine:latest
          restartPolicy: Always
          command: ['sh', '-c', 'tail /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
  volumes:
    - name: data
      emptyDir: {}

边车容器和 Pod 生命周期

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

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

由于这些容器被定义为 Init 容器,所以它们享有与其他 Init 容器相同的顺序和按序执行保证, 从而允许将边车容器与常规 Init 容器混合使用,支持复杂的 Pod 初始化流程。

与常规 Init 容器相比,在 initContainers 中定义的边车容器在启动后继续运行。 当 Pod 的 .spec.initContainers 中有多个条目时,这一点非常重要。 在边车风格的 Init 容器运行后(kubelet 将该 Init 容器的 started 状态设置为 true), kubelet 启动 .spec.initContainers 这一有序列表中的下一个 Init 容器。 该状态要么因为容器中有一个正在运行的进程且没有定义启动探针而变为 true, 要么是其 startupProbe 成功而返回的结果。

带边车容器的 Job

如果你定义 Job 时使用基于 Kubernetes 风格 Init 容器的边车容器, 各个 Pod 中的边车容器不会阻止 Job 在主容器结束后进入完成状态。

以下是一个具有两个容器的 Job 示例,其中一个是边车:

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 /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      restartPolicy: Never
      volumes:
        - name: data
          emptyDir: {}

与应用容器的区别

边车容器与同一 Pod 中的应用容器并行运行。不过边车容器不执行主应用逻辑,而是为主应用提供支持功能。

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

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

与 Init 容器的区别

边车容器与主容器并行工作,扩展其功能并提供附加服务。

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

边车容器可以直接与主应用容器交互,因为与 Init 容器一样, 它们总是与应用容器共享相同的网络,并且还可以选择共享卷(文件系统)。

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

容器内的资源共享

假如执行顺序为 Init 容器、边车容器和应用容器,则关于资源用量适用以下规则:

  • 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为 Pod 有效初始 request/limit。 如果任何资源没有指定资源限制,则被视为最高限制。
  • Pod 对资源的 有效 limit/request 是如下两者中的较大者:
    • 所有应用容器对某个资源的 limit/request 之和
    • Init 容器中对某个资源的有效 limit/request
  • 系统基于有效的 limit/request 完成调度,这意味着 Init 容器能够为初始化过程预留资源, 而这些资源在 Pod 的生命周期中不再被使用。
  • Pod 的 有效 QoS 级别,对于 Init 容器和应用容器而言是相同的。

配额和限制适用于 Pod 的有效请求和限制值。

Sidecar 容器和 Linux Cgroup

在 Linux 上,Pod Cgroup 的资源分配基于 Pod 级别的有效资源请求和限制,这一点与调度器相同。

接下来

最后修改 May 15, 2024 at 12:22 AM PST: [zh-cn] sync sidecar-containers (9336671cee)