如何使用ExternalDNS自动管理来自DigitalOceanKubernetes的DNS记录

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。

介绍

将 Web 应用程序部署到 Kubernetes 时,通常使用 Services 和 Ingresses 将应用程序暴露在所需域的集群之外。 这不仅涉及手动配置 Ingress,还涉及在您的提供商处手动配置 DNS 记录,这可能是一个耗时且容易出错的过程。 随着您的应用程序变得越来越复杂,这可能会成为一个障碍; 当外部 IP 发生变化时,需要相应地更新 DNS 记录。

为了克服这个问题,Kubernetes sig-network 团队 创建了 ExternalDNS,用于从 Kubernetes 集群内自动管理外部 DNS 记录。 部署后,ExternalDNS 将在后台运行,几乎不需要额外配置。 每当创建或更改服务或入口时,ExternalDNS 将立即更新记录。

在本教程中,您将通过 Helm 将 ExternalDNS 安装到您的 DigitalOcean Kubernetes 集群,并将其配置为使用 DigitalOcean 作为您的 DNS 提供程序。 然后,您将部署一个带有 Ingress 的示例 Web 应用程序,并使用 ExternalDNS 将其指向您的域名。 最后,您将拥有一个用于服务和入口的自动 DNS 记录管理系统。

先决条件

  • 一个 DigitalOcean Kubernetes 集群,您的连接配置为 kubectl 默认值。 创建集群时,在 Connect to your Cluster 步骤下显示了有关如何配置 kubectl 的说明。 要在 DigitalOcean 上创建 Kubernetes 集群,请阅读 Kubernetes 快速入门
  • 安装在本地机器上的 Helm 3 包管理器。 完成 如何使用 Helm 3 包管理器 教程在 Kubernetes 集群上安装软件的 步骤 1
  • 使用 Helm 安装在集群上的 Nginx 入口控制器,以便将 ExternalDNS 与入口资源一起使用。 为此,请遵循 如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx 入口。 您需要按照步骤 2 中的说明将 publishService 属性设置为 true
  • 具有读写权限的 DigitalOcean API 密钥(个人访问令牌)。 要创建一个,请访问 如何创建个人访问令牌
  • 完全注册的域名。 本教程将自始至终使用 echo.your_domain。 您可以在 Namecheap 上购买一个域名,在 Freenom 上免费获得一个域名,或者使用您选择的域名注册商。

第 1 步 — 使用 Helm 安装 ExternalDNS

在本节中,您将使用 Helm 将 ExternalDNS 安装到您的集群,并将其配置为与 DigitalOcean DNS 服务一起使用。

为了覆盖 ExternalDNS Helm 图表的一些默认设置,您需要创建一个 values.yaml 文件,您将在安装期间将其传递给 Helm。 在先决条件中用于访问集群的机器上,通过运行以下命令创建文件:

nano externaldns-values.yaml

添加以下行:

externaldns-values.yaml

provider: digitalocean

digitalocean:
  apiToken: your_api_token

interval: "1m"

policy: sync # or upsert-only

# domainFilters: [ 'your_domain' ]

在第一个块中,您将 DNS 服务提供商设置为 DigitalOcean。 然后,在下一个块中,您通过替换 your_api_token 来定义您的 DigitalOcean API 令牌。

下一行设置 ExternalDNS 轮询入口和服务更改的时间间隔。 您可以将其设置为较低的值以更快地将更改传播到您的 DNS,默认值为 1 分钟。

policy 设置决定 ExternalDNS 是仅插入 DNS 记录 (upsert-only) 还是根据需要创建和删除它们 (sync)。 幸运的是,从 0.3 版开始,ExternalDNS 通过创建随附的 TXT 记录来支持所有权概念,在其中存储有关其创建的域的信息,从而将其操作范围仅限于其创建的域。

domainFilters 参数用于限制 ExternalDNS 可以管理的域。 您可以取消注释并以字符串数组的形式输入您的域,但这不是必需的。

完成编辑后,保存并关闭文件。

ExternalDNS Helm 图表是 Bitnami 图表库 的一部分。 通过运行以下命令将其添加到您的 Helm 安装中:

helm repo add bitnami https://charts.bitnami.com/bitnami

然后,刷新 Helm 的缓存以下载其内容:

helm repo update

最后,运行以下命令将 ExternalDNS 安装到您的集群:

helm install external-dns bitnami/external-dns -f externaldns-values.yaml

输出将类似于以下内容:

OutputNAME: external-dns
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **

To verify that external-dns has started, run:

  kubectl --namespace=default get pods -l "app.kubernetes.io/name=external-dns,app.kubernetes.io/instance=external-dns"

您可以通过运行验证 ExternalDNS 创建:

kubectl --namespace=default get pods -l "app.kubernetes.io/name=external-dns,app.kubernetes.io/instance=external-dns"
OutputNAME                            READY   STATUS    RESTARTS   AGE
external-dns-56c85ff66b-2vm88   1/1     Running   0          24s

您已将 ExternalDNS 安装到 Kubernetes 集群。 接下来,您将部署一个示例 Web 应用程序,使用 Nginx Ingress 公开它,并让 ExternalDNS 自动将您的域名指向适当的负载均衡器。

