Kubernetes 中的 NGINX 无法解析 DNS
Posted
技术标签:
【中文标题】Kubernetes 中的 NGINX 无法解析 DNS【英文标题】:DNS does not resolve with NGINX in Kubernetes 【发布时间】:2017-04-02 15:14:21 【问题描述】:我有一个使用 kube-aws 设置的 Kubernetes 集群。我正在尝试运行自定义 nginx 配置,该配置使用 DNS 解析来代理_pass。这是 NGINX 代码块
location /api/v1/lead
resolver 10.3.0.10 ipv6=off;
set $container lead-api;
proxy_pass http://$container:3000;
10.3.0.10 来自 Kubernetes 中找到的 DNS 服务的集群 IP。我还尝试了 127.0.0.11,这是我们在 docker-compose/docker 环境中使用的。
$ kubectl describe --namespace=kube-system service kube-dns
Name: kube-dns
Namespace: kube-system
Labels: k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=KubeDNS
Selector: k8s-app=kube-dns
Type: ClusterIP
IP: 10.3.0.10
Port: dns 53/UDP
Endpoints: 10.2.26.61:53
Port: dns-tcp 53/TCP
Endpoints: 10.2.26.61:53
Session Affinity: None
此配置适用于使用 docker-compose 的三种不同环境。但是,我在 Kubernetes 集群的 NGINX 日志中收到以下错误
[error] 9#9: *20 lead-api 无法解析(2:服务器故障),客户端:10.2.26.0,服务器:,请求:“GET /api/v1/lead/661DF757-722B- 41BB-81BD-C7FD398BBC88 HTTP/1.1"
如果我在 NGINX pod 中运行 nslookup,我可以使用相同的 dns 服务器解析主机:
$ kubectl exec nginx-1855584872-kdiwh -- nslookup lead-api
Server: 10.3.0.10
Address: 10.3.0.10#53
Name: lead-api.default.svc.cluster.local
Address: 10.3.0.167
我不知道这是否重要,但请注意错误的“服务器”部分为空。当我查看 dnsmasq 的 pod 日志时,我看不到任何相关内容。如果我将 NGINX 块更改为对 proxy_pass 进行硬编码,那么它可以很好地解决。但是,我还有其他需要动态代理名称的配置。我可以用这种方式对每个上游进行硬编码,但我想知道如何使 DNS 解析器工作。
location /api/v1/lead
proxy_pass http://lead-api:3000;
【问题讨论】:
您可能需要使用完整的限定名称,即lead-api。解析名称失败,因为您需要使用完全限定域名。也就是说,您应该使用:
lead-api.<namespace>.svc.cluster.local
不只是
lead-api
只使用主机名通常会起作用,因为在 kubernetes 中,resolv.conf
配置了搜索域,因此您通常不需要提供服务的 FQDN。例如:
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.3.240.10
options ndots:5
但是,当您告诉 nginx 使用自定义解析器时,必须指定 FQDN,因为它无法从这些域搜索规范中受益。
【讨论】:
这是我的问题。它适用于我们部署到默认 NS 的一个系统,但不适用于我们有自定义 NS 的另一个系统。要解决它,您实际上可以只放 lead-api.您需要使用Service
http://kubernetes.io/docs/user-guide/services/
kubernetes Service
代理流量到您的 Pods
(即您所谓的“服务”,即您的应用程序)
我猜你使用 Kubernetes 来部署和扩展你的应用程序 (Pods
),所以一旦你扩展并且你有多个 Pod 可以通信,就需要对它们进行负载平衡。这就是 Service
所做的。
Service
有自己的 IP 地址。只要 Service
存在,在上游引用此 Service
的 Nginx Pod
就可以正常工作。
Nginx(免费版)在无法解析上游时会死掉,但如果定义了Service
,它有自己的IP,它会被解析。
如果Service
后面的Pods
没有运行,Nginx 将看不到这一点,并会尝试转发流量但会返回 502(错误网关)
所以,只需定义Service
,然后使用适当的标签显示您的Pods
,以便Service
将它们拾取。你可以删除、缩放、替换那些Pods
而不影响Nginx Pod
。只要Service
后面至少有一个 Pod 运行,Nginx 将始终能够连接到您的 API。
【讨论】:
lead-api 是一项服务,我了解服务的工作原理。我也明白我可以将配置更改(并且已经拥有)硬编码“lead-api”。我知道如果我先启动 Lead-api 服务,上游将正常工作。我有其他需要相同解析器配置的动态 nginx 配置。这只是一个例子。我的问题不是“如何让它以其他方式工作”而是“为什么 DNS 解析器不起作用。” 您是否尝试过使用 FQDN? 投反对票,因为这没有抓住重点,服务根本不是这里的问题。 因此为什么在更多细节之后我写了另一个被接受的答案。以上是关于Kubernetes 中的 NGINX 无法解析 DNS的主要内容,如果未能解决你的问题,请参考以下文章
如果配置文件中的多个站点之一无法解析,nginx 将无法启动。 “在上游找不到主机”
Kubernetes基础_05_StatefulSet全解析(有状态的Pod)
Kubernetes基础_05_StatefulSet全解析(有状态的Pod)