基于eRDMA加速服务网格Pod间的网络性能

Alibaba Cloud Linux 3提供的共享内存通信(Shared Memory Communication)是一种兼容socket层、使用远程内存直接访问(RDMA)技术的高性能内核网络协议栈,能够透明优化TCP应用网络通信性能。然而,在原生ECS环境中使用SMC技术优化网络性能时,用户需要谨慎维护SMC白名单以及容器网络命名空间中的配置,以防止SMC非预期降级到TCP。ASM为用户提供了可控的网络环境(集群内)SMC优化能力,能够自动优化服务网格Pod间的流量,用户无需关心具体的SMC配置。

前提条件

已添加集群到ASM实例

使用限制

操作步骤

步骤一:节点环境初始化

SMC利用eRDMA网卡加速网络性能,在启用之前需要对节点进行相应的初始化准备。

  1. Alibaba Cloud Linux 3系统内核为5.10.134-17.3及以上,升级方式可参见更换内核版本

  2. 为节点安装 erdma-controller 组件,并开启 SMC-R 透明加速,详情参见使用eRDMA加速容器网络

步骤二:部署测试应用

  1. 为测试使用的default命名空间启用自动注入,具体请参见启用自动注入

  2. 使用以下内容,创建fortioserver.yaml文件。

    展开查看fortioserver.yaml

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: fortioserver
    spec:
      ports:
      - name: http-echo
        port: 8080
        protocol: TCP
      - name: tcp-echoa
        port: 8078
        protocol: TCP
      - name: grpc-ping
        port: 8079
        protocol: TCP
      selector:
        app: fortioserver
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: fortioserver
      name: fortioserver
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: fortioserver
      template:
        metadata:
          labels:
            app: fortioserver
          annotations:
            sidecar.istio.io/inject: "true"
            sidecar.istio.io/proxyCPULimit: 2000m
            proxy.istio.io/config: |
              concurrency: 2 
        spec:
          shareProcessNamespace: true
          containers:
          - name: captured
            image: fortio/fortio:latest_release
            ports:
            - containerPort: 8080
              protocol: TCP
            - containerPort: 8078
              protocol: TCP
            - containerPort: 8079
              protocol: TCP
          - name: anolis
            securityContext:
              runAsUser: 0
            image: openanolis/anolisos:latest
            args:
            - /bin/sleep
            - 3650d
    ---
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-switch: "off"
      name: fortioclient
    spec:
      ports:
      - name: http-report
        port: 8080
        protocol: TCP
      selector:
        app: fortioclient
      type: LoadBalancer
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: fortioclient
      name: fortioclient
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: fortioclient
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true"
            sidecar.istio.io/proxyCPULimit: 4000m
            proxy.istio.io/config: |
               concurrency: 4
          labels:
            app: fortioclient
        spec:
          shareProcessNamespace: true
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - fortioserver
                topologyKey: "kubernetes.io/hostname"
          containers:
          - name: captured
            volumeMounts:
            - name: shared-data
              mountPath: /var/lib/fortio
            image: fortio/fortio:latest_release
            ports:
            - containerPort: 8080
              protocol: TCP
          - name: anolis
            securityContext:
              runAsUser: 0
            image: openanolis/anolisos:latest
            args:
            - /bin/sleep
            - 3650d
          volumes:
          - name: shared-data
            emptyDir: {}
    
  3. 使用ACK集群的KubeConfig,执行以下命令,部署测试应用。

    kubectl apply -f fortioserver.yaml
  4. 执行以下命令,查看测试应用的状态。

    kubectl get pods | grep fortio

    预期输出:

    NAME                            READY   STATUS    RESTARTS      
    fortioclient-8569b98544-9qqbj   3/3     Running   0
    fortioserver-7cd5c46c49-mwbtq   3/3     Running   0

    预期输出表明两个应用均正常启动。

步骤三:在基础环境运行测试,查看基线测试结果

