在ACK集群使用自定义CNI插件

ACK默认提供的TerwayFlannel CNI插件,能够满足绝大多数的容器网络需求。但在某些场景下,若您需要使用其他CNI插件中的特定功能,ACK支持通过Bring your own Container Network Interface(简称BYOCNI)模式在集群中安装自定义CNI插件。本文介绍如何创建未安装CNI插件的ACK托管集群Pro,并手动安装自定义CNI插件。

责任声明

容器网络接口(CNI)不仅影响集群内东西向流量,还影响南北向流量,以及核心组件的部分能力(例如Webhook依赖API Server能够直接访问Pod)。

对于用户侧在ACK托管集群Pro中使用自定义CNI插件产生的故障,阿里云不提供SLA;自定义CNI插件相关的网络能力需要用户侧自行保障,进行故障排查及修复,ACK不提供相关的技术支持。

如果您需要CNI相关支持,请使用ACK提供的CNI插件,或者使用商业版CNI插件以获得第三方的专业技术支持。

注意事项

如果您的自定义CNI插件使用Overlay网络,ACK托管集群ProAPI Server将无法访问任何Webhook,影响包括metrics-server在内的所有使用Webhook能力的组件。

步骤一:创建BYOCNI集群

  1. ACK目前只能通过CreateCluster - 创建集群或者通过Terraform创建ACK托管集群的方式创建一个未安装CNI插件的ACK托管集群Pro(简称BYOCNI集群)。您需要在创建集群时,禁用kube-flannel-ds组件。

    使用OpenAPI

    使用Terraform

    "addons": [
        {
            "name": "kube-flannel-ds",
            "disabled": true
        }
    ]
    addons {
      name     = "kube-flannel-ds"
      disabled = true
    }
  2. (可选)使用VPC路由模式需要额外配置cloud-controller-manager组件。详细内容,请参见cloud-controller-manager配置

    使用OpenAPI

    使用Terraform

    "addons": [
        {
            "name": "cloud-controller-manager",
            "config": "{\"EnableCloudRoutes\":\"true\",\"BackendType\":\"NodePort\"}"
        }
    ]
    addons {
      name = "cloud-controller-manager"
      config = jsonencode({
        EnableCloudRoutes = "true"
        BackendType       = "NodePort"
      })
    }
  3. 集群创建成功后,由于未安装CNI插件,所有节点将处于未就绪 (NotReady) 状态,这属于正常现象。成功安装CNI插件后,节点状态将自动变为就绪(Ready)。

    image

步骤二:安装自定义CNI插件

重要

以下步骤仅以安装Cilium(VPC路由模式)为例。请您根据实际所选的CNI插件调整操作。

在本示例操作之前,请确保已使用kubectl连接集群并安装Helm CLI。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群Installing Helm

本示例中的Cilium镜像位于海外仓库,可能出现拉取失败的情况。您可参见下列解决方案:
方案一:通过什么是容器镜像服务ACR订阅海外源镜像,请参见订阅海外源镜像
方案二:创建全球加速GA(Global Accelerator)实例,使用其覆盖全球的网络加速服务直接拉取海外源镜像,请参见使用GA实现ACK跨域加速拉取容器镜像
  1. 执行以下命令,添加Ciliumhelm仓库。

    helm repo add cilium https://helm.cilium.io/
  2. 执行以下命令安装Cilium。请根据您的集群网络规划,修改命令中的参数。

    helm install --set securityContext.privileged=true \
        --set routingMode=native \
        --set ipam.mode=kubernetes \
        --set ipMasqAgent.enable=true \
        --set ipMasqAgent.config.nonMasqueradeCIDRs='{172.16.0.0/12,10.0.0.0/8 }' \
        --set ipv4NativeRoutingCIDR=172.16.0.0/12 \
        cilium cilium/cilium --version 1.17.4 \
      --namespace kube-system

    关键参数说明:

    • ipv4NativeRoutingCIDR:172.16.0.0/12为集群使用的Pod地址段。

    • ipMasqAgent.config.nonMasqueradeCIDRs:172.16.0.0/12为集群使用的Pod地址段,10.0.0.0/8为集群使用的VPC地址段。

    预期输出:

    NAME: cilium
    LAST DEPLOYED: Fri Jul 18 16:34:50 2025
    NAMESPACE: kube-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    You have successfully installed Cilium with Hubble.
    
    Your release version is 1.17.4.
    
    For any further help, visit https://docs.cilium.io/en/v1.17/gettinghelp
  3. 成功安装Cilium CNI插件之后,节点进入就绪(Ready)状态。

    image

更多配置

您可以在创建BYOCNI集群时通过更详细的参数定制集群的行为,以更好地满足CNI插件的需要。

Node分配PodCIDR

有些CNI插件依赖Node上的PodCIDR属性为Pod分配IP,您可以在创建集群的时候指定container_cidrnode_cidr_mask来设置集群内Pod网段和每个节点上网段的掩码。

在配置了container_cidrcidr_mask的情况下,集群内节点将分配PodCIDR,否则节点上不会分配。具体配置方式,请参见CreateCluster - 创建集群

cloud-controller-manager配置

ACK cloud-controller-managerBYOCNI集群提供了可选的能力。您可以在创建集群时,通过配置cloud-controller-manager addon的参数,开启和关闭响应的能力。

参数

默认值

是否必填

描述

EnableCloudRoutes

false

当启用Node上的PodCIDR之后,如果您使用VPC路由表实现Pod之间的互通,您可以启用cloud-controller-managerenableCloudRoutes功能,cloud-controller-manager将自动地为每个节点上的PodCIDR段添加一个路由表,从PodCIDR分配的IP地址,在VPC内可以直接访问。

BackendType

NodePort

cloud-controller-manager负责处理LoadBalancer类型的Service,包括创建CLB/NLB、将Pod配置到CLB/NLB后端等。默认情况下,cloud-controller-manager将集群内的Node IP配置到负载均衡后端,负载均衡将流量转发到节点上,再通过节点内Service转发的配置转发到Pod上。如果您的BYOCNI插件为Pod分配的是VPC IP,您可以直接将Pod IP配置到负载均衡后端,而不需要再通过节点转发。

可选值:

  • NodePort:负载均衡后端配置节点IP,通过节点转发到Pod。

  • Pod:负载均衡后端直接挂载Pod IP,要求Pod地址必须是VPC地址。

配置示例:

使用OpenAPI

使用Terraform

"addons": [
    {
        "name": "cloud-controller-manager",
        "config": "{\"EnableCloudRoutes\":\"true\",\"BackendType\":\"NodePort\"}"
    }
]
addons {
  name = "cloud-controller-manager"
  config = jsonencode({
    EnableCloudRoutes = "true"
    BackendType       = "NodePort"
  })
}