将静态公共 IP 地址和 DNS 标签用于 Azure Kubernetes 服务 (AKS) 负载均衡器

在 Azure Kubernetes 服务 (AKS) 群集中创建负载均衡器资源时,分配给该资源的公共 IP 地址仅在该资源的生命周期内有效。 如果删除 Kubernetes 服务,则会同时删除关联的负载均衡器和 IP 地址。 如果要分配特定 IP 地址或保留已重新部署的 Kubernetes 服务的 IP 地址,请创建并使用静态公共 IP 地址。

本文介绍如何创建静态公共 IP 地址并将其分配给 Kubernetes 服务。

开始之前

  • 需要安装和配置 Azure CLI 版本 2.0.59 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI
  • 本文介绍如何将标准 SKU IP 与 标准 SKU 负载均衡器结合使用。 有关详细信息,请参阅 Azure 中的 IP 地址类型和分配方法

创建 AKS 群集

  1. 使用 az group create 命令创建 Azure 资源组。

    az group create --name myNetworkResourceGroup --location chinanorth
    
  2. 使用 az aks create 命令创建 AKS 群集。

    az aks create --name myAKSCluster --resource-group myNetworkResourceGroup --generate-ssh-keys
    

创建静态 IP 地址

  1. 使用命令“az aks show”获取节点资源组的名称,并查询属性“nodeResourceGroup”。

    az aks show --name myAKSCluster --resource-group myNetworkResourceGroup --query nodeResourceGroup -o tsv
    
  2. 使用 az network public ip create 命令在节点资源组中创建静态公共 IP 地址。

    az network public-ip create \
        --resource-group <node resource group name> \
        --name myAKSPublicIP \
        --sku Standard \
        --allocation-method static
    

    注意

    如果在 AKS 群集中使用了“基本”SKU 负载平衡器,请在定义公共 IP 时为 --sku 参数使用值 Basic。 仅基本 SKU IP 兼容基本 SKU 负载均衡器,仅标准 SKU IP 兼容标准 SKU 负载均衡器。

  3. 使用命令“az network public-ip list”获取静态公共 IP 地址。 指定节点资源组的名称和创建的公共 IP 地址,然后查询 ipAddress

    az network public-ip show --resource-group <node resource group name> --name myAKSPublicIP --query ipAddress --output tsv
    

