作为Write for DOnations计划的一部分,作者选择了免费和开源基金来接受捐赠。
介绍
将 Web 应用程序部署到 Kubernetes 时,您通常使用服务和入口来在所需域中的集群之外公开应用程序。这不仅涉及手动配置 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
默认设置。创建集群时,有关如何配置的说明kubectl
显示在“连接到集群”步骤下。要在 DigitalOcean 上创建 Kubernetes 集群,请阅读Kubernetes 快速入门。 -
安装在本地机器上的 Helm 3 包管理器。完成第1步的如何与头盔3包管理器上Kubernetes集群上安装软件的教程。
-
使用 Helm 安装在集群上的 Nginx 入口控制器,以便将 ExternalDNS 与入口资源一起使用。为此,请遵循如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx Ingress。您需要按照步骤 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
添加以下几行:
provider: digitalocean
digitalocean:
apiToken: your_api_token
interval: "1m"
policy: sync # or upsert-only
# domainFilters: [ 'your_domain' ]
在第一个块中,您将 DNS 服务提供商设置为 DigitalOcean。然后,在下一个块中,您通过替换 来定义您的 DigitalOcean API 令牌your_api_token
。
下一行设置 ExternalDNS 轮询 Ingress 和服务更改的时间间隔。您可以将其设置为较低的值以更快地将更改传播到您的 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 应用程序http-echo
由 Hashicorp 提供。它是一个内存中的 Web 服务器,可以回显您给它的消息。您将其 Kubernetes 清单存储在名为echo.yaml
. 创建它并打开它进行编辑:
- nano echo.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 被定义为允许通过端口访问 Deployment 中的 Pod 80
。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 记录。interval
Helm 图表中的设置控制您等待 DNS 记录创建所需的时间长度。在 中externaldns-values.yaml
,间隔长度默认设置为 1 分钟。
您可以访问您的 DigitalOcean 控制面板以查找 A 和 TXT 记录。
一旦指定的时间间隔已过,或者您在控制面板中找到记录,请使用curl
以下命令访问您的域:
- curl echo.your_domain
您将收到以下输出:
OutputEcho!
此消息确认您已配置 ExternalDNS 并创建了必要的 DNS 记录以指向 Nginx 入口控制器的负载均衡器。如果您有错误消息,请给它一些时间。或者,您可以尝试从您将收到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
用以下几行替换文件内容:
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 管道。