详细聊聊K8s容器内nginx带变量的域名解析
如果 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.com502 Bad Gateway 502 Bad Gateway
nginx/1.14.2
nginx 的错误日志:
[error] 615#615: *1 no resolver defined to resolve svc-a
查看当前的 resolve 配置:
$ cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.152.183.10 options 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-a svc-a.default.svc.cluster.local has address 10.152.183.160 $ host svc-a.default svc-a.default.svc.cluster.local has address 10.152.183.160 $ host svc-a.default.svc svc-a.default.svc.cluster.local has address 10.152.183.160 $ host svc-a.default.svc.cluster.local svc-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.local kube-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)
有至少两种方式可以拿到这个集群域名:
/etc/resolv.conf 文件的 search 指令。
这是 kubelet 的一个启动参数,可以找到你的集群启动参数来获取到。 我这里用的是 microk8s 搭建的测试集群,其中就有一个集群域名参数的值。
$ ps aux|grep kubelet root 728595 16.0 11.1 3549776 872556 ? Ssl 02:25 9:44 /snap/microk8s/2870/kubelite --scheduler-args-file=/var/snap/microk8s/2870/args/kube-scheduler --controller-manager-args-file=/var/snap/microk8s/2870/args/kube-controller-manager --proxy-args-file=/var/snap/microk8s/2870/args/kube-proxy --kubelet-args-file=/var/snap/microk8s/2870/args/kubelet --apiserver-args-file=/var/snap/microk8s/2870/args/kube-apiserver --kubeconfig-file=/var/snap/microk8s/2870/credentials/client.config --start-control-plane=true $ cat /var/snap/microk8s/2870/args/kubelet ... --cluster-domain=cluster.local ...
由于集群域名不是变化的量,所以每次从文件里面读取并无必要(第一种方式),所以推荐第二种。
总结
栏 目:其它服务器
本文地址:https://zz.feitang.co/server/35092.html
您可能感兴趣的文章
- 01-12Docker部署rabbitmq遇到的两个问题
- 01-12最新虚拟机VMware 14安装教程
- 01-12使用docker compose安装harbor私有仓库的详细教程
- 01-12Windows下Docker安装各种软件的详细过程
- 01-12seata docker 高可用部署的详细介绍
- 01-12浅谈Tomcat多层容器的设计
- 01-12Gogs+Jenkins+Docker 自动化部署.NetCore的方法步骤
- 01-12解决vscode docker插件docker.socket权限问题
- 01-12Docker中运行PostgreSQL并推荐几款连接工具
- 01-12Docker核心原理之 Cgroup详解


阅读排行
推荐教程
- 12-07一文教你怎么选择Tomcat对应的JDK版本
- 12-23linux中ftp无法访问怎么办
- 12-11docker存储目录迁移示例教程
- 12-10docker start启动容器后仍然exit状态的解决
- 12-10Linux下如何安装Logstash
- 12-05Docker安装Jenkins全过程
- 01-05Shell脚本去重的几种方法实例
- 12-22kvm虚拟机配置NAT端口转发的实现方法
- 12-19Zabbix SAML SSO 登录绕过漏洞的操作流程
- 12-15Docker-Compose搭建Spark集群的实现方法




