k8s-Sidecar容器学习

发布于:2025-09-14 ⋅ 阅读:(16) ⋅ 点赞:(0)

1. 什么是Sidecar容器

Sidecar容器中文翻译边车容器,主要作用就是为Pod中的业务容器,提供辅助功能,比如:在spec.containers:运行一个nginx作为业务容器,在spec.containers中运行filebeat日志采集器,边车容器也可以称为Init容器的特例。

2. Sidecar容器与Init容器和业务容器对比

官网有对比:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/sidecar-containers/#differences-from-application-containers,我自己总结以下。

和业务容器对比:

容器类型 功能 启动方式 生命周期 命名空间
Sidecar容器 为业务容器提供辅助功能 多个Sidecar容器并行启动 拥有独立的生命周期,对Sidecar的维护不会影响业务容器。 与业务容器共享相同的网络和存储命名空间。这种共存使它们能够紧密交互并共享资源。
业务容器 执行业务代码 并行启动 - -

容器终止:
当Pod被杀死或者重建时,kubelet会向所有容器发送SIGTERM信号,留给30s的时间用于处理请求,超过30s后,还未停止就会向容器发送SIGKILL强制停止。但是当Pod中有Sidecar容器时,kubelet会推迟终止边车容器,具体实现是:需要等到所有的业务容器停止后,边车容器才会接收到SIGTERM信号,但是这个时候30s安全停止时间可能已经过去25s,紧接着,kubelet会向所有容器发送SIGKILL信号,强制停止,这也包括Sidecar容器,所以,这时Sidecar的退出码可能非0,由于Sidecar不是业务容器所以可以忽略这个异常。

和Init容器对比:

容器类型 启动模式 是否支持:lifecycle、livenessProbe、startupProbe、readinessProbe 是否能与业务容器交互
Sidecar容器 在业务容器启动前,并行启动,与主应用容器同时运行,在整个 Pod 的生命周期中都处于活动状态,并且可以独立于主容器启动和停止 支持 与业务容器共享相同的网络和存储命名空间。这种共存使它们能够紧密交互并共享资源。
Init容器 在业务容器启动前,串行启动,执行完就退出 不支持 Init 容器在主容器启动之前停止,因此 Init 容器无法与 Pod 中的应用容器交换消息。 所有数据传递都是单向的(例如,Init 容器可以将信息放入 emptyDir 卷中)。

3. Sidecar容器和Pod的生命周期

  • 如果创建 Init 容器时将 restartPolicy 设置为 Always, 则它将在整个 Pod 的生命周期内启动并持续运行。

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

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

  • 在 Pod 终止时, kubelet 会推迟终止边车容器,直到主应用容器已完全停止。边车容器随后将按照它们在 Pod 规约中出现的相反顺序被关闭。 这种方法确保了在不再需要边车服务之前这些边车继续发挥作用,以支持 Pod 内的其他容器,具体实现上面已经讲过了。

4. 容器内的资源共享

和Init容器一样,优先要满足保证边车容器的limit/request,业务容器和边车容器limit/request谁的大就使用谁的配置去申请资源。

4 创建带有Sidecar容器的Pod

在这里插入图片描述

创建一个tail_f_nginx的边车容器,持续打印nginx容器中的日志,yaml资源文件如下:

cat nginx-po.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: html
          mountPath: /var/log/nginx
  initContainers:
    - name: tailfnginx
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      restartPolicy: Always
      command: ['sh','-c','tail -F /var/log/nginx/access.log']
      volumeMounts:
        - name: html
          mountPath: /var/log/nginx
  volumes:
    - name: html
      emptyDir: {}

使用kubectl describe pod nginx查看Pod事件:

Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m     default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal  Pulled     3m26s  kubelet            Container image "busybox:latest" already present on machine
  Normal  Created    3m26s  kubelet            Created container: tailfnginx
  Normal  Started    3m26s  kubelet            Started container tailfnginx
  Normal  Pulled     3m25s  kubelet            Container image "nginx:latest" already present on machine
  Normal  Created    3m25s  kubelet            Created container: nginx
  Normal  Started    3m24s  kubelet            Started container nginx

如上可以看出边车容器优先与业务容器启动。

访问nginx容器,查看tailfnginx容器是否能正常打印日志:

kubectl describe pods/nginx | grep '^IP:'
IP:               10.244.1.11
curl 10.244.1.11
kubectl logs pods/nginx -c tailfnginx
tail: can't open '/var/log/nginx/access.log': No such file or directory
tail: /var/log/nginx/access.log has appeared; following end of new file
10.244.0.0 - - [12/Sep/2025:15:21:20 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.9.1" "-"

可以看到正常获取到了nginx访问的日志,但是第一条日志显示没有找到/var/log/nginx/access.log文件,这是因为优先与nginx容器启动,nginx还没有启动导致的。