dns docker

在CI中进行不稳定的测试是一场噩梦。 您无法确定您的新代码是否损坏了某些东西,或者仅仅是那些测试再次变得不稳定。 因此,每当我们看到开源项目Adapt的CI出现奇怪的随机故障时,我们都将尽快找出问题的根源。 这是关于我们如何发现(偶然)用流量泛滥DNS服务器以及如何在Docker中使用DNS缓存来解决问题的故事。

背景

AdaptJS是我从事的一个开源项目,可以将应用程序部署到多种云和技术中,因此,使用Docker,Kubernetes,AWS,Google Cloud和其他类似技术进行了大量的系统测试和端到端测试。

我们在测试中大量使用了Docker,因此最终创建了许多短期容器,这些容器会启动,完成一些工作,例如构建或安装应用程序,然后被删除。 随着我们添加越来越多的这些测试,我们开始看到以前稳定的系统测试在CI中随机失败。

症状:测试超时

我们看到的第一个症状是测试超时。 我们的许多端到端测试的超时时间都很短,因此我们可以检测到新代码是否突然使最终用户花费了更长的时间。 但是现在,通常需要半秒的测试有时会花费5.5秒。

额外的5秒是一个很好的线索-听起来像-5秒可能是某种超时。 怀着这种直觉,我们回顾了所有看似随机的测试失败并找到了共同的线索:它们都是引发网络请求的测试。 我们还注意到一些测试花费了更长的时间才失败……总是以5秒为增量。

这里没有太多的网络协议可以使用,因此快速搜索可以为我们指明正确的方向。 在Linux上,DNS服务器查询的默认超时仅为5秒 。

为了了解DNS的运行情况,我们找到了在Linux上调试网络问题的最重要的工具: tcpdump 。 (或者,如果您更喜欢GUI版本, wireshark也很棒。)我们在主机系统(Amazon Workspaces Linux实例)上运行tcpdump并使用过滤器查看DNS流量:

$  tcpdump -n -i eth1 port 53
11:35:59.474735 IP 172.16.0.131.54264 > 172.16.0.119.domain: 64859+ AAAA? registry-1.docker.io. (38)
11:35:59.474854 IP 172.16.0.131.49631 > 172.16.0.119.domain: 43524+ A? registry-1.docker.io. (38)
11:35:59.476871 IP 172.16.0.119.domain > 172.16.0.131.49631: 43524 8/0/1 A 34.197.189.129, A 34.199.40.84, A 34.199.77.19, A 34.201.196.144, A 34.228.211.243, A 34.232.31.24, A 52.2.186.244, A 52.55.198.220 (177)
11:35:59.476957 IP 172.16.0.119.domain > 172.16.0.131.54264: 64859 0/1/1 (133)

我们注意到的第一件事是,我们向VPC的AWS默认DNS服务器生成了大量DNS查询。 看起来由于各种原因,所有那些短命的容器在启动时都倾向于进行一堆DNS查找。 接下来,我们注意到其中一些DNS查询没有得到答复。

共享DNS服务器实施速率限制是很常见的,这样一个用户就不会降低其他用户的性能。 在这里,我们怀疑AWS DNS服务器正是在这样做。 我们无法找到一种方法来确认我们是否确实达到了AWS速率限制,但是对于我们来说,不要对我们的DNS服务器进行DoS似乎是明智的。

解决方案:使用dnsmasq的Docker DNS缓存

为了隔离主机中的DNS流量,我们需要一个本地DNS服务器充当缓存。 dnsmasq是此类缓存的绝佳选择。 它可靠,使用广泛且设置超级简单。 并且由于我们所有的测试都在Docker容器中运行,因此也可以在Docker中运行DNS服务器。

基本想法非常简单:在Docker主机网络上运行dnsmasq容器作为DNS缓存,然后使用--dns选项指向缓存容器的IP地址运行测试容器。

这是启动DNS缓存容器的dns_cache脚本:

