秋栈博客

七月

记录一次由阿里云网段冲突导致的pod中DNS解析问题

2023-03-29

记录一次由阿里云网段冲突导致的pod中DNS解析问题

背景

在阿里云购买了杭州地区的ECS来自建了一套单节点kubernetes集群,用来安装Robusts测试。 但是在实际跑的过程中Robusta平台UI那边始终获取不到集群的链接,遂查看robusta-runner的日志: 看样子是解析不到他们的api地址,看到他们的技术总监在线,拉来问了问: 他们说就是DNS的问题。遂开始排查。

排障过程

先进入pod测试: kubectl exec -it robusta-runner-86cbcb749b-kjwhb -n robusta -- bash
root@robusta-runner-86cbcb749b-kjwhb:/app# nslookup baidu.com
Server:		10.96.0.10
Address:	10.96.0.10#53

** server can't find baidu.com: SERVFAIL
一开始我以为是ECS的DNS出问题,在宿主机直接去ping他们的API地址发现是正常的。 难不成是coredns的问题,遂开始排查pod内的DNS地址和coredns的是否一致:
$ kubectl exec robusta-runner-77fd9d5557-ck2b4 -n robusta cat /etc/resolv.conf
nameserver 10.96.0.10
search robusta.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

$ kubectl get svc -n kube-system kube-dns
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10           53/UDP,53/TCP,9153/TCP   81m
# 看是否存在 endpoint:
$ kubectl -n kube-system describe svc kube-dns | grep -i endpoints
Endpoints:         10.29.47.67:53,10.29.47.68:53
Endpoints:         10.29.47.67:53,10.29.47.68:53
Endpoints:         10.29.47.67:9153,10.29.47.68:9153

测试端口

使用telnet测试53端口是否正常
$ telnet 10.96.0.10 53
Trying 10.96.0.10...
Connected to 10.96.0.10.
Escape character is '^]'.

抓包测试

使用 tcpdump 工具来捕获网络接口上所有入站和出站的 DNS 流量,并将其写入一个名为 dns.pcap 的文件中。-nn 表示禁用DNS解析,直接显示IP地址和端口号。-w保存到文件。 -tttt 表示以可读格式输出时间戳,-i any 表示对所有网络接口进行监视。
tcpdump -i any port 53 -w dns.pcap
tcpdump -i any port 53 -nn -tttt
果然,一样的。查看robusta应用的DNS策略也是没毛病的。
$ kubectl get deployments.apps -n robusta robusta-runner -o yaml | grep dns
      dnsPolicy: ClusterFirst
configmap中的forward也正确。
$ kubectl get cm -n kube-system coredns -o yaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-03-28T11:49:26Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "242"
  uid: bfead4fb-e99d-4173-8289-30ce96aa39cd
到这里那就知道不是组件的问题了,还是本机的问题。

排查本机问题

查看本地DNS与集群网段
$ cat /etc/resolv.conf
options timeout:2 attempts:3 rotate single-request-reopen
; generated by /usr/sbin/dhclient-script
nameserver 100.100.2.136
nameserver 100.100.2.138

$ kubectl cluster-info dump | grep -e cluster-cidr
                            "--cluster-cidr=100.64.0.0/10",
通过询问阿里云得知CentOS 7公共镜像中,DNS的etc/resolv.conf文件是通过执行/usr/sbin/dhclient-script脚本生成的。在重启实例后dhclient发起请求获取地址等信息时会重置掉原有的/etc/resolv.conf配置文件。
root@ubuntu:/# nslookup baidu.com
Server:		10.96.0.10
Address:	10.96.0.10#53

Non-authoritative answer:
Name:	baidu.com
Address: 110.242.68.66
Name:	baidu.com
Address: 39.156.66.10
 

解决方案

方案1、将 /etc/resolv.conf 文件设置为不可修改(immutable)状态,避免因为重启系统配置还原。
# 加锁
chattr +i /etc/resolv.conf
# 解锁
chattr -i /etc/resolv.conf
方案2、将DNS添加到网卡中。在默认情况下,系统会根据网络接口配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0 中的配置来自动更新 /etc/resolv.conf 文件中的 DNS 服务器配置。当系统启动或者网络接口状态发生变化时,会执行脚本 /sbin/dhclient-script 来更新 /etc/resolv.conf 文件中的 DNS 配置。
echo "DNS1=223.5.5.5" >> /etc/sysconfig/network-scripts/ifcfg-eth0
echo "DNS1=223.6.6.6" >> /etc/sysconfig/network-scripts/ifcfg-eth0
systemctl restart network
方案3(推荐)、更换pod网段. 避免和阿里云的网段冲突,又能正常解析阿里云内网域名。 sealos为例:sealos init --podcidr 10.30.0.0/12

再次测试

$ kubectl rollout restart deployment coredns -n kube-system
$ kubectl rollout restart deployment robusta-runner -n robusta

再次查看日志,解决。

  • 0