你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用应用程序路由加载项将 NGINX 入口控制器配置为支持 Azure 专用 DNS 区域

本文演示了如何将 NGINX 入口控制器配置为与 Azure 内部负载均衡器协同工作,以及如何配置专用 Azure DNS 区域来使专用终结点的 DNS 解析能够解析特定域。

开始之前

连接到 AKS 群集

若要从本地计算机连接到 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 可以使用 az aks install-cli 命令在本地安装它。 如果使用的是 Azure Cloud Shell,则 kubectl 已安装。

以下示例使用 az aks get-credentials 命令连接到 myResourceGroup 中名为 myAKSCluster 的群集。

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

创建虚拟网络

若要向虚拟网络发布专用 DNS 区域,你需要指定一个列表,在其中包含允许在该区域中解析记录的虚拟网络。 这些条目被称为虚拟网络链接

以下示例在名为 myResourceGroup 的资源组中创建一个名为 myAzureVNet 的虚拟网络,并在该 VNet 中创建一个名为 mySubnet 且具有特定地址前缀的子网。

az network vnet create \
  --name myAzureVNet \
  --resource-group myResourceGroup \
  --location eastus \
  --address-prefix 10.2.0.0/16 \
  --subnet-name mysubnet \
  --subnet-prefixes 10.2.0.0/24

创建 Azure 专用 DNS 区域

注意

你可以将应用路由加载项配置为自动在一个或多个 Azure 全局和专用 DNS 区域中为 Ingress 资源上定义的主机创建记录。 所有全局 Azure DNS 区域和所有专用 Azure DNS 区域都需要位于同一资源组中。

你将使用 az network private-dns zone create 命令创建 DNS 区域,并且需要指定区域名称和要在其中创建该区域的资源组。 以下示例在 myResourceGroup 资源组中创建名为 private.contoso.com 的 DNS 区域。

az network private-dns zone create --resource-group myResourceGoup --name private.contoso.com

你将使用 az network private-dns link vnet create 命令创建之前创建的 DNS 区域的虚拟机链接。 以下示例为虚拟网络 myAzureVNet 创建名为 myDNSLink 的链接,以链接到区域 private.contoso.com。 请包括 --registration-enabled 参数来指定链接不启用注册。

az network private-dns link vnet create --resource-group myResourceGroup \
  --name myDNSLink \
  --zone-name private.contoso.com \
  --virtual-network myAzureVNet \
  --registration-enabled false

Azure DNS 专用区域自动注册功能管理部署在虚拟网络中的虚拟机的 DNS 记录。 在启用此设置的情况下将虚拟网络与专用 DNS 区域链接在一起时,系统会为虚拟网络中部署的 AKS 节点的每个虚拟机创建 DNS 记录。

将 Azure 专用 DNS 区域附加到应用程序路由加载项

注意

az aks approuting zone add 命令使用运行该命令的用户的权限来创建 Azure DNS 区域角色分配。 “专用 DNS 区域参与者”角色是用于管理专用 DNS 资源的内置角色,并分配给该加载项的托管标识。 有关 AKS 托管标识的详细信息,请参阅托管标识摘要

  1. 使用 az network dns zone show 命令检索 DNS 区域的资源 ID,并将输出设置为名为 ZONEID 的变量。 以下示例查询 myResourceGroup 资源组中的 private.contoso.com 区域。

    ZONEID=$(az network private-dns zone show --resource-group myResourceGroup --name private.contoso.com --query "id" --output tsv)
    
  2. 使用 az aks approuting zone 命令更新加载项以启用与 Azure DNS 的集成。 可以传递以逗号分隔的 DNS 区域资源 ID 列表。 以下示例更新 myResourceGroup 资源组中的 AKS 群集 myAKSCluster。

    az aks approuting zone add --resource-group myResourceGroup --name myAKSCluster --ids=${ZONEID} --attach-zones
    

创建具有专用 IP 地址和内部负载均衡器的 NGINX 入口控制器

应用程序路由附加产品使用称作 NginxIngressController 的 Kubernetes 自定义资源定义 (CRD) 来配置 NGINX 入口控制器。 你可以创建更多入口控制器或修改现有配置。

NginxIngressController CRD 有一个 loadBalancerAnnotations 字段,该字段通过设置负载均衡器注释来控制 NGINX 入口控制器的行为。

