如果 nginx 的 proxy_pass 指令带有变量名的话: server { server_name ~^(/w+)/.example/.com$; location / { proxy_pass http://svc-$1; }} 不配置 resolver 是不能使用的(虽然可以成功加载配置): $ curl --resolve 'a.example.com:80:127.0.0.1' a.example.com<html><head><title>502 Bad Gateway</title></head><body bgcolor="white"><center><h1>502 Bad Gateway</h1></center><hr><center>nginx/1.14.2</center></body></html> nginx 的错误日志: [error] 615#615: *1 no resolver defined to resolve svc-a 查看当前的 resolve 配置: $ cat /etc/resolv.confsearch default.svc.cluster.local svc.cluster.local cluster.localnameserver 10.152.183.10options ndots:5 尝试把它添加到 nginx 的配置里面: server { server_name ~^(/w+)/.example/.com$; location / { resolver 10.152.183.10; proxy_pass http://svc-$1; }} 结果是仍然不能可用: [error] 3817#3817: *10 svc-a could not be resolved (3: Host not found) nginx 要求配置 resolver 指令,那么可以猜测,它没有使用系统的 resolve.conf 文件,也就是:不走系统那一套来解析域名。 所以现在的差异就在于下面 search 这一行了: search default.svc.cluster.local svc.cluster.local cluster.local search 指令的用途:当名字无法解析时,加上这些后缀再尝试解析。 根据 K8s 的 Service 的 DNS 文章所言可以推测: - cluster.local 是 K8s 的 cluster_domain
- default.svc.cluster.local 是名字空间的域名( default 是我的名字空间)
而服务的域名则是:<服务>.<名字空间域名>。 所以当我 curl svc-a 的时候,实际上返回的是 svc-a.default.svc.cluster.local 的结果: $ host svc-asvc-a.default.svc.cluster.local has address 10.152.183.160$ host svc-a.defaultsvc-a.default.svc.cluster.local has address 10.152.183.160$ host svc-a.default.svcsvc-a.default.svc.cluster.local has address 10.152.183.160$ host svc-a.default.svc.cluster.localsvc-a.default.svc.cluster.local has address 10.152.183.160 看出来了吗?以上命令省略的恰好是 search 指令列出来的部分。 但是,nginx 的 resolver 不支持 search,所以应该写完整的域名。 server { server_name ~^(/w+)/.example/.com$; location / { resolver 10.152.183.10; proxy_pass http://svc-$1.default.svc.cluster.local; }} 以上这样配置就没有问题了。 但是,hardcode 了一个 resolver,不好,得去掉,用服务名的方式找到 K8s DNS 的域名。 我的 K8s 的域名是 kube-dns 服务提供的,名字空间是 kube-system,所以完整的 resolver 是: kube-dns.kube-system.svc.cluster.local。 $ host kube-dns.kube-system.svc.cluster.localkube-dns.kube-system.svc.cluster.local has address 10.152.183.10 最终的 nginx 配置: server { server_name ~^(/w+)/.example/.com$; location / { resolver kube-dns.kube-system.svc.cluster.local; proxy_pass http://svc-$1.default.svc.cluster.local; }} 其中的变量,应该按你的场景来修改: kube-dns 是我的集群使用的 DNS 服务 kube-system 是我的 DNS 服务所在的名字空间 default 是我的名字空间 cluster.local 是集群域名(cluster_domain) 有至少两种方式可以拿到这个集群域名: 由于集群域名不是变化的量,所以每次从文件里面读取并无必要(第一种方式),所以推荐第二种。
总结 下载地址: 三款Docker图形化工具优缺点对比 Nginx设置成服务并开机自动启动的配置 |