第 2 步 — 部署和公开示例 Web 应用程序

在本节中,您将部署一个虚拟 Web 应用程序到您的集群,以便使用您的 Ingress 公开它。 然后,您将设置 ExternalDNS 以自动为您配置 DNS 记录。 最后,您的域的 DNS 记录将指向 Ingress 的负载均衡器。

您将部署的虚拟 Web 应用程序是 Hashicorp 的 http-echo。 它是一个内存中的 Web 服务器,可以回显您给它的消息。 您将其 Kubernetes 清单存储在一个名为 echo.yaml 的文件中。 创建它并打开它进行编辑:

nano echo.yaml

将以下行添加到您的文件中:

回声.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: "echo.your_domain"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: echo
            port:
              number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 3
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Echo!"
        ports:
        - containerPort: 5678

在此配置中,您定义了一个部署、一个入口和一个服务。 Deployment 由 http-echo 应用程序的三个副本组成,并传入了一条自定义消息 (Echo!)。 Service 被定义为允许通过端口 80 访问 Deployment 中的 Pod。 Ingress 配置为在您的域中公开服务。

echo.your_domain 替换为您的域,然后保存并关闭文件。

现在您无需手动配置域的 DNS 记录。 将配置应用到 Kubernetes 后,ExternalDNS 将自动执行此操作。

要应用配置,请运行以下命令:

kubectl create -f echo.yaml

您将收到以下输出:

Outputingress.extensions/echo-ingress created
service/echo created
deployment.apps/echo created

您需要等待一小段时间,ExternalDNS 才能注意到更改并创建相应的 DNS 记录。 Helm 图表中的 interval 设置控制您需要等待 DNS 记录创建的时间长度。 在externaldns-values.yaml中,间隔长度默认设置为1分钟。

您可以访问您的 DigitalOcean 控制面板以查找 A 和 TXT 记录。

一旦指定的时间间隔过去,或者您在控制面板中找到记录,请使用 curl 访问您的域:

curl echo.your_domain

您将收到以下输出:

OutputEcho!

此消息确认您已配置 ExternalDNS 并创建了必要的 DNS 记录以指向 Nginx Ingress Controller 的负载均衡器。 如果您有错误消息,请给它一些时间。 或者,您可以尝试从您的浏览器访问您的域,您将收到 Echo!

您已经通过使用 Ingress 部署示例应用程序来测试 ExternalDNS。 您还可以在 DigitalOcean 控制面板中观察新的 DNS 记录。 在下一步中,您将在您的域名下公开该服务。

第 3 步 - (可选)使用服务公开应用程序

在此可选部分中,您将使用带有 ExternalDNS 而不是 Ingress 的服务。 ExternalDNS 允许您为 DNS 服务器提供不同的 Kubernetes 资源。 使用服务与修改此备用资源的配置的 Ingress 类似。

注意:执行此步骤将删除您刚刚创建的DNS记录。


由于您将自定义包含在 echo.yaml 中的服务,因此您将不再需要 echo-ingress。 使用以下命令将其删除:

kubectl delete ing echo-ingress

输出将是:

Outputingress.extensions/echo-ingress deleted

ExternalDNS 将删除它在上一步中创建的现有 DNS 记录。 在该步骤的剩余部分中,您可以使用之前使用过的同一个域。

接下来,打开echo.yaml文件进行编辑:

nano echo.yaml

用以下几行替换文件内容:

回声.yaml

apiVersion: v1
kind: Service
metadata:
  name: echo
  annotations:
    external-dns.alpha.kubernetes.io/hostname: echo.your_domain
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 3
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Echo!"
        ports:
        - containerPort: 5678

您已从先前设置的文件中删除了 Ingress,并将服务类型更改为 LoadBalancer。 此外,您还添加了一个注释,指定了 ExternalDNS 的域名。

通过运行以下命令将更改应用到集群:

kubectl apply -f echo.yaml

输出将是:

Output...
service/echo configured
deployment.apps/echo configured

您可以通过运行以下命令检查服务的负载均衡器是否可用:

kubectl get svc echo -w
OutputNAME   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
echo   LoadBalancer   10.245.81.235   <pending>     80:31814/TCP   8s
...

与上一步一样,您需要等待一段时间才能创建和传播 DNS 记录。 完成后,curl 您指定的域:

curl echo.your_domain

输出将与上一步相同:

OutputEcho!

如果出现错误,请稍等片刻,或者您可以尝试其他域。 由于 DNS 记录缓存在客户端系统上,因此更改可能需要很长时间才能真正传播。

在此步骤中,您创建了一个服务(类型为 LoadBalancer)并使用 ExternalDNS 将其指向您的域名。

结论

ExternalDNS 在后台静默工作,提供无摩擦的体验。 您的 Kubernetes 集群刚刚成为有关域的核心信息来源。 您不再需要手动更新 DNS 记录。

当从持续交付系统创建测试环境时,ExternalDNS 的真正威力将变得显而易见。 如果您想在 Kubernetes 集群上设置这样的系统,请访问 如何在 DigitalOcean Kubernetes 上使用 Spinnaker 设置 CD 管道