创建 Azure Kubernetes 服务 (AKS) 群集并将其配置为通过 Azure CLI 使用虚拟节点

借助虚拟节点,可以在 Azure 容器实例 (ACI) 和 AKS 群集中运行的 Pod 之间实现网络通信。 若要提供此通信,请创建虚拟网络子网并分配委托的权限。 虚拟节点仅适用于使用高级网络 (Azure CNI) 创建的 AKS 群集。 默认情况下,AKS 群集是使用基本网络 (kubenet) 创建的。 本文介绍如何创建虚拟网络和子网,然后部署使用高级网络的 AKS 群集。

本文介绍了如何使用 Azure CLI 创建和配置虚拟网络资源和启用了虚拟节点的 AKS 群集。

开始之前

重要

在将虚拟节点用于 AKS 之前,请查看 AKS 虚拟节点的限制ACI 的虚拟网络限制。 这些限制会影响 AKS 群集和虚拟节点的位置、网络配置和其他配置详细信息。

  • 你需要在订阅中注册 ACI 服务提供程序。 可以使用 az provider list 命令检查 ACI 提供程序的注册状态。

    az provider list --query "[?contains(namespace,'Microsoft.ContainerInstance')]" -o table
    

    Microsoft.ContainerInstance 提供程序应报告为“已注册”,如下面的示例输出所示:

    Namespace                    RegistrationState    RegistrationPolicy
    ---------------------------  -------------------  --------------------
    Microsoft.ContainerInstance  Registered           RegistrationRequired
    

    如果提供程序显示为“未注册”,请使用 az provider register 注册该提供程序。

    az provider register --namespace Microsoft.ContainerInstance
    
  • 如果使用的是 Azure CLI,则本文需要使用 Azure 2.0.49 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

启动 Azure 本地 Shell

如果希望在本地安装并使用 CLI,则本文需要 Azure CLI 版本 2.0.49 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

创建资源组

Azure 资源组是用于部署和管理 Azure 资源的逻辑组。

  • 使用 az group create 命令创建资源组。

    az group create --name myResourceGroup --location eastus
    

创建虚拟网络

重要

虚拟节点需要一个自定义虚拟网络和关联的子网。 它不能与 AKS 群集关联到同一个虚拟网络。

  1. 使用 az network vnet create 命令创建虚拟网络。 以下示例将使用 10.0.0.0/8 地址前缀创建一个名为 myVnet 的虚拟网络和一个名为 myAKSSubnet 的子网。 此子网的地址前缀默认为 10.240.0.0/16。

    az network vnet create \
        --resource-group myResourceGroup \
        --name myVnet \
        --address-prefixes 10.0.0.0/8 \
        --subnet-name myAKSSubnet \
        --subnet-prefix 10.240.0.0/16
    
  2. 使用 az network vnet subnet create 命令为虚拟节点创建额外的子网。 以下示例将使用 10.241.0.0/16 地址前缀创建一个名为 myVirtualNodeSubnet 的子网。

    az network vnet subnet create \
        --resource-group myResourceGroup \
        --vnet-name myVnet \
        --name myVirtualNodeSubnet \
        --address-prefixes 10.241.0.0/16
    

创建具有托管标识的 AKS 群集

  1. 使用 az network vnet subnet show 命令获取子网 ID。

    az network vnet subnet show --resource-group myResourceGroup --vnet-name myVnet --name myAKSSubnet --query id -o tsv
    
  2. 使用 az aks create 命令创建 AKS 群集,并将 <subnetId> 替换为上一步中获得的 ID。 以下示例将创建包含 5 个节点的名为 myAKSCluster 的群集。

    az aks create \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --node-count 5 \
        --network-plugin azure \
        --vnet-subnet-id <subnetId>
    

    几分钟后,该命令完成并返回有关群集的 JSON 格式的信息。

有关托管标识的详细信息,请参阅使用托管标识

启用虚拟节点加载项

  • 使用 az aks enable-addons 命令启用虚拟节点。 以下示例将使用上一步中创建的名为 myVirtualNodeSubnet 的子网。

    az aks enable-addons \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --addons virtual-node \
        --subnet-name myVirtualNodeSubnet
    

连接到群集

  1. 使用 az aks get-credentials 命令将 kubectl 配置为连接到你的 Kubernetes 群集。 此步骤下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  2. 使用 kubectl get 命令验证与群集的连接,该命令将返回群集节点的列表。

    kubectl get nodes
    

    以下示例输出显示了所创建的单个 VM 节点以及用于 Linux 的虚拟节点 virtual-node-aci-linux:

    NAME                          STATUS    ROLES     AGE       VERSION
    virtual-node-aci-linux        Ready     agent     28m       v1.11.2
    aks-agentpool-14693408-0      Ready     agent     32m       v1.11.2
    