执行以下步骤来创建具有面向内部的 Azure 负载均衡器(使用专用 IP 地址)的 NGINX 入口控制器。

  1. 将以下 YAML 清单复制到名为 nginx-internal-controller.yaml 的新文件中,并将该文件保存到本地计算机。

    apiVersion: approuting.kubernetes.azure.com/v1alpha1
    kind: NginxIngressController
    metadata:
      name: nginx-internal
    spec:
      ingressClassName: nginx-internal
      controllerNamePrefix: nginx-internal
      loadBalancerAnnotations: 
        service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    
  2. 使用 kubectl apply 命令创建 NGINX 入口控制器资源。

    kubectl apply -f nginx-internal-controller.yaml
    

    以下示例输出显示了已创建的资源:

    nginxingresscontroller.approuting.kubernetes.azure.com/nginx-internal created
    
  3. 验证是否已创建入口控制器

    可以使用 kubectl get nginxingresscontroller 命令验证 NGINX 入口控制器的状态。

    kubectl get nginxingresscontroller
    

    以下示例输出显示了创建的资源。 控制器可能需要几分钟时间才可用:

    NAME             INGRESSCLASS                         CONTROLLERNAMEPREFIX   AVAILABLE
    default          webapprouting.kubernetes.azure.com   nginx                  True
    nginx-internal   nginx-internal                       nginx-internal         True
    

部署应用程序

应用程序路由附加产品使用 Kubernetes Ingress 对象的注释来创建适当的资源。

  1. 使用 kubectl create namespace 命令创建名为 hello-web-app-routing 的应用程序命名空间以运行示例 Pod。

    kubectl create namespace hello-web-app-routing
    
  2. 通过将以下 YAML 清单复制到名为 deployment.yaml 的新文件中来创建部署,并将该文件保存到本地计算机。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aks-helloworld  
      namespace: hello-web-app-routing
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aks-helloworld
      template:
        metadata:
          labels:
            app: aks-helloworld
        spec:
          containers:
          - name: aks-helloworld
            image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
            ports:
            - containerPort: 80
            env:
            - name: TITLE
              value: "Welcome to Azure Kubernetes Service (AKS)"
    
  3. 通过将以下 YAML 清单复制到名为 service.yaml 的新文件中来创建服务,并将该文件保存到本地计算机。

    apiVersion: v1
    kind: Service
    metadata:
      name: aks-helloworld
      namespace: hello-web-app-routing
    spec:
      type: ClusterIP
      ports:
      - port: 80
      selector:
        app: aks-helloworld
    
  4. 使用 kubectl apply 命令创建群集资源。

    kubectl apply -f deployment.yaml -n hello-web-app-routing
    

    以下示例输出显示了创建的资源:

    deployment.apps/aks-helloworld created created
    
    kubectl apply -f service.yaml -n hello-web-app-routing
    

    以下示例输出显示了创建的资源:

    service/aks-helloworld created created
    

创建使用 Azure 专用 DNS 区域中的主机名和专用 IP 地址的入口资源

  1. 将以下 YAML 清单复制到名为 ingress.yaml 的新文件中,并将该文件保存到本地计算机。

    <Hostname> 更新为你的 DNS 主机的名称,例如 helloworld.private.contoso.com。 验证你是否为 ingressClassName 指定了 nginx-internal

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: aks-helloworld
      namespace: hello-web-app-routing
    spec:
      ingressClassName: nginx-internal
      rules:
      - host: <Hostname>
        http:
          paths:
          - backend:
              service:
                name: aks-helloworld
                port:
                  number: 80
            path: /
            pathType: Prefix
    
  2. 使用 kubectl apply 命令创建群集资源。

    kubectl apply -f ingress.yaml -n hello-web-app-routing
    

    以下示例输出显示了已创建的资源:

    ingress.networking.k8s.io/aks-helloworld created
    

验证是否已创建托管 Ingress

可以使用 kubectl get ingress 命令验证是否已创建托管 Ingress。

kubectl get ingress -n hello-web-app-routing

以下示例输出显示了创建的托管 Ingress:

NAME             CLASS            HOSTS                            ADDRESS      PORTS   AGE
aks-helloworld   nginx-internal   helloworld.private.contoso.com   10.224.0.7   80      98s

验证 Azure 专用 DNS 区域是否已更新

几分钟后,运行 az network private-dns record-set a list 命令来查看 Azure 专用 DNS 区域的 A 记录。 指定资源组的名称和 DNS 区域的名称。 在此示例中,资源组为 myResourceGroup,DNS 区域为 private.contoso.com。

az network private-dns record-set a list --resource-group myResourceGroup --zone-name private.contoso.com

以下示例输出显示了所创建的记录:

[
  {
    "aRecords": [
      {
        "ipv4Address": "10.224.0.7"
      }
    ],
    "etag": "188f0ce5-90e3-49e6-a479-9e4053f21965",
    "fqdn": "helloworld.private.contoso.com.",
    "id": "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/resourceGroups/foo/providers/Microsoft.Network/privateDnsZones/private.contoso.com/A/helloworld",
    "isAutoRegistered": false,
    "name": "helloworld",
    "resourceGroup": "foo",
    "ttl": 300,
    "type": "Microsoft.Network/privateDnsZones/A"
  }
]

后续步骤

有关与 SSL 加密、高级 NGINX 入口控制器和入口资源配置相关的其他配置信息,请查看 DNS 和 SSL 配置以及应用程序路由加载项配置