#!/usr/bin/env bash: " ${IMAGE:=andyshinn/dnsmasq:2.76} "
: " ${NAME:=dnsmasq} "
: " ${ADAPT_DNS_IP_FILE:=/tmp/adapt_dns_ip} "# Get IP address for an interface, as visible from inside a container
# connected to the host network
interfaceIP () {# Run a container and get ifconfig output from inside# We need the ifconfig that will be visible from inside the dnsmaq# containerdocker run --rm --net=host busybox ifconfig " $1 " 2>/dev/null | \awk '/inet /{print(gensub(/^.*inet (addr:)?([0-9.]+)\s.*$/, "\\2", 1))}'
}if docker inspect -- type container " ${NAME} " >& /dev/null ; thenif [ -f " ${ADAPT_DNS_IP_FILE} " ]; then# dnsmasq is already startedcat " ${ADAPT_DNS_IP_FILE} "exit 0elseecho DNS cache container running but file ${ADAPT_DNS_IP_FILE} does not exist. >&2exit 1fi
fi# We only support attaching to the default (host) bridge named "bridge".
DOCKER_HOST_NETWORK=bridge# Confirm that "bridge" is the default bridge
IS_DEFAULT=$(docker network inspect " ${DOCKER_HOST_NETWORK} " --format '{{(index .Options "com.docker.network.bridge.default_bridge")}}' )
if [ " ${IS_DEFAULT} " != "true" ]; thenecho Cannot start DNS cache. The Docker network named \ " ${DOCKER_HOST_NETWORK} \" does not exist or is not the default bridge. >&2exit 1
fi# Get the Linux interface name for the bridge, typically " docker0 "
INTF_NAME= $(docker network inspect "${DOCKER_HOST_NETWORK}" --format '{{(index .Options "com.docker.network.bridge.name") }}')
if [ -z " ${INTF_NAME} " ]; thenecho Cannot start DNS cache. Unable to determine default bridge interface name. >&2exit 1
fi# Get the IP address of the bridge interface. This is the address that
# dnsmasq will listen on and other containers will send DNS requests to.
IP_ADDR= $(interfaceIP "${INTF_NAME}")
if [ -z " ${IP_ADDR} " ]; thenecho Cannot start DNS cache. Docker bridge interface ${INTF_NAME} does not exist. >&2exit 1
fi# Run the dnsmasq container. The hosts's /etc/resolv.conf configuration will
# be used by dnsmasq to resolve requests.
docker run --rm -d --cap-add=NET_ADMIN --name " ${NAME} " --net=host -v/etc/resolv.conf:/etc/resolv.conf " ${IMAGE} " --bind-interfaces --listen-address=" ${IP_ADDR} " --log-facility=- > /dev/null
if [ $? -ne 0 ]; thenecho Cannot start DNS cache. Docker run failed.exit 1
fi# Remember what IP address to use as DNS server, then output it.
echo ${IP_ADDR} > " ${ADAPT_DNS_IP_FILE} "
echo ${IP_ADDR}

除了启动容器(如果尚未运行)之外,脚本还会输出缓存容器的IP地址。 我们将在我们启动的任何其他容器的命令行上使用它。 该脚本还确保dnsmasq仅侦听Docker内部(在Docker桥接口上)的DNS请求,因此需要做一些额外的工作来确定要侦听的IP地址。

这是一个如何启动DNS缓存,记住变量DNS_IP的IP地址,然后运行另一个将使用该缓存的容器的DNS_IP

$  DNS_IP=$(dns_cache)
$  docker run --dns ${DNS_IP} --rm busybox ping -c1 adaptjs.org

验证缓存工作正常

在我们的测试中开始使用缓存后,主机系统发送到AWS DNS服务器的DNS查询数量就减少了。 我们还通过检查dnsmasq统计信息来确认缓存正常运行。 将SIGUSR1发送到dnsmasq会使其将统计信息打印到其日志中 :

$  docker kill -s USR1 dnsmasq
$  docker logs dnsmasq
dnsmasq[1]: cache size 150, 1085/4664 cache insertions re-used unexpired cache entries.
dnsmasq[1]: queries forwarded 1712, queries answered locally 3940
dnsmasq[1]: queries for authoritative zones 0
dnsmasq[1]: server 172.16.0.119#53: queries sent 1172, retried or failed 0
dnsmasq[1]: server 172.16.1.65#53: queries sent 252, retried or failed 0
dnsmasq[1]: server 172.16.0.2#53: queries sent 608, retried or failed 0

最重要的是,我们看到系统测试超时显着减少,并且CI运行稳定。

这个问题使我们花了一段时间才找到答案。 但是保持CI健康非常重要。 如果您有太多的零星测试失败,则开发人员倾向于忽略CI结果,并推送可能损坏的代码。

因此,尽管查找这些故障很费时,但考虑到修复的简便性,绝对值得投资。

最初发布在 Adapt博客上

翻译自: https://hackernoon.com/fixing-dns-timeouts-in-docker-hbr32ej

dns docker

