使用原生Sidecar方式部署网格代理

服务网格ASM支持以Sidecar模式或Sidecarless模式为集群中的应用部署网格代理,以实现对底层网络功能的抽象化管理,例如负载均衡、服务发现、流量控制、安全性增强、流量可观测等。ASM通过Sidecar模式将网格代理容器加入到Pod,让网格代理容器与应用容器共同部署在同一Pod中、共享相同的网络命名空间,并使得网格代理透明地拦截和处理应用容器的入站和出站流量。本文主要介绍在ASM中使用原生Sidecar方式部署网格代理。

传统Sidecar与原生Sidecar

对比项

传统Sidecar

原生Sidecar

受支持K8s版本

1.2~1.28。

1.28及以上。

受支持ASM版本

1.22以下版本的ASM实例。

1.22及以上版本ASM实例添加1.30及以上版本的Kubernetes集群(ACK、ACK Serverless或ACS集群)时,默认将以原生Sidecar方式部署网格代理。

部署方式

Sidecar容器与主容器都配置在containers字段下。

Sidecar容器配置initContainers字段,并存在restartPolicy: Always字段。

生命周期

无法与主容器同步,需要单独管理。

与主容器同步,无需额外配置。

传统Sidecar方式的网格代理实际上作为Pod中的普通容器与应用容器一同部署,并分别拥有各自的生命周期。这可能会产生以下的已知问题:

  • 如果应用容器启动速度比Sidecar代理容器快,则应用容器将无法访问网络。我们可以通过配置Sidecar优雅启动来解决此问题,但在Sidecar代理启动速度较慢时仍然可能出现问题。具体操作,请参见Sidecar优雅启动

  • 如果Sidecar代理容器先于应用容器关闭,则应用容器无法访问网络。我们可以通过配置Sidecar优雅终止来解决此问题,但可能会导致Pod终止时间延长。具体操作,请参见Sidecar优雅终止

  • 如果Job类应用容器运行结束后退出,Sidecar代理容器仍将运行并保持Pod无限期运行。

  • 在 Sidecar代理容器启动之前运行的initContainers将无法访问网络。通常我们可以通过设置部分出口流量免于经过Sidecar代理来绕过此问题。具体操作,请参见不拦截对外访问的地址范围

如何确认网格代理是否以原生Sidecar方式部署

当您看到Pod的initContainers字段中存在istio-proxy容器,并且容器配置中包含restartPolicy: Always字段时,则网格代理正在以原生Sidecar方式部署。例如:

apiVersion: v1
kind: Pod
metadata:
  name: sleep-xxxxxxxx-xxxxx
  namespace: default
spec:
  containers:
...
      image: 'registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2'
      imagePullPolicy: IfNotPresent
      name: sleep
...
  initContainers:
...  
      image: registry-cn-hangzhou-vpc.ack.aliyuncs.com/acs/proxyv2:v1.22.2.35-ge64ec8af-aliyun
      imagePullPolicy: IfNotPresent
      name: istio-proxy
      ports:
        - containerPort: 15090
          name: http-envoy-prom
          protocol: TCP
      restartPolicy: Always  # 包含此字段则表示使用原生sidecar方式部署
...

在这种模式下,所有与Sidecar代理生命周期相关的Sidecar代理配置都将失效(因为原生Sidecar不再需要这些配置)。更多信息,请参见配置Sidecar代理

如何切换回传统Sidecar代理部署方式

如果您的集群中还部署了一些依赖较老K8s版本,且会修改Pod定义的MutatingWebhook组件(如kubesphere的logsidecar-injector),这些组件可能会删除原生Sidecar的定义,导致创建失败。您可能需要切换回传统Sidecar代理部署模式,以保持和老版本MutatingWebhook的兼容性。

具体操作步骤如下:

  1. 使用kubectl连接到ASM实例。具体操作,请参见通过控制面kubectl访问Istio资源

  2. 执行以下命令,为asmmeshconfig资源追加配置。

    kubectl patch asmmeshconfig default --type=merge --patch='{"spec":{"enableNativeSidecar":false}}'

    预期输出:

    asmmeshconfig.istio.alibabacloud.com/default patched
  3. 手动重启Pod。具体操作,请参见重新部署工作负载

  4. 执行以下命令,再次查看Pod信息。

    kubectl get pod sleep-xxxxxxxx-xxxxx -o yaml

    预期输出:

    apiVersion: v1
    kind: Pod
    metadata:
      name: sleep-xxxxxxxx-xxxxx
      namespace: default
    spec:
      containers:
    ...  
          image: registry-cn-hangzhou-vpc.ack.aliyuncs.com/acs/proxyv2:v1.22.2.35-ge64ec8af-aliyun      
          name: istio-proxy
          ports:
            - containerPort: 15090
              name: http-envoy-prom
              protocol: TCP
    ...
          image: 'registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2'
          imagePullPolicy: IfNotPresent
          name: sleep
    ...

    可以看到,Sidecar容器istio-proxy不再处于initContainers下,而是与主容器一同配置在containers下。