fortio应用启动后,会暴露8080端口监听,访问该端口将打开fortio应用的控制台页面。为了生成测试流量,可以将fortioclient的端口映射到当前所用机器,在当前所用机器上打开fortio的控制台页面。

  1. 使用ACK集群的KubeConfig,执行以下命令,将fortio客户端的Service监听的8080端口映射到本地的8080端口。

    kubectl port-forward service/fortioclient 8080:8080
  2. 在浏览器中输入http://localhost:8080/fortio地址,访问fortio客户端控制台,并修改相关配置。

    image

    请按照下表修改页面上的参数。

    参数

    示例值

    URL

    http://fortioserver:8080/echo

    QPS

    100000

    Duration

    30s

    Threads/Simultaneous connections

    64

    Payload

    填写以下字符串(128 Byte):

    xhsyL4ELNoUUbC3WEyvaz0qoHcNYUh0j2YHJTpltJueyXlSgf7xkGqc5RcSJBtqUENNjVHNnGXmoMyILWsrZL1O2uordH6nLE7fY6h5TfTJCZtff3Wib8YgzASha8T8g

  3. 配置完成后,在页面下方,单击Start开始测试,等待进度条结束,测试完毕。

    image

    测试运行完毕后,页面将给出本次测试的结果。下图仅供参考,测试结果请以实际环境为准。

    image

    页面输出的测试结果横坐标为请求的Latency,观察柱形图在横坐标上的分布可以得出请求延迟的分布情况,紫色曲线为在不同响应时间范围内完成的请求数量。纵坐标为完成的请求数。同时,图表顶部给出了P50/P75/P90/P99/P99.9的请求Latency数据。得到基础环境数据后,需要为应用启用SMC,准备进行SMC加速后的性能验证。

步骤四:为ASM实例和工作负载启用SMC加速

  1. 使用服务网格的KubeConfig编辑网格配置,添加"smcEnabled: true",以启用SMC加速功能。

    $ kubectl edit asmmeshconfig
    
    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMMeshConfig
    metadata:
      name: default
    spec:
      ambientConfiguration:
        redirectMode: ""
        waypoint: {}
        ztunnel: {}
      cniConfiguration:
        enabled: true
        repair: {}
      smcEnabled: true
  2. 使用ACK集群的KubeConfig,执行以下命令,修改fortioserverfortioclientDeployment,为Pod添加Annotation。

    为网格实例启用加速后,还需要进一步为工作负载启用加速,通过为Pod添加Keysmc.asm.alibabacloud.com/enabled,值设置为trueAnnotation,可以为工作负载启用SMC加速,您需要同时为需要优化的两端工作负载均启用加速

    1. 编辑fortioclientDeployment定义。

      $ kubectl edit deployment fortioclient
      
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        ......
        name: fortioclient
      spec:
        ......
        template:
          metadata:
            ......
            annotations:
              smc.asm.alibabacloud.com/enabled: "true"
              
    2. 编辑fortioserverDeployment定义。

      $ kubectl edit deployment fortioserver
      
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        ......
        name: fortioserver
      spec:
        ......
        template:
          metadata:
            ......
            annotations:
              smc.asm.alibabacloud.com/enabled: "true"
              

步骤五:加速后环境运行测试,查看启用优化后的测试结果

由于修改Deployment将使工作负载重启,因此您需要参考步骤三重新进行fortioclient端口映射,再次发起测试,等待测试结束查看结果。

image

与加速前的结果对比,可以看到启用ASM SMC加速后,延迟下降,QPS明显提升。

FAQ

  1. 为什么启用SMC后访问某些数据库服务卡住,无法完成连接建立?

    这是因为访问数据库服务大多经过负载均衡网元,而部分网元实现没有严格遵守TCP option标准,错误识别SMC协议规范中的254类型TCP option,导致网络连接建立失败,无法访问服务。

    您可以通过如下方式确认此问题:

    1. 在节点上安装aliyun-smc-extensions工具包:

      sudo yum install -y aliyun-smc-extensions
    2. 使用aliyunsmc-check对目标URL进行通信链路检查:

      aliyunsmc-check syn_check --url <url>

      aliyunsmc-check会检查目标URL访问路径上的TCP option重放,冲突以及超长问题。输出结果示例如下:

      image

    若检查发现服务访问路径上确实存在对TCP option的非标处理,建议在访问此服务的POD中关闭SMC加速。