1、k8s中,ip是变化的,两个容器可以通过dns访问,这样大家可以在代码里写死对方的url了。
2、如果微服务是go的程序,一般用的就是go内置的http库,go内置dns客户端。dns客户端会缓存域名和ip的关系,不用每次都查询dns。
3、容器中的/etc/resolv.conf映射的是主机中的这个路径,文件内容如下
bash
cat /paasdata/docker/containers/104b4a2351a0426fad29c1ed26a8582a27a34b7b1876b9b7ca312eaca52918b4/resolv.conf
nameserver 123.123.0.5
search idos.service.openpalette service.openpalette idos.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
---
- nameserver 123.123.0.5 含义:指定了容器进行 DNS 查询时使用的上游 DNS 服务器地址。
- search idos.service.openpalette service.openpalette idos.svc.cluster.local svc.cluster.local cluster.local
含义:定义了域名搜索后缀列表。当应用程序请求解析一个非完全限定域名(即不带完整后缀的短名称,如 my-service)时,DNS 解析器会依次尝试将这些后缀追加到短名称后面,直到解析成功或列表耗尽。
- options ndots:5 含义:设置判断域名是否为"完全限定域名"的阈值。
规则:如果待解析的域名中包含的点号(.)数量 少于 ndots 的值(这里是 5),DNS 解析器会认为这是一个短名称,并优先使用上面的 search 列表进行补全尝试。
如果点号数量 大于或等于 5,解析器会直接将其视为完全限定域名,首先尝试直接解析,如果失败才可能回退到 search 列表(取决于具体实现和 search 配置)。
4、主机中的/etc/resolv.conf是这样的
bash
$ cat /etc/resolv.conf
search svc.cluster.local cluster.local service.openpalette
options timeout:1
options attempts:1
nameserver 193.101.0.11
验证一下两个dns都可以使用 busybox -> CoreDNS (123.123.0.5) -> 直接解析并返回 123.123.0.1
$ ./busybox nslookup kubernetes.default.svc.cluster.local 123.123.0.5
Server: 123.123.0.5
Address: 123.123.0.5:53
Non-authoritative answer:
Name: kubernetes.default.svc.cluster.local
Address: 123.123.0.1
Non-authoritative answer:
验证一下两个dns都可以使用 busybox -> DNS (193.101.0.11) -> 转发请求 -> CoreDNS (123.123.0.5) -> 返回 123.123.0.1
$ ./busybox nslookup kubernetes.default.svc.cluster.local
Server: 193.101.0.11
Address: 193.101.0.11:53
Non-authoritative answer:
Name: kubernetes.default.svc.cluster.local
Address: 123.123.0.1
Non-authoritative answer:
bash
在容器内再验证一下
/home/ipo $ busybox nslookup kubernetes.default.svc.cluster.local
Server: 123.123.0.5
Address: 123.123.0.5:53
Name: kubernetes.default.svc.cluster.local
Address: 123.123.0.1
/home/ipo $ busybox nslookup backup-outter.idos.svc.cluster.local
Server: 123.123.0.5
Address: 123.123.0.5:53
Name: backup-outter.idos.svc.cluster.local
Address: 123.123.98.166
试试其它命令,也可看到域名被转换成什么IP地址了
/home/ipo $ busybox ping backup-outter.idos.svc.cluster.local
PING backup-outter.idos.svc.cluster.local (123.123.98.166): 56 data bytes
ping: permission denied (are you root?)
/home/ipo $ busybox wget -O - http://backup-outter.idos.svc:12311/api/backup-outter/v1/backupSettings
Connecting to backup-outter.idos.svc:12311 (123.123.98.166:12311)
writing to stdout
{"customFtp":null}
5、最后,再说明一下这个IP,不是容器的IP(192.169.0.196),而是svc的IP(123.123.98.166)
所以,k8s这个dns机制,是依赖svc机制的。我们通过dns访问的是svc,k8s的svc再把消息转发到容器中
如果没有svc,就需要其它办法把容器的IP注册到DNS服务器中。
bash
$ kubectl get svc backup-outter -n idos
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
backup-outter ClusterIP 123.123.98.166 <none> 12311/TCP 5d4h
$ kubectl describe svc backup-outter -n idos
Name: backup-outter
Namespace: idos
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 123.123.98.166
IPs: 123.123.98.166
Port: backupoutterport 12311/TCP
TargetPort: 12311/TCP
Endpoints: 192.169.0.196:12311
$ docker exec 35da55069e32 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if214: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
link/ether 7e:46:bc:8a:9d:ab brd ff:ff:ff:ff:ff:ff
inet 192.169.0.196/24 brd 192.169.0.255 scope global eth0
valid_lft forever preferred_lft forever