Ingress DNS
为您的 minikube 服务器上运行的 Ingress 控制器提供的 DNS 服务
概述
问题
在本地运行 minikube 时,您可能希望在 Ingress 控制器上运行您的服务,这样您就不必使用 minikube tunnel 或 NodePorts 来访问您的服务。虽然在许多情况下 NodePort 可能会很好,但 Ingress 是测试某些功能所必需的。Ingress 控制器非常棒,因为您可以在类似 Helm Chart 的东西中定义整个架构,并且您的所有服务都将可用。
但是,对于 minikube 来说,还有一个额外的挑战。您的 Ingress 控制器依赖于 DNS,因此像 myservice.test
这样的本地 DNS 名称必须解析为您的 minikube ip
。真正实现此目的的唯一方法是在您的 /etc/hosts
文件中为每个服务添加一个条目。由于显而易见的原因,这会变得很混乱。对于您正在运行的每个服务,并且每个服务都有自己的 DNS 条目,您都需要手动配置它。即使您对其进行自动化,也需要依赖主机操作系统来存储配置,而不是将其存储在您的集群中。更糟糕的是,这些配置必须随着服务的添加、删除和重命名而不断维护和更新。我称之为 /etc/hosts
污染问题。
解决方案
如果您可以神奇地访问本地服务而无需编辑您的 /etc/hosts
文件会怎样? 好吧,现在你可以了。ingress-dns
插件充当在您的 Kubernetes 集群内运行的 DNS 服务。您所要做的就是安装该服务并将 minikube ip
作为 DNS 服务器添加到您的主机上。每次查询 DNS 服务时,都会向 Kubernetes 主服务发出 API 调用,以获取所有 Ingress 的列表。如果找到与名称匹配的项,则会返回与 minikube ip
匹配的 IP 地址。例如,如果 minikube ip
为 192.168.99.169
,并且在集群中配置了 myservice.test
的 Ingress 规则,则来自主机的 DNS 查询将产生
#bash:~$ nslookup myservice.test $(minikube ip)
Server: 192.168.99.169
Address: 192.168.99.169#53
Non-authoritative answer:
Name: myservice.test $(minikube ip)
Address: 192.168.99.169
安装
1启动 minikube
minikube start
2启用插件
minikube addons enable ingress
minikube addons enable ingress-dns
3添加 `minikube ip` 作为 DNS 服务器
在 Linux 上,您应该确定您的域名解析器配置,并相应地更新其配置。为此,请查看 /etc/resolv.conf
的第一行
- 如果它提到
resolvconf
,则解析很可能由 resolvconf 处理, - 如果是
# Generated by NetworkManager
,则解析由 NetworkManager 处理, - 如果类似于
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8)
,则解析由 systemd-resolved 处理。
启动 minikube,并应用以下与您的系统配置匹配的配置。
使用 resolvconf 的 Linux OS
更新文件 /etc/resolvconf/resolv.conf.d/base
以包含以下内容。
search test
nameserver 192.168.99.169
timeout 5
将 192.168.99.169
替换为 minikube ip
的输出。
如果您的 Linux OS 使用 systemctl
,请运行以下命令。
sudo resolvconf -u
systemctl disable --now resolvconf.service
如果您的 Linux OS 不使用 systemctl
,请运行以下命令。
# TODO add supporting docs for Linux OS that do not use `systemctl`
请参阅 https://linux.die.net/man/5/resolver
使用 NetworkManager 的 Linux OS
NetworkManager 可以运行集成的缓存 DNS 服务器 - dnsmasq
插件,并且可以配置为对每个域使用单独的名称服务器。
编辑 /etc/NetworkManager/NetworkManager.conf
并通过添加以下内容来启用 dns=dnsmasq
[main]
dns=dnsmasq
另请参阅 NetworkManager.conf 中的 dns=
。
配置 dnsmasq 以处理以 .test
结尾的域名
sudo mkdir -p /etc/NetworkManager/dnsmasq.d/
echo "server=/test/$(minikube ip)" | sudo tee /etc/NetworkManager/dnsmasq.d/minikube.conf
重启 Network Manager
systemctl restart NetworkManager.service
确保您的 /etc/resolv.conf
仅包含单个名称服务器
cat /etc/resolv.conf | grep nameserver
nameserver 127.0.0.1
使用 systemd-resolved 的 Linux OS
运行以下命令为 .test
域添加 minikube DNS
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/minikube.conf << EOF
[Resolve]
DNS=$(minikube ip)
Domains=~test
EOF
sudo systemctl restart systemd-resolved
在 /etc/resolver/minikube-test
中创建一个文件,包含以下内容。
domain test
nameserver 192.168.99.169
search_order 1
timeout 5
将 192.168.99.169
替换为您的 minikube ip
。
如果您有多个 minikube IP,则必须为每个 IP 配置一个文件。
请参阅 https://www.unix.com/man-page/opendarwin/5/resolver/
请注意,port
功能无法按文档所述工作。
以管理员身份打开 Powershell
并执行以下操作。
Add-DnsClientNrptRule -Namespace ".test" -NameServers "$(minikube ip)"
以下操作将在创建新规则之前删除任何匹配的规则。这对于更新 minikube ip
非常有用。
Get-DnsClientNrptRule | Where-Object {$_.Namespace -eq '.test'} | Remove-DnsClientNrptRule -Force; Add-DnsClientNrptRule -Namespace ".test" -NameServers "$(minikube ip)"
4(可选)配置集群内 DNS 服务器以解析集群内的本地 DNS 名称
有时,通过 Ingress 及其本地 DNS 名称(微服务/API/测试)访问集群内的其他应用程序很有用。在这种情况下,集群内 DNS 服务器 - CoreDNS 应该使用 ingress-dns 插件来解析本地 DNS 名称。
编辑您的 CoreDNS 配置
kubectl edit configmap coredns -n kube-system
并为您的本地域添加块
test:53 {
errors
cache 30
forward . 192.168.99.169
}
将 192.168.99.169
替换为您的 minikube ip
。
最终的 ConfigMap 应如下所示
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
...
}
test:53 {
errors
cache 30
forward . 192.168.99.169
}
kind: ConfigMap
metadata:
...
请参阅 https://kubernetes.ac.cn/docs/tasks/administer-cluster/dns-custom-nameservers/
测试
1添加测试 Ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/minikube/master/deploy/addons/ingress-dns/example/example.yaml
注意:示例 Ingress 的最低 Kubernetes 版本为 1.19
2确认 DNS 查询正在返回 A 记录
nslookup hello-john.test $(minikube ip)
nslookup hello-jane.test $(minikube ip)
3确认域名在主机操作系统上解析
ping hello-john.test
ping hello-jane.test
预期结果
PING hello-john.test (192.168.99.169): 56 data bytes
64 bytes from 192.168.99.169: icmp_seq=0 ttl=64 time=0.361 ms
PING hello-jane.test (192.168.99.169): 56 data bytes
64 bytes from 192.168.99.169: icmp_seq=0 ttl=64 time=0.262 ms
4Curl 示例服务器
curl http://hello-john.test
curl http://hello-jane.test
预期结果
Hello, world!
Version: 1.0.0
Hostname: hello-world-app-557ff7dbd8-64mtv
Hello, world!
Version: 1.0.0
Hostname: hello-world-app-557ff7dbd8-64mtv
已知问题
.localhost 始终解析为回环地址
.localhost 通常会解析为回环地址(请参阅 RFC 2606 和 RFC 6761),因此它不能用于 minikube ip
。请改用 .test、.example 或 .invalid
.local 是保留的 TLD
请勿使用 .local,因为它是 mDNS 和 bind9 DNS 服务器的保留 TLD
Mac OS
mDNS 重新加载
每次在 /etc/resolver
中创建文件或对文件进行更改时,您可能需要运行以下命令来重新加载 Mac OS mDNS 解析器。
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
待办事项
- 添加一个在主机操作系统上运行的服务,该服务将自动更新
/etc/resolver
中的文件 - 在运行
minikube addons enable ingress-dns
时启动此服务,并在运行minikube addons disable ingress-dns
时停止该服务
贡献者
此插件中使用的镜像
镜像 | 来源 | 所有者 |
---|---|---|
ingress-nginx | ingress-nginx | Kubernetes ingress-nginx |
minikube-ingress-dns | minikube-ingress-dns | Cryptex 实验室 |