部署示例应用

  1. 创建名为 virtual-node.yaml 的文件,并将其复制到以下 YAML 中。 YAML 通过定义 nodeSelectortoleration 来计划节点上的容器。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aci-helloworld
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aci-helloworld
      template:
        metadata:
          labels:
            app: aci-helloworld
        spec:
          containers:
          - name: aci-helloworld
            image: mcr.azk8s.cn/azuredocs/aci-helloworld
            ports:
            - containerPort: 80
          nodeSelector:
            kubernetes.io/role: agent
            beta.kubernetes.io/os: linux
            type: virtual-kubelet
          tolerations:
          - key: virtual-kubelet.io/provider
            operator: Exists
          - key: azure.com/aci
            effect: NoSchedule
    
  2. 使用 kubectl apply 命令运行应用程序。

    kubectl apply -f virtual-node.yaml
    
  3. 使用带 -o wide 参数的 kubectl get pods 命令获取 Pod 列表和计划的节点。

    kubectl get pods -o wide
    

    Pod 在虚拟节点 virtual-node-aci-linux 上计划,如以下示例输出所示:

    NAME                            READY     STATUS    RESTARTS   AGE       IP           NODE
    aci-helloworld-9b55975f-bnmfl   1/1       Running   0          4m        10.241.0.4   virtual-node-aci-linux
    

    系统从被委派用于虚拟节点的 Azure 虚拟网络子网中为该 Pod 分配了一个内部 IP 地址。

注意

如果使用存储在 Azure 容器注册表中的映像,请配置并使用 Kubernetes 机密。 虚拟节点的当前限制是无法使用集成的 Microsoft Entra 服务主体身份验证。 如果不使用机密,则在虚拟节点上计划的 Pod 将无法启动并报告错误 HTTP response status code 400 error code "InaccessibleImage"

测试虚拟节点 Pod

  1. 使用 Web 客户端浏览到演示应用程序,从而测试虚拟节点上运行的 Pod。 由于为该 Pod 分配了一个内部 IP 地址,因此,可以从 AKS 群集上的另一个 Pod 快速测试此连接。

  2. 使用以下 kubectl run -it 命令创建测试 Pod 并向其附加终端会话。

    kubectl run -it --rm testvk --image=mcr.azk8s.cn/dotnet/runtime-deps:6.0
    
  3. 使用 apt-get 在 Pod 中安装 curl

    apt-get update && apt-get install -y curl
    
  4. 使用 curl 访问 Pod 的地址,例如 http://10.241.0.4。 提供上一个 kubectl get pods 命令中所示的你自己的内部 IP 地址。

    curl -L http://10.241.0.4
    

    将显示演示应用程序,如以下精简版示例输出中所示:

    <html>
    <head>
      <title>Welcome to Azure Container Instances!</title>
    </head>
    [...]
    
  5. 使用 exit 关闭与测试 Pod 之间的终端会话。 会话结束时便会删除该 Pod。

删除虚拟节点

  1. 使用 kubectl delete 命令删除虚拟节点上运行的 aci-helloworld pod。

    kubectl delete -f virtual-node.yaml
    
  2. 使用 az aks disable-addons 命令启用虚拟节点。

    az aks disable-addons --resource-group myResourceGroup --name myAKSCluster --addons virtual-node
    
  3. 使用以下命令移除虚拟网络资源和资源组。

    # Change the name of your resource group, cluster and network resources as needed
    RES_GROUP=myResourceGroup
    AKS_CLUSTER=myAKScluster
    AKS_VNET=myVnet
    AKS_SUBNET=myVirtualNodeSubnet
    
    # Get AKS node resource group
    NODE_RES_GROUP=$(az aks show --resource-group $RES_GROUP --name $AKS_CLUSTER --query nodeResourceGroup --output tsv)
    
    # Get network profile ID
    NETWORK_PROFILE_ID=$(az network profile list --resource-group $NODE_RES_GROUP --query "[0].id" --output tsv)
    
    # Delete the network profile
    az network profile delete --id $NETWORK_PROFILE_ID -y
    
    # Grab the service association link ID
    SAL_ID=$(az network vnet subnet show --resource-group $RES_GROUP --vnet-name $AKS_VNET --name $AKS_SUBNET --query id --output tsv)/providers/Microsoft.ContainerInstance/serviceAssociationLinks/default
    
    # Delete the service association link for the subnet
    az resource delete --ids $SAL_ID --api-version 2021-10-01
    
    # Delete the subnet delegation to Azure Container Instances
    az network vnet subnet update --resource-group $RES_GROUP --vnet-name $AKS_VNET --name $AKS_SUBNET --remove delegations
    

后续步骤

在本文中,你在虚拟节点上计划了一个 Pod,并为其分配了一个专用的内部 IP 地址。 也可以改为创建服务部署,并通过负载均衡器或入口控制器将流量路由到 Pod。 有关详细信息,请参阅在 AKS 中创建基本入口控制器

虚拟节点通常是 AKS 中缩放解决方案的一个组件。 有关缩放解决方案的详细信息,请参阅以下文章: