安装 ExternalDNS 以进行服务发现

本主题介绍了如何将 ExternalDNS 部署到 Tanzu Kubernetes Grid 中的工作负载集群。

ExternalDNS 服务使用声明性 Kubernetes 本机接口将应用程序的 DNS 记录发布到 DNS 服务器。在 Tanzu Kubernetes Grid 中它打包为 CLI 管理的软件包

对于在具有负载均衡的共享服务集群(AWS、Azure 和使用 NSX Advanced Load Balancer 的 vSphere)中部署 Harbor 的环境,可以使用 ExternalDNS 为 Harbor 服务发布 DNS 主机名。这提供了从其他集群访问 Harbor 的权限。有关详细信息,请参见 Harbor 注册表和 ExternalDNS

必备条件

  • 安装了以下内容的引导计算机:
    • Tanzu CLI、Tanzu CLI 插件和 kubectl
    • yq v4.5 或更高版本。
  • 您已在 vSphere、Amazon Web Services (AWS) 或 Azure 上部署管理集群,不管是连接到 Internet 的环境还是 Internet 受限环境。如果在 Internet 受限环境中使用 Tanzu Kubernetes Grid,请在部署管理集群之前,先执行准备将管理集群部署到 Internet 受限环境中的过程。
  • 您已使用 tanzu context use 命令登录到 Tanzu CLI。
  • 您已确定要通过 ExternalDNS 向 DNS 服务器公开的服务的完全限定域名 (FQDN)。

为 ExternalDNS 部署准备集群

ExternalDNS 服务必须与它将导出 DNS 记录的服务部署到相同的集群中。

  • 要安装 Harbor,请遵循安装 Harbor for Service Registry 中的必备条件和过程。
  • ExternalDNS 支持为 Kubernetes 服务和 Contour HTTPProxy 资源创建记录。如果要为工作负载集群中的 Contour HTTPProxy 资源创建记录,则必须在集群中安装 Contour 软件包。有关说明,请参见安装 Contour 以进行 Ingress 控制。Harbor 也需要 Contour 软件包。

为 ExternalDNS 软件包准备配置文件

已对 AWS (Route 53)、Azure DNS 和 RFC2136 (BIND) 验证 ExternalDNS 软件包。提供的配置导出 LoadBalancer 类型的 Contour HTTPProxy 资源和 Kubernetes Services 的记录。

外部 DNS 社区以不同的稳定性级别与许多 DNS 提供程序保持集成。除非另有说明,VMware 不保证支持将 ExternalDNS 软件包与特定提供程序集成。