使用静态 IP 地址创建服务

  1. 首先,确定 AKS 群集正在使用的托管标识类型:系统分配的托管标识或用户分配的托管标识。 如果不确定,请调用az aks show命令并查询标识的类型属性。

    az aks show \
        --name myAKSCluster \
        --resource-group myResourceGroup \
        --query identity.type \
        --output tsv       
    

    如果群集使用托管标识,则 type 属性的值将为 SystemAssigned 或 UserAssigned

    如果群集正在使用服务主体,则 type 属性的值为 null。 请考虑升级群集以使用托管标识。

  2. 如果 AKS 群集使用系统分配的托管标识,则查询托管标识的主体 ID,如下所示:

    # Get the principal ID for a system-assigned managed identity.
    CLIENT_ID=$(az aks show \
        --name myAKSCluster \
        --resource-group myNetworkResourceGroup \
        --query identity.principalId \
        --output tsv)
    

    如果 AKS 群集使用用户分配的托管标识,则主体 ID 将为 null。 请改为查询用户分配的托管标识的客户端 ID:

    # Get the client ID for a user-assigned managed identity.
    CLIENT_ID=$(az aks show \
        --name myAKSCluster \
        --resource-group myNetworkResourceGroup \
        --query identity.userAssignedIdentities.*.clientId \
        --output tsv    
    
  3. 通过调用az role assignment create命令,为公共 IP 资源组的 AKS 群集使用的托管标识分配委派权限。

    # Get the resource ID for the node resource group.
    RG_SCOPE=$(az group show \
        --name <node resource group> \
        --query id \
        --output tsv)
    
    # Assign the Network Contributor role to the managed identity,
    # scoped to the node resource group.
    az role assignment create \
        --assignee ${CLIENT_ID} \
        --role "Network Contributor" \
        --scope ${RG_SCOPE}
    

    重要

    如果自定义了出站 IP,请确保群集标识对出站公共 IP 和入站公共 IP 均具有相应权限。

  4. 创建名为 load-balancer-service.yaml 的文件并复制以下 YAML 文件中的内容,提供自己在上一步中创建的公共 IP 地址和节点资源组名称。

    重要

    loadBalancerIP 属性添加到负载均衡器 YAML 清单将弃用以下上游 Kubernetes。 虽然当前使用情况保持不变,并且现有服务无需修改即可正常工作,但我们强烈建议改为设置服务注释。 要设置服务注释,可以将 service.beta.kubernetes.io/azure-pip-name 用于公共 IP 名称,或将 service.beta.kubernetes.io/azure-load-balancer-ipv4 用于 IPv4 地址并将 service.beta.kubernetes.io/azure-load-balancer-ipv6 用于 IPv6 地址,如示例 YAML 中所示。

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
        service.beta.kubernetes.io/azure-pip-name: myAKSPublicIP
      name: azure-load-balancer
    spec:
      type: LoadBalancer
      ports:
      - port: 80
      selector:
        app: azure-load-balancer
    

    注意

    添加 service.beta.kubernetes.io/azure-pip-name 批注可确保创建最有效的 LoadBalancer,强烈建议避免潜在的限制。

  5. 使用 service.beta.kubernetes.io/azure-dns-label-name 服务批注将面向公众的 DNS 标签设置为服务。 这将使用 Azure 的公共 DNS 服务器和顶级域为你的服务发布完全限定的域名 (FQDN)。 批注值在 Azure 位置上应该是唯一的,因此建议使用完全符合条件的标签。 Azure 会自动将所选位置的默认后缀追加到你提供的名称(例如 <location>.chinacloudapp.cn),从而创建 FQDN。

    注意

    若要在自己的域中发布服务,请参阅 Azure DNSexternal-dns 项目。

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
        service.beta.kubernetes.io/azure-pip-name: myAKSPublicIP
        service.beta.kubernetes.io/azure-dns-label-name: <unique-service-label>
      name: azure-load-balancer
    spec:
      type: LoadBalancer
      ports:
      - port: 80
      selector:
        app: azure-load-balancer
    
  6. 使用 kubectl apply 命令创建服务和部署。

    kubectl apply -f load-balancer-service.yaml
    
  7. 若要查看负载均衡器的 DNS 标签,请使用命令“kubectl describe service”。

    kubectl describe service azure-load-balancer
    

    DNS 标签将在 Annotations 下列出,如以下精简示例输出所示:

    Name:                    azure-load-balancer
    Namespace:               default
    Labels:                  <none>
    Annotations:             service.beta.kuberenetes.io/azure-dns-label-name: <unique-service-label>
    

疑难解答

如果 Kubernetes 服务清单的属性“loadBalancerIP”中定义的静态 IP 地址不存在或尚未在节点资源组中创建,并且也尚未配置其他托管,则负载均衡器服务创建将会失败。 若要排除此故障,请使用 kubectl describe 命令查看服务创建事件。 提供 YAML 清单中指定的服务的名称,如以下示例中所示:

kubectl describe service azure-load-balancer

输出将显示有关 Kubernetes 服务资源的信息。 以下示例输出显示了 Events 中的 Warning:“user supplied IP address was not found”。在这些情况下,请确认是否已在节点资源组中创建静态公共 IP 地址,以及在 Kubernetes 服务清单中指定的 IP 地址是否正确。

Name:                     azure-load-balancer
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=azure-load-balancer
Type:                     LoadBalancer
IP:                       10.0.18.125
IP:                       40.121.183.52
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  32582/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                      Age               From                Message
  ----     ------                      ----              ----                -------
  Normal   CreatingLoadBalancer        7s (x2 over 22s)  service-controller  Creating load balancer
  Warning  CreatingLoadBalancerFailed  6s (x2 over 12s)  service-controller  Error creating load balancer (will retry): Failed to create load balancer for service default/azure-load-balancer: user supplied IP Address 40.121.183.52 was not found

后续步骤

若要更好地控制发向应用程序的网络流量,请使用 AKS 的应用程序路由加载项。 有关应用程序路由加载项的详细信息,请参阅使用应用程序路由加载项的托管 NGINX 入口