配置Sidecar容器启停顺序

当您采用Sidecar容器的形式实现类似DaemonSet的效果,从而提供额外的服务或功能(如日志记录、监控、安全性或流量转发),这些功能需要控制Sidecar容器相对于主应用容器的启停顺序。本文介绍如何配置Sidecar容器启停顺序。

功能说明

在ACS场景下,由于虚拟节点的限制,不支持Kubernetes的DaemonSet功能。此时部分需要使用DaemonSet的场景可以采用为Pod添加Sidecar容器的形式来实现类似效果。 然而,Sidecar容器的生命周期无法独立于Pod的生命周期。为了达到类似于DaemonSet的效果,您需要进行一些配置来控制Sidecar容器的启停顺序。保证Sidecar容器在Pod创建时先于应用主容器启动, 并保证在Job类Pod中业务容器已经退出的情况下, 强制终止Sidecar容器。

针对上述场景,ACS支持通过两种方式配置Sidecar容器的启停顺序:

  • 社区原生Sidecar声明

    在K8s 1.29及以上的版本, 默认支持原生的Sidecar声明方式。 即通过把Sidecar配置为Init容器,并将restartPolicy设置成Always

    说明

    常规的Sidecar方式不同,原生Sidecar方式将Sidecar容器作为一个特殊的Init容器来实现。Pod启动时,应用容器需要等待Sidecar容器完成启动之后才可以正常运行。同时restartPolicy: Always的配置使得Sidecar容器可以启动、停止和重新启动,且不会影响主应用容器和其他Init容器。

  • ACS定制声明

    对于K8s 1.28及以下的版本, ACS支持为普通容器设置一个特殊的环境变量__IS_SIDECAR__,来标记此容器是否为Sidecar。

配置说明

配置方法

Pod字段/环境变量名称

配置说明

社区原生Sidecar声明

Init容器的restartPolicy字段

  • Never: 表示容器类型为普通的Init容器。 默认值为Never。

  • Always:表示容器类型为Sidecar容器。

ACS定制声明

普通容器的环境变量:__IS_SIDECAR__

  • true:表示容器类型为Sidecar容器。

  • false:表示容器类型为普通容器。默认值为false。

配置示例

  1. test-sidecar.yaml的内容示例如下,表示创建一个Job,Job内包含两个容器,app为业务容器,sidecar为Sidecar容器。

    ACS定制声明

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: test
    spec:
      template:
        metadata:
          labels:
            app: test
        spec:
          containers:
          - name: app
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
            command: ['sh', '-c', 'for i in $(seq 1 10);do echo "logging" >> /var/logs.txt; sleep 1; done']
          - name: sidecar
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
            command: ['sh', '-c', 'touch /var/logs.txt && tail -F /var/logs.txt']
            env:
            - name: __IS_SIDECAR__   # 为此容器设置环境变量
              value: "true"          # 标记此容器为sidecar
          restartPolicy: Never
      backoffLimit: 2

    社区原生Sidecar声明

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: test
    spec:
      template:
        metadata:
          labels:
            app: test
        spec:
          initContainers:
          - name: sidecar
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
            command: ['sh', '-c', 'touch /var/logs.txt && tail -F /var/logs.txt']
            restartPolicy: Always  # 声明此容器为sidecar
          containers:
          - name: app
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
            command: ['sh', '-c', 'for i in $(seq 1 10);do echo "logging" >> /var/logs.txt; sleep 1; done']
          restartPolicy: Never
      backoffLimit: 2
  2. 执行以下命令,创建Job。

    kubectl apply -f test-sidecar.yaml
  3. 查看Job详情和对应的Pod详情,观察环境变量的效果。

    • 确认Job已经运行完成,且状态为Succeeded

      kubectl describe job <job-name>

      示例如下:

      image

  4. 查看Sidecar容器详情,观察容器的启动顺序和实际的退出码

    kubectl describe pod <pod-name>
    • 容器的启动顺序示例如下,可以看到sidecar容器先于app容器启动, 从而保证应用主容器依赖的sidecar功能(例如流量转发)提前就绪;另外,可以看到app容器运行结束后(10s后),sidecar容器会被强制杀掉,从而保证作业Pod可以完成:

      image

    • 退出码示例如下,可以看到sidecar容器被强制退出,且退出码是0,保证不会干扰作业Pod运行是成功还是失败的判断。

      image