Sidecar 容器
Kubernetes v1.33 [稳定](默认启用)Sidecar 容器是与 Pod 中的主要应用程序容器一起运行的辅助容器。这些容器用于通过提供额外的服务或功能(例如日志记录、监控、安全性或数据同步)来增强或扩展主要应用容器的功能,而无需直接更改主要应用程序代码。
通常,Pod 中只有一个应用容器。例如,如果有一个需要本地 Web 服务器的 Web 应用程序,则本地 Web 服务器是一个 sidecar,而 Web 应用程序本身是应用容器。
Kubernetes 中的 Sidecar 容器
Kubernetes 将 Sidecar 容器实现为 init 容器的一种特殊情况;Sidecar 容器在 Pod 启动后保持运行。本文档使用术语常规 init 容器来明确指仅在 Pod 启动期间运行的容器。
前提是您的集群启用了 SidecarContainers 特性门控(该特性自 Kubernetes v1.29 起默认处于活动状态),您可以为 Pod 的 initContainers 字段中列出的容器指定 restartPolicy。这些可重启的sidecar 容器独立于其他 init 容器和同一 Pod 中的主要应用程序容器。可以在不影响主要应用程序容器和其他 init 容器的情况下启动、停止或重启这些容器。
您还可以运行一个 Pod,其中包含未标记为 init 或 sidecar 容器的多个容器。如果 Pod 中的容器对于 Pod 的整体工作是必需的,但您不需要控制哪些容器先启动或停止,则这是合适的。如果您需要支持 Kubernetes 的旧版本,这些版本不支持容器级别的 restartPolicy 字段,也可以这样做。
示例应用程序
这是一个包含两个容器的 Deployment 示例,其中一个容器是 sidecar
说明
在此示例中,sidecar 容器有意在initContainers 下定义,并使用 restartPolicy: Always。Kubernetes 将此类容器视为在 Pod 的整个生命周期内持续运行的 sidecar。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: {}Sidecar 容器和 Pod 生命周期
如果创建了一个 restartPolicy 设置为 Always 的 init 容器,它将在 Pod 的整个生命周期内启动并保持运行。这对于运行与主应用程序容器分离的支持服务很有帮助。
如果为该 init 容器指定了 readinessProbe,则其结果将用于确定 Pod 的 ready 状态。
由于这些容器被定义为 init 容器,因此它们受益于与常规 init 容器相同的排序和顺序保证,从而允许您将 sidecar 容器与常规 init 容器混合,以实现复杂的 Pod 初始化流程。
与常规 init 容器相比,在 initContainers 中定义的 sidecar 在启动后会继续运行。当 Pod 的 .spec.initContainers 列表中有多个条目时,这一点很重要。在 sidecar 样式的 init 容器正在运行时(kubelet 已将该 init 容器的状态设置为 true),kubelet 然后从有序的 .spec.initContainers 列表中启动下一个 init 容器。该状态变为 true 的原因是容器中有一个正在运行的进程并且没有定义启动探测,或者是因为其 startupProbe 成功。
在 Pod 终止时,kubelet 会推迟终止 sidecar 容器,直到主应用程序容器完全停止。然后,sidecar 容器将按照 Pod 规范中出现的顺序关闭。这种方法可确保 sidecar 保持运行状态,从而支持 Pod 中的其他容器,直到不再需要其服务为止。
带有 Sidecar 容器的 Job
如果您使用 Kubernetes 样式的 init 容器定义了一个 Job,则每个 Pod 中的 sidecar 容器不会阻止 Job 在主容器完成后完成。
这是一个带有两个容器的 Job 示例,其中一个容器是 sidecar
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: {}与应用程序容器的区别
Sidecar 容器与 Pod 中的应用容器一起运行。但是,它们不执行主要应用程序逻辑;而是为主要应用程序提供支持功能。
Sidecar 容器具有自己的独立生命周期。它们可以独立于应用容器启动、停止和重启。这意味着您可以在不影响主要应用程序的情况下更新、扩展或维护 sidecar 容器。
Sidecar 容器与主要容器共享相同的网络和存储命名空间。这种共同定位使它们能够紧密交互和共享资源。
从 Kubernetes 的角度来看,sidecar 容器的正常终止不太重要。当其他容器占用所有分配的正常终止时间时,sidecar 容器将在有时间正常终止之前收到 SIGTERM 信号,然后是 SIGKILL 信号。因此,sidecar 容器的非 0 退出代码(0 表示成功退出)在 Pod 终止时是正常的,并且通常应被外部工具忽略。
与 init 容器的区别
Sidecar 容器与主容器一起工作,扩展其功能并提供额外的服务。
Sidecar 容器与主应用程序容器并发运行。它们在 Pod 的整个生命周期中处于活动状态,并且可以独立于主容器启动和停止。与 init 容器不同,sidecar 容器支持 探测以控制其生命周期。
Sidecar 容器可以与主应用程序容器直接交互,因为与 init 容器一样,它们始终共享相同的网络,并且还可以选择共享卷(文件系统)。
init 容器在主容器启动之前停止,因此 init 容器无法与 Pod 中的应用容器交换消息。任何数据传递都是单向的(例如,init 容器可以将信息放入 emptyDir 卷中)。
更改 sidecar 容器的镜像不会导致 Pod 重启,但会触发容器重启。
容器内的资源共享
鉴于 init、sidecar 和应用容器的执行顺序,适用以下资源使用规则
- 任何特定资源请求或限制在所有 init 容器中定义的最高值是有效的 init 请求/限制。如果任何资源没有指定资源限制,则认为这是最高的限制。
- Pod 的有效请求/限制用于资源是 pod 开销和以下各项的更高值
- 所有非 init 容器(应用和 sidecar 容器)的资源请求/限制之和
- 资源的有效 init 请求/限制
- 基于有效请求/限制进行调度,这意味着 init 容器可以为初始化保留 Pod 生命周期的资源。
- Pod 的有效 QoS 层级是所有 init、sidecar 和应用容器的 QoS 层级。
基于有效的 Pod 请求和限制应用配额和限制。
Sidecar 容器和 Linux cgroups
在 Linux 上,Pod 级别控制组 (cgroups) 的资源分配基于有效的 Pod 请求和限制,与调度器相同。
接下来
- 了解如何 采用 Sidecar 容器
- 阅读一篇关于 原生 sidecar 容器的博客文章。
- 阅读关于 创建具有 init 容器的 Pod的信息。
- 了解 探测类型:存活探测、就绪探测、启动探测。
- 了解 pod 开销。