AWS (Route 53)
要准备配置文件以在 AWS 上部署 ExternalDNS 软件包,请执行以下操作:
  1. 使用服务将使用的域在 Route 53 中创建托管区域。
  2. 记录托管区域 ID (Hosted zone ID)。稍后,在配置 ExternalDNS 时,您将使用此 ID。
  3. 为 ExternalDNS 创建允许 ExternalDNS 更新 Route 53 的 IAM 策略。在 AWS 控制台中,转到 IAM 仪表板,然后在访问管理 (access Management)下,导航到策略 (Policies)屏幕。单击创建策略 (Create Policy)并切换到 JSON 选项卡。粘贴到以下策略中。如果需要,可以对策略进行微调,以允许更新刚创建的托管区域。完成向导中的操作。

    {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "route53:ChangeResourceRecordSets"
         ],
         "Resource": [
           "arn:aws:route53:::hostedzone/*"
         ]
       },
       {
         "Effect": "Allow",
         "Action": [
           "route53:ListHostedZones",
           "route53:ListResourceRecordSets"
         ],
         "Resource": [
           "*"
         ]
       }
     ]
    }
    
  4. 使用上面创建的策略 创建 ExternalDNS 的 IAM 用户。在 AWS 控制台中,转到用户 (Users)屏幕,然后单击添加用户 (Add users)。提供 IAM 用户的名称,并确保启用编程访问 (Programmatic access)。在向导的权限 (Permissions)屏幕上,单击直接附加现有策略 (Attach existing policies directly),然后选择在上一步中创建的策略。

  5. 继续到向导的最后一页。记录访问密钥 ID (Access key ID)私有访问密钥 (Secret access key)。要使这些 Route 53 凭据可用于 ExternalDNS,请在将运行 ExternalDNS 的命名空间中创建 Kubernetes 密钥。

    1. kubectl 的上下文设置为要部署 ExternalDNS 的集群。例如:

      kubectl config use-context tkg-services-admin@tkg-services
      
    2. 创建 Kubernetes 密钥:

      kubectl -n tanzu-system-service-discovery create secret generic route53-credentials \
      --from-literal=aws_access_key_id=YOUR-ACCESS-KEY-ID \
      --from-literal=aws_secret_access_key=YOUR-SECRET-ACCESS-KEY
      

      其中,YOUR-ACCESS-KEY-IDYOUR-SECRET-ACCESS-KEY 是您在上面记录的凭据。

  6. 通过检索 ExternalDNS 软件包的默认配置为该软件包创建配置文件:

    tanzu package available get external-dns.tanzu.vmware.com/PACKAGE-VERSION --default-values-file-output FILE-PATH
    

    其中,PACKAGE-VERSION 是要安装的 ExternalDNS 软件包的版本,FILE-PATH 是要将配置文件保存到的位置,例如,external-dns-data-values.yaml

  7. external-dns-data-values.yaml 文件中配置以下设置。此文件用于配置 ExternalDNS 软件包。

    ---
    
    # Namespace in which to deploy ExternalDNS pods.
    namespace: tanzu-system-service-discovery
    
    # Deployment-related configuration.
    deployment:
    args:
      - --source=service
      - --source=ingress
      - --source=contour-httpproxy # Provide this to enable Contour HTTPProxy support. Must have Contour installed or ExternalDNS will fail.
      - --domain-filter=DOMAIN # Makes ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones.
      - --policy=upsert-only # Prevents ExternalDNS from deleting any records, omit to enable full synchronization.
      - --registry=txt
      - --txt-owner-id=HOSTED-ZONE-ID
      - --txt-prefix=txt # Disambiguates TXT records from CNAME records.
      - --provider=aws
      - --aws-zone-type=public # Looks only at public hosted zones. Valid values are public, private, or no value for both.
      - --aws-prefer-cname
    env:
      - name: AWS_ACCESS_KEY_ID
         valueFrom:
         secretKeyRef:
            name: route53-credentials
            key: aws_access_key_id
      - name: AWS_SECRET_ACCESS_KEY
         valueFrom:
         secretKeyRef:
            name: route53-credentials
            key: aws_secret_access_key
    securityContext: {}
    volumeMounts: []
    volumes: []
    

    external-dns-data-values.yaml 文件中的占位符替换为您的值。有关更多配置选项,请参见 ExternalDNS 文档。

    external-dns-data-values.yaml 文件中设置任何其他配置选项之前,请查看 ExternalDNS 软件包的值结构定义。要检索值结构定义,请运行:

    tanzu package available get external-dns.tanzu.vmware.com/AVAILABLE-VERSION --values-schema
    

    其中,AVAILABLE-VERSION 是 ExternalDNS 软件包的版本。--values-schema 标记从 ExternalDNS 软件包的 Package API 资源检索 valuesSchema 部分。您可以将值结构定义的输出格式 --output 设置为 yamljsontable。有关详细信息,请参见安装和管理软件包中的软件包

RFC2136 (BIND) 服务器
RFC2136 提供程序允许您使用任何与 RFC2136 兼容的 DNS 服务器作为 ExternalDNS 的提供程序,例如 BIND。
  1. 请求或创建服务器的 TSIG 密钥。必须授权此密钥才能更新和传输要更新的区域。密钥看上去与下面类似:

    key "externaldns-key" {
    algorithm hmac-sha256;
    secret "/2avn5M4ndEztbDqy66lfQ+PjRZta9UXLtToW6NV5nM=";
    };
    

    如果您要管理自己的 DNS 服务器,则可以使用 tsig-keygen -a hmac-sha256 externaldns 命令创建 TSIG 密钥。将输出复制到 DNS 服务器配置。例如,对于 BIND,您可以将密钥添加到 named.conf 文件,并为该区域配置 allow-transferupdate-policy 字段。例如:

    key "externaldns-key" {
    algorithm hmac-sha256;
    secret "/2avn5M4ndEztbDqy66lfQ+PjRZta9UXLtToW6NV5nM=";
    };
    zone "k8s.example.org" {
    type master;
    file "/etc/bind/zones/k8s.zone";
          allow-transfer {
          key "externaldns-key";
          };
          update-policy {
          grant externaldns-key zonesub ANY;
          };
    };
    

    上面假设您还具有类似于以下内容的区域文件:

    $TTL 60 ; 1 minute
    @         IN SOA  k8s.example.org.  root.k8s.example.org. (
                      16  ; serial
                      60  ; refresh (1 minute)
                      60  ; retry (1 minute)
                      60  ; expire (1 minute)
                      60  ; minimum (1 minute)
                      )
                NS   ns.k8s.example.org.
    ns           A    1.2.3.4
    
  2. 通过检索 ExternalDNS 软件包的默认配置为该软件包创建配置文件:

    tanzu package available get external-dns.tanzu.vmware.com/PACKAGE-VERSION --default-values-file-output FILE-PATH
    

    其中,PACKAGE-VERSION 是要安装的 ExternalDNS 软件包的版本,FILE-PATH 是要将配置文件保存到的位置,例如,external-dns-data-values.yaml

  3. external-dns-data-values.yaml 文件中配置以下设置。此文件用于配置 ExternalDNS 软件包。

    ---
    
    # Namespace in which to deploy ExternalDNS pods.
    namespace: tanzu-system-service-discovery
    
    # Deployment-related configuration.
    deployment:
    args:
       - --source=service
       - --source=ingress
       - --source=contour-httpproxy # Provide this to enable Contour HTTPProxy support. Must have Contour installed or ExternalDNS will fail.
       - --domain-filter=DOMAIN # For example, k8s.example.org. Makes ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones.
       - --policy=upsert-only # Prevents ExternalDNS from deleting any records, omit to enable full synchronization.
       - --registry=txt
       - --txt-owner-id=k8s
       - --txt-prefix=external-dns- # Disambiguates TXT records from CNAME records.
       - --provider=rfc2136
       - --rfc2136-host=IP-ADDRESS-OF-RFC2136-DNS-SERVER
       - --rfc2136-port=53
       - --rfc2136-zone=DNS-ZONE # For example, k8s.example.org.
       - --rfc2136-tsig-secret=TSIG-SECRET-FROM-STEP-1
       - --rfc2136-tsig-secret-alg=hmac-sha256
       - --rfc2136-tsig-keyname=TSIG-KEY-NAME # For example, externaldns-key.
       - --rfc2136-tsig-axfr
    env: []
    securityContext: {}
    volumeMounts: []
    volumes: []
    

    external-dns-data-values.yaml 文件中的占位符替换为您的值。有关更多配置选项,请参见 ExternalDNS 文档。

    external-dns-data-values.yaml 文件中设置任何其他配置选项之前,请查看 ExternalDNS 软件包的值结构定义。要检索值结构定义,请运行:

    tanzu package available get external-dns.tanzu.vmware.com/AVAILABLE-VERSION --values-schema
    

    其中,AVAILABLE-VERSION 是 ExternalDNS 软件包的版本。--values-schema 标记从 ExternalDNS 软件包的 Package API 资源检索 valuesSchema 部分。您可以将值结构定义的输出格式 --output 设置为 yamljsontable。有关详细信息,请参见安装和管理软件包中的软件包

Azure
要准备配置文件以在 Azure 上部署 ExternalDNS 软件包,请执行以下操作:
  1. 登录到 az CLI:

    az login
    
  2. 设置订阅:

    az account set -s SUBSCRIPTION-ID-GUID
    
  3. 创建服务主体:

    az ad sp create-for-rbac -n SERVICE-PRINCIPAL-NAME
    

    命令的 JSON 输出类似于以下内容:

    {
      "appId": "a72a7cfd-7cb0-4b02-b130-03ee87e6ca89",
      "displayName": "foo",
      "name": "http://foo",
      "password": "515c55da-f909-4e17-9f52-236ffe1d3033",
      "tenant": "b35138ca-3ced-4b4a-14d6-cd83d9ea62f0"
    }
    
  4. 将权限分配给服务主体:

    1. 检索资源组的 ID:

      az group show --name RESOURCE-GROUP --query id
      
    2. 将读取者角色分配给资源组范围的服务主体。您需要从上述 az ad sp create-for-rbac 命令的输出中获得 appId

      az role assignment create --role "Reader" --assignee APP-ID-GUID --scope RESOURCE-GROUP-RESOURCE-ID
      
    3. 检索 DNS 区域的 ID:

      az network dns zone show --name DNS-ZONE-NAME -g RESOURCE-GROUP-NAME --query id
      
    4. 将参与者角色分配给 DNS 区域范围的服务主体:

      az role assignment create --role "Contributor" --assignee APP-ID-GUID --scope DNS-ZONE-RESOURCE-ID
      
  5. 要将 ExternalDNS 服务连接到 Azure DNS 服务,请在本地计算机上创建一个名为 azure.json 的配置文件,其中包含如下内容:

    {
     "tenantId": "01234abc-de56-ff78-abc1-234567890def",
     "subscriptionId": "01234abc-de56-ff78-abc1-234567890def",
     "resourceGroup": "MyDnsResourceGroup",
     "aadClientId": "01234abc-de56-ff78-abc1-234567890def",
     "aadClientSecret": "uKiuXeiwui4jo9quae9o"
    }
    

    将上述示例中的值替换为您自己的值,如下所示:

    • 要检索 tenantId,您可以运行 az account show --query "tenantId" 命令。
    • 要检索 subscriptionId,您可以运行 az account show --query "id" 命令。
    • resourceGroup 是 DNS 区域所在的资源组的名称。
    • aadClientId 是服务主体输出中的 appId
    • aadClientSecret 是服务主体输出中的密码。
  6. 要使 Azure 凭据可用于 ExternalDNS,请在将运行 ExternalDNS 的命名空间中创建 Kubernetes 密钥:

    1. kubectl 的上下文设置为要部署 ExternalDNS 的集群。例如:

      kubectl config use-context tkg-services-admin@tkg-services
      
    2. 使用上一步中的 azure.json 配置文件创建密钥:

      kubectl -n tanzu-system-service-discovery create secret generic azure-config-file --from-file=azure.json
      
  7. 通过检索 ExternalDNS 软件包的默认配置为该软件包创建配置文件:

    tanzu package available get external-dns.tanzu.vmware.com/PACKAGE-VERSION --default-values-file-output FILE-PATH
    

    其中,PACKAGE-VERSION 是要安装的 ExternalDNS 软件包的版本,FILE-PATH 是要将配置文件保存到的位置,例如,external-dns-data-values.yaml

  8. external-dns-data-values.yaml 文件中配置以下设置。此文件用于配置 ExternalDNS 软件包。

    ---
    
    # Namespace in which to deploy ExternalDNS.
    namespace: tanzu-system-service-discovery
    
    # Deployment-related configuration.
    deployment:
     args:
       - --source=service
       - --source=ingress
       - --source=contour-httpproxy # Provide this to enable Contour HTTPProxy support. Must have Contour installed or ExternalDNS will fail.
       - --domain-filter=DOMAIN # For example, k8s.example.org. Makes ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones.
       - --policy=upsert-only # Prevents ExternalDNS from deleting any records, omit to enable full synchronization.
       - --registry=txt
       - --txt-prefix=externaldns- # Disambiguates TXT records from CNAME records.
       - --provider=azure
       - --azure-resource-group=RESOURCE-GROUP # Azure resource group.
     env: []
     securityContext: {}
     volumeMounts:
       - name: azure-config-file
         mountPath: /etc/kubernetes
         readOnly: true
     volumes:
       - name: azure-config-file
         secret:
           secretName: azure-config-file
    

    external-dns-data-values.yaml 文件中的占位符替换为您的值。有关更多配置选项,请参见 ExternalDNS 文档。

    external-dns-data-values.yaml 文件中设置任何其他配置选项之前,请查看 ExternalDNS 软件包的值结构定义。要检索值结构定义,请运行:

    tanzu package available get external-dns.tanzu.vmware.com/AVAILABLE-VERSION --values-schema
    

    其中,AVAILABLE-VERSION 是 ExternalDNS 软件包的版本。--values-schema 标记从 ExternalDNS 软件包的 Package API 资源检索 valuesSchema 部分。您可以将值结构定义的输出格式 --output 设置为 yamljsontable。有关详细信息,请参见安装和管理软件包中的软件包


安装 ExternalDNS 软件包

  1. kubectl 的上下文设置为要部署 ExternalDNS 的集群。例如:

    kubectl config use-context tkg-services-admin@tkg-services
    
  2. 如果集群没有安装有 ExternalDNS 软件包的软件包存储库,例如 tanzu-standard 存储库,请安装一个:

    tanzu package repository add PACKAGE-REPO-NAME --url PACKAGE-REPO-ENDPOINT --namespace tkg-system
    

    其中:

    • PACKAGE-REPO-NAME 是软件包存储库的名称,如 tanzu-standard 或使用 ADDITIONAL_IMAGE_REGISTRY 变量配置的专用映像注册表的名称。
    • PACKAGE-REPO-ENDPOINT 是软件包存储库的 URL。

      • 对于此版本,tanzu-standard URL 为 projects.registry.vmware.com/tkg/packages/standard/repo:v2023.10.16。要从 Tanzu CLI 获取此值,请参见列出软件包存储库,或在 Tanzu Mission Control 中查看集群 (Cluster) 窗格中的附加模块 (Addons) > 存储库 (Repositories) 列表。
  3. 检索 ExternalDNS 软件包的名称:

    tanzu package available list -A
    
  4. 检索 ExternalDNS 软件包的版本:

    tanzu package available list external-dns.tanzu.vmware.com -A
    
  5. 如果 external-dns-data-values.yaml 文件包含注释,请在安装软件包之前将注释移除:

    yq -i eval '... comments=""' external-dns-data-values.yaml
    
  6. 安装软件包:

    tanzu package install external-dns \
    --package external-dns.tanzu.vmware.com \
    --version AVAILABLE-PACKAGE-VERSION \
    --values-file external-dns-data-values.yaml \
    --namespace TARGET-NAMESPACE
    

    其中:

    • TARGET-NAMESPACE 是要在其中安装 ExternalDNS 软件包的命名空间。例如,my-packagestanzu-cli-managed-packages 命名空间。

      • 如果未指定 --namespace 标记,则 Tanzu CLI 会在 default 命名空间中安装软件包。ExternalDNS pod 以及与 ExternalDNS 组件关联的任何其他资源是在 tanzu-system-service-discovery 命名空间中创建的;请勿将 ExternalDNS 软件包安装到此命名空间中。
      • 指定的命名空间必须已存在,例如,通过运行 kubectl create namespace my-packages
    • AVAILABLE-PACKAGE-VERSION 是上面检索到的版本。

    例如:

    tanzu package install external-dns \
    --package external-dns.tanzu.vmware.com \
    --version 0.10.0+vmware.1-tkg.1 \
    --values-file external-dns-data-values.yaml \
    --namespace my-packages
    
  7. 确认已安装 external-dns 软件包:

    tanzu package installed list -A
    

    要查看有关软件包的更多详细信息,还可以运行:

    tanzu package installed get external-dns --namespace PACKAGE-NAMESPACE
    

    其中,PACKAGE-NAMESPACE 是安装 external-dns 软件包的命名空间。

  8. 确认 external-dns 应用已在 PACKAGE-NAMESPACE 中成功协调:

    kubectl get apps -A
    

    如果状态不是 Reconcile Succeeded,请查看 external-dns 应用的完整状态详细信息。查看完整状态可帮助您解决问题。

    kubectl get app external-dns --namespace PACKAGE-NAMESPACE -o yaml
    

    其中,PACKAGE-NAMESPACE 是安装软件包的命名空间。如果故障排除无法帮助您解决问题,则必须先卸载软件包,然后再重新安装:

    tanzu package installed delete external-dns --namespace PACKAGE-NAMESPACE
    
  9. 确认 ExternalDNS pod 正在 tanzu-system-service-discovery 命名空间中运行:

    kubectl get pods -A
    

正在验证 ExternalDNS

如果配置了 Contour,ExternalDNS 将自动监视 HTTPProxy 资源的指定命名空间,并为主机名与配置的域筛选器匹配的服务创建 DNS 记录。

ExternalDNS 还会自动监视带注释 external-dns.alpha.kubernetes.io/hostname 的 Kubernetes 服务,并为其注释与配置的域筛选器匹配的服务创建 DNS 记录。

例如,对于带有注释 external-dns.alpha.kubernetes.io/hostname: foo.k8s.example.org 的服务,ExternalDNS 将为 foo.k8s.example.org 创建 DNS 记录。可以通过检查您创建的区域来验证记录是否存在。

更新正在运行的 ExternalDNS 部署

如果需要在部署后更改 ExternalDNS 软件包的配置,请按照以下步骤更新部署的 ExternalDNS 软件包。

  1. external-dns-data-values.yaml 中更新 ExternalDNS 配置。

  2. 更新已安装软件包的配置:

    tanzu package installed update external-dns \
    --version INSTALLED-PACKAGE-VERSION \
    --values-file external-dns-data-values.yaml \
    --namespace INSTALLED-PACKAGE-NAMESPACE
    

    其中:

    • INSTALLED-PACKAGE-VERSION 是已安装 ExternalDNS 软件包的版本。
    • INSTALLED-PACKAGE-NAMESPACE 是安装 ExternalDNS 软件包的命名空间。

    例如:

    tanzu package installed update external-dns \
    --version 0.10.0+vmware.1-tkg.1 \
    --values-file external-dns-data-values.yaml \
    --namespace my-packages
    

将使用您添加的新值协调 ExternalDNS 软件包。kapp-controller 应用更改可能需要长达五分钟的时间。

有关 tanzu package installed update 命令的详细信息,请参见安装和管理软件包中的更新软件包。您可以使用以下命令更新已安装软件包的版本或配置。

check-circle-line exclamation-circle-line close-line
Scroll to top icon