dns docker_使用DNS缓存修复Docker中的DNS超时[教程]相关推荐

  1. linux中DNS服务器查看域名,如何在Linux中查看DNS服务器设置

    1. 前言 DNS(域名系统)是非常重要的基础网络服务,如邮件服务器.互联网浏览和流媒体服务,如Netflix和Spotify等网络服务都依赖于它. 它在一个叫做DNS服务器的特殊计算机上工作-它保存 ...

  2. cmd 新增dns_win10在cmd中修改dns方法教程

    电脑中有些操作需要更改dns地址才可以进行,有时候为了获得更加速度的上网体验或者是想体验一些防劫持智能dns的话,就需要去更改dns地址.那么,Win10在cmd中修改dns对于此类问题,今天小编就详 ...

  3. linux mint 修改dns,如何在Ubuntu和LinuxMint中刷新DNS缓存

    本篇文章给大家介绍的内容是关于如何在Ubuntu和LinuxMint中刷新DNS缓存,下面我们来看具体的内容. 域名系统(DNS)是互联网的主干网之一.你无法想象在全球数百万用户的公共网络上运行网站. ...

  4. Linux在shell终端中清空DNS缓存,刷新DNS的方法(ubuntu,debian)

    前言 在Linux系统里查询DNS使用如下命令 dig baidu.com @114.114.114.114 或者使用系统默认的DNS服务器查询 nslookup baidu.com 下文中的方法不一 ...

  5. linux mint 修改dns,如何在Ubuntu和LinuxMint中刷新DNS缓存-linux运维

    本篇文章给大家介绍的内容是关于如何在Ubuntu和LinuxMint中刷新DNS缓存,下面我们来看具体的内容. 域名系统(DNS)是互联网的主干网之一.你无法想象在全球数百万用户的公共网络上运行网站. ...

  6. 通过负载均衡器+域名实现容灾切换-(8)基于DNS解析的GSLB在BS架构中应用实践(转)(1)...

    ================================================================================================= 摘自 ...

  7. 服务器事件刷新消息,Windows Server 2003 中的 DNS 事件消息 1616 到 6702

    更多信息 一般 DNS 事件消息 1616 MessageId=1616 Severity=Error SymbolicName=DNS_EVENT_TEXT_STRING_TOO_LONG DNS ...

  8. 为何解析浏览器地址参数会为null_request 包中出现 DNS 解析超时的探究

    事情的起因是这样的,公司使用自建 dns 服务器,但是有一个致命缺陷,不支持 ipv6 格式的地址解析,而 node 的 DNS 解析默认是同时请求 v4 和 v6 的地址的,这样会导致偶尔在解析 v ...

  9. Linux7中安装DNS服务,CentOS7/RHEL7搭建DNS服务器

    CentOS7/RHEL7搭建DNS服务器 DNS(域名系统)主要用于域名与IP地址的相互转换,将IP地址转换成对应的主机名或将主机名转换成与之相对应IP地址的一种机制.通过域名解析出IP地址的叫做正 ...

最新文章

  1. WebForm页面生命周期及asp.net运行机制
  2. 中国采盐行业运营效益分析与项目投资可行性研究报告2022-2028年
  3. ThreadPoolExecutor的七个参数详解
  4. OpenGL延迟着色之一
  5. android 清空所有控件,如何清空android ListView控件的内容
  6. 剑指offer之 旋转数组的最小数字
  7. SetConsoleCursorPosition光标的位置控制
  8. LeetCode算法入门- Palindrome Number-day2
  9. ”*“在正则表达式和通配符的应用
  10. kettle 提交数据量_Kettle数据同步速度调优记录
  11. go实现区块链[3]-遍历区块链与数据库持久化
  12. Python学习-将list列表写入文件并读取方法汇总
  13. 如何在windows下安装GIT
  14. Citrix基础端口了解
  15. 切换google的公共库缓解网站访问慢的问题
  16. LCS最长公共子序列——动态规划
  17. 3A游戏制作人员职位及部分职位要求
  18. protel 99se交互式布局
  19. 国产 TF232RL 驱动
  20. java 输出水仙花数

热门文章

  1. 用c语言编写简单的餐厅点餐系统(带后台)
  2. WEB前端程序员找工作跳槽简历该怎么写?
  3. 虚拟化技术 - CPU虚拟化
  4. ubuntu 改屏幕分辨率命令_如何使用Ubuntu命令行更改屏幕分辨率?
  5. 腾讯云接口调用签名鉴权
  6. 胜博发表示玩游戏也能做公益!守望先锋为乳癌研究基金会募得一千多万美金
  7. 5G与AI, 浅谈(未完待续。。。)
  8. Win10 笔记本本地摄像头提供 Rtsp 视频流服务
  9. 【大学物理·光学】单缝的夫琅禾费衍射
  10. 全球与中国IC托盘行业调查与未来发展趋势研究报告