【K8s 精选】定位 coredns 解析超时问题

本文结合域名请求慢的问题,从虚拟网络定位到域名解析,根据 coredns 添加域名后缀的机制,定位 coredns 解析慢的根因。

1.问题现象

背景:项目是微服务 + flink,其中 flink 采用 k8s session standalone 的部署模式。
问题:微服务通过 flink restful api 启动作业的平均时长超过 40s,导致客户端超时和作业失联。

#为了排除 flink 内部启动作业耗时因素,使用 /jobs/overview 测试微服务到 flink 的网络耗时
$time curl http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview
{"jobs":[{"jid":"0bf232afb7febbb8b070221833ddb99c","name":"TopSpeedWindowing","state":"RUNNING","start-time":1631687894914,"end-time":-1,"duration":701488855,"last-modification":1631687895895,"tasks":{"total":3,"created":0,"scheduled":0,"deploying":0,"running":3,"finished":0,"canceling":0,"canceled":0,"failed":0,"reconciling":0}}]}
real    0m10.528s
user    0m0.004s
sys     0m0.005s

2.根因定位

定位思路:理解 Service 【K8s 精选】Kubernetes Service 介绍在使用 service name 即域名的场景下,Client Pod3 首先拿着域名去 coredns 解析成 ClusterIP,接着去请求 ClusterIP,最后通过 Kube-Proxy 把请求转发到目标后端 Pod。

Kubernetes 服务发现架构.JPG

2.1 虚拟化网络分析

2.1.1 curl 命令详解

参考curl命令详解,例如

curl --header "Content-Type: application/json"  -X POST   --data '{"text":"germany"}'   https://labs.tib.eu/falcon/api?mode=short

2.1.2 curl 获取 http 各阶段的响应时间

参考通过curl得到http各阶段的响应时间

time_namelookup:DNS解析时间
time_connect:连接时间,从请求开始到 DNS 解析完毕所用时间。单纯的连接时间=time_connect - time_namelookup
time_appconnect:建立完成时间,例如 SSL/SSH 等建立连接或者完成三次握手的时间。
time_redirect:重定向时间,包括最后一次传输前的几次重定向的 DNS 解析、连接、预传输、传输时间。
time_pretransfer: 从开始到准备传输的时间。
time_starttransfer:开始传输时间。在 client 发出请求后,服务端返回数据的第一个字节所用的时间。

进入业务容器,编辑完获取数据的格式后,执行 curl 命令。

/dev/null 表示空设备,即丢弃一切写入的数据,但显示写入操作成功。

$vim curl-format.txt

time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_redirect: %{time_redirect}\n
time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
$kubectl get svc |grep flink
flink-jobmanager                          ClusterIP   10.96.0.123   <none>        8123/TCP,8124/TCP,8091/TCP   4d22h
# 首先使用 ClusterIP 测试接口调用时长
$curl -w "@curl-format.txt" -o /dev/null -l "http://10.96.0.123:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0  81865      0 --:--:-- --:--:-- --:--:-- 94285
time_namelookup: 0.004
time_connect: 0.005
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.005
time_starttransfer: 0.008
----------
time_total: 0.008

# 然后使用 service name 即域名测试接口调用时长
$curl -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0     62      0  0:00:10  0:00:10 --:--:--   164
time_melookup: 10.516
time_connect: 10.517
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 10.517
time_starttransfer: 10.520
----------
time_total: 10.520


对比 ClusterIP 和 service name 的接口调用时长,由 time_namelookup 可知 DNS 解析时间长。

2.2 域名解析分析

2.2.1 外部分析 - coredns 解析域名

$kubectl logs coredns-66509f5cf2-km1q4 -nkube-system
2021-09-23T01:54:04.590Z [ERROR] plugin/errors: 2 flink-jobmanager.default.svc.cluster.local.openstacklocal. A: read udp 10.244.0.18:32960->100.79.1.250:53: i/o timeout
2021-09-23T01:54:09.592Z [ERROR] plugin/errors: 2 flink-jobmanager.default.svc.cluster.local.openstacklocal. A: read udp 10.244.0.18:59978->100.79.1.250:53: i/o timeout
2021-09-23T01:56:00.609Z [ERROR] plugin/errors: 2 flink-jobmanager.default.svc.cluster.local.openstacklocal. AAAA: read udp 10.244.2.19:41797->100.79.1.250:53: i/o timeout
2021-09-23T01:56:02.610Z [ERROR] plugin/errors: 2 flink-jobmanager.default.svc.cluster.local.openstacklocal. AAAA: read udp 10.244.2.19:48375->100.79.1.250:53: i/o timeout

由 coredns 后台关键日志 A: read udp xxx->xxx: i/o timeout可知 IPV4 解析超时,AAAA: read udp xxx->xxx: i/o timeout 可知 IPV6解析也超时。

IPV4 和 IPV6 耗时对比
# IPV4 请求耗时
$curl -4 -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:03 --:--:--     0
time_melookup: 0.000
time_connect: 0.000
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.000
time_starttransfer: 0.000
----------
time_total: 3.510

# IPV6 请求耗时
$curl -6 -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0    146      0  0:00:04  0:00:04 --:--:--   146
time_melookup: 4.511
time_connect: 4.512
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 4.512
time_starttransfer: 4.515
----------
time_total: 4.515

