[英]DNS does not resolve with NGINX in Kubernetes
I have a Kube.netes cluster that I setup with kube-aws .我有一个使用kube-aws设置的 Kube.netes 集群。 I'm trying to run a custom NGINX configuration which uses DNS resolutions to proxy_pass.我正在尝试运行自定义 NGINX 配置,该配置使用 DNS 分辨率到 proxy_pass。 Here is the NGINX block of code这是 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 comes from the cluster IP of the DNS service found in Kube.netes. 10.3.0.10 来自 Kube.netes 中 DNS 服务的集群 IP。 I've also tried 127.0.0.11 which is what we use in the docker-compose/docker environments.我还尝试了 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
This configuration works well on three different environments which use docker-compose. However I get the following error in the NGINX logs of the Kube.netes cluster此配置适用于使用 docker-compose 的三个不同环境。但是,我在 Kube.netes 集群的 NGINX 日志中收到以下错误
[error] 9#9: *20 lead-api could not be resolved (2: Server failure), client: 10.2.26.0, server: , request: "GET /api/v1/lead/661DF757-722B-41BB-81BD-C7FD398BBC88 HTTP/1.1" [错误] 9#9:*20 lead-api 无法解析(2:服务器故障),客户端:10.2.26.0,服务器:,请求:“GET /api/v1/lead/661DF757-722B-41BB-81BD -C7FD398BBC88 HTTP/1.1"
If I run nslookup within the NGINX pod I can resolve the host with the same dns server:如果我在 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
I don't know if it matters or not, but notice the "server" part of the error is empty.我不知道这是否重要,但请注意错误的“服务器”部分是空的。 When I look at the pod logs for dnsmasq I don't see anything relevant.当我查看 dnsmasq 的 pod 日志时,我没有看到任何相关内容。 If I change the NGINX block to hardcode the proxy_pass then it resolves fine.如果我将 NGINX 块更改为对 proxy_pass 进行硬编码,那么它就可以正常解析。 However, I have other configurations that require dynamic proxy names.但是,我有其他需要动态代理名称的配置。 I could hard code every upstream this way, but I want to know how to make the DNS resolver work.我可以通过这种方式对每个上游进行硬编码,但我想知道如何使 DNS 解析器工作。
location /api/v1/lead {
proxy_pass http://lead-api:3000;
}
Resolving the name fails because you need to use the Full Qualified Domain name. 解析名称失败,因为您需要使用完全限定域名。 That is, you should use: 也就是说,你应该使用:
lead-api.<namespace>.svc.cluster.local
not just 不只是
lead-api
Using just the hostname will usually work because in kubernetes the resolv.conf
is configured with search domains so that you don't usually need to provide a service's FQDN. 仅使用主机名通常是有效的,因为在kubernetes中, resolv.conf
配置了搜索域,因此您通常不需要提供服务的FQDN。 eg: 例如:
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.3.240.10
options ndots:5
However, specifying the FQDN is necessary when you tell nginx to use a custom resolver because it does not get the benefit of these domain search specs. 但是,当您告诉nginx使用自定义解析程序时,指定FQDN是必要的,因为它不会从这些域搜索规范中获益。
One other option would be to specify kubedns as the resolver.另一种选择是将 kubedns 指定为解析器。 On many systems, this would look something like the following:在许多系统上,这看起来像下面这样:
resolver kube-dns.kube-system.svc.cluster.local valid=10s;
You need to use a Service
您需要使用Service
http://kubernetes.io/docs/user-guide/services/ http://kubernetes.io/docs/user-guide/services/
A kubernetes Service
proxies traffic to your Pods
(ie what you call 'service', which is your application) 一个kubernetes Service
代理流量到您的Pods
(即你所说的“服务”,这是你的应用程序)
I guess you use Kubernetes for the ability to deploy and scale your applications ( Pods
) so traffic will need to be load balanced to them once you scale and you have multiple Pods to talk to. 我猜你使用Kubernetes的部署和扩展应用程序的能力( Pods
),所以一旦你达到你有多个荚谈交通将需要负载均衡的他们。 This is what a Service
does. 这就是Service
作用。
A Service
has its own IP address. Service
有自己的IP地址。 As long as the Service
exists, a Nginx Pod
referencing this Service
in upstream will work fine. 只要Service
存在,在上游引用此Service
的Nginx Pod
就可以正常工作。
Nginx (free version) dies when it can't resolve the upstream, but if the Service
is defined, it has its own IP and it gets resolved. Nginx(免费版)在无法解析上游时死亡,但如果定义了Service
,它就有自己的IP并得到解决。
If the Pods
behind the Service
are not running, Nginx will not see that, and will try to forward the traffic but will return a 502 (bad gateway) 如果Service
后面的Pods
没有运行,Nginx将不会看到,并将尝试转发流量,但将返回502(坏网关)
So, just defined the Service
and then bring up your Pods
with the proper label so the Service
will pick them up. 因此,只需定义Service
,然后使用正确的标签调出您的Pods
,以便Service
接收它们。 You can delete, scale, replace those Pods
without affecting the Nginx Pod
. 您可以删除,规模化,取代那些Pods
而不影响Nginx的Pod
。 As long as there is at least one Pod running behind the Service
, Nginx will always be able to connect to your API. 只要Service
后面至少有一个Pod运行,Nginx将始终能够连接到您的API。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.