一次 salt-run 很久才返回的排查
由来
所有 salt-run 命令耗时都很久
1 | $ time salt-run jobs.active |
排查
salt-master 是容器里运行的,改容器没 ptrace 权限,怕重启容器后故障无了。就容器内执行卡住后看下宿主机进程 salt-run 是唯一的,宿主机上有 strace 命令,strace 看看:
1 | strace -p `ps -ef | grep -E 'salt-ru[n]' | awk '{print $2}' ` |
左边窗口执行,右边赶紧 strace,发现有输出后卡主,赶紧按回车分开,最后往上翻找空行附近就是卡住的信息。从上面看就是 glibc 的 DNS 解析行为:
- 先看
/etc/nsswitch.conf
内的hosts
行,看 hosts 和 dns 的优先级 connect(11, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.xx.xx.1")}, 16) = 0
发起了 DNS 解析请求的连接信息sendto(11, "e\366\1\0\0\1\0\0\0\0\0\0\7kubexxx\0\0\34\0\1", 25, MSG_NOSIGNAL, NULL, 0) = 25
DNS 请求
然后再执行下,另一个窗口看了下链接确实存在 DNS 解析行为:
1 | ss -anuop | grep :53 |
然后抓包看了下请求:
1 | 往右侧翻 |
发现是请求 hostname的 IPv6 DNS 解析记录,然后加了下 hosts 就好了。
1 | echo "::1 $HOSTNAME" >> /etc/hosts |
解决
搜了下关键字 salt-run dns ipv6
看看有没有其他人遇到,结果找到类似问题:
- https://github.com/saltstack/salt/issues/40912
- https://github.com/saltstack/salt/issues/32719#issuecomment-238114720
但是回复都是老版本遇见多,我这边版本都很新了:
1 | salt --versions-report |
这种是 glibc 的行为,salt 会解析 hostname,业务临近封库,改这个 docker 镜像内启动脚本也来不及了,就先在代码层面解决了,搜了下 python socket 库并没有那种纯看 hosts 条目的库,就手动写了如下逻辑:
1 | import fcntl |