结论:IPV6 解析比 IPV4 多耗时约 20%,说明 IPV6 对域名解析有一定的影响,建议 coredns 关闭 IPV6 解析。然而直接用 IPV4 解析也耗时 3s+,需要进一步对容器内部进行抓包分析。

建议:如果 IPV6 模式没有使用,可以关闭。

2.2.2 内部分析 - 容器内部解析域名

通过宿主机抓起 Pod 网络数据报

nsenter 可以进入 Pod 容器 net 命名空间,同时提供一个快速进入 Pod 容器 net 命名空间脚本,可以参考在容器环境使用 tcpdump 抓包

# 步骤1 获取容器的 pid
$ docker ps |grep flink-jobmanager-7b58565dc8-msgpp
1386ce6244ae        192.168.31.37:5000/flink                      "bash -cx /opt/flink/s…"   3 weeks ago         Up 3 weeks                              k8s_flink-jobmanager-7b58565dc8-msgpp_4b6d15d8-7b54-41fb-bf46-ffa91aa33963_0

$ docker inspect 1386ce6244ae| grep Pid
            "Pid": 63046,
            "PidMode": "",
            "PidsLimit": 0,

# 步骤2 根据 pid 执行命令
# 53 是 corends 域名解析端口 
$ nsenter -t 63046 -n
$ tcpdump 'src host 10.244.3.81 and src port 8091'

# 步骤3 打开新窗口,进入容器并执行上述的 curl 命令
$curl -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview"

下载 tcpdump 的抓包数据 xxx.pcap, 利用 wireshark 分析 tcpdump 报文,其结果如下:
flink-jobmanager.default.svc.cluster.local 域名解析成 ip 的时间约 10s
② 在域名解析的过程中,在 flink-jobmanager.default.svc.cluster.local 的基础上,其后缀依次添加default.svc.cluster.localsvc.cluster.localcluster.localopenstacklocal

查看业务容器中的配置 /etc/resolv.conf,发现上述的后缀恰好是search 内容。

$ cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options ndots:5 single-request-reopen

3 容器 /etc/resolv.conf 配置分析

容器 /etc/resolv.conf 配置如下:

nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options ndots:5 single-request-reopen

① nameserver

resolv.conf 文件的第一行是 nameserver,内容是 coredns 的 ClusterIP

$kubectl get svc -nkube-system |grep dns
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP   167d

② search

resolv.conf 文件的第一行是 search。当域名解析的时候,将域名依次添加后缀,例如:

flink-jobmanager.default.svc.cluster.local.default.svc.cluster.local
flink-jobmanager.default.svc.cluster.local.svc.cluster.local
flink-jobmanager.default.svc.cluster.local.cluster.local
flink-jobmanager.default.svc.cluster.local.openstacklocal

③ options

resolv.conf 文件的第一行是 options 其它项,常见配置是 ndots。ndots: 5 表示如果域名包含的 "." 少于5个,则先添加 search 后缀,再使用绝对域名;如果域名包含的 "." 大于等于5个,则先使用绝对域名,再添加 search 后缀

#样例1 域名a.b.c.d.e,则域名的顺序如下
a.b.c.d.e.default.svc.cluster.local
a.b.c.d.e.svc.cluster.local
a.b.c.d.e.cluster.local
a.b.c.d.e.openstacklocal
a.b.c.d.e

#样例2 域名a.b.c.d.e.f,则域名的顺序如下
a.b.c.d.e.f
a.b.c.d.e.f.default.svc.cluster.local
a.b.c.d.e.f.svc.cluster.local
a.b.c.d.e.f.cluster.local
a.b.c.d.e.f.openstacklocal

结合 flink-jobmanager.default.svc.cluster.local 域名解析慢的问题,由于该域名包含 "." 等于 4,即少于5,所以会首先依次添加后缀default.svc.cluster.local、svc.cluster.local、cluster.local openstacklocal。因此,解决方案有 ①flink-jobmanager.default.svc.cluster.local 修改为 flink-jobmanager;②ndots: 5 修改为 ndots: 4

4 解决方案

4.1 使用简洁域名

将访问的域名从flink-jobmanager.default.svc.cluster.local 修改为 flink-jobmanager,效果如下:

curl -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0  82038      0 --:--:-- --:--:-- --:--:-- 94285
time_melookup: 0.004
time_connect: 0.005
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.005
time_starttransfer: 0.008
----------
time_total: 0.008

4.2 resolv.conf 配置更改

将 /etc/resolv.conf 的 options 配置 ndots: 5 修改为 ndots: 4,或者修改 deployment 的 yaml 配置,效果如下:

     # 修改 deployment 的 yaml 配置
     # spec.spec.dnsConfig.options[].ndots
      dnsConfig:
        options:
          - name: ndots
            value: 4
          - name: single-request-reopen
curl -w "@curl-format.txt" -o /dev/null -l "http://flink-jobmanager.default.svc.cluster.local:8091/jobs/overview"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   660  100   660    0     0  82038      0 --:--:-- --:--:-- --:--:-- 94285
time_melookup: 0.005
time_connect: 0.006
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.005
time_starttransfer: 0.008
----------
time_total: 0.008
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容