Kubernetes:缓慢的 DNS

Kubernetes: slow DNS

我有一个 Kubernetes 集群,它是使用 AWS 中的 kube-up.sh 脚本初始化的,偶尔在从另一个 pod 中查找一项服务时,DNS 查找速度非常慢。这是基本图片:

    (browser)
        |
        V
      (ELB)
        |
        V
(front-end service)
        |
        V
  (front-end pod)
        |
        V
 (back-end service)
        |
        V
  (back-end pod)
        |
        V
    (database)

我在前端和后端级别安装了计时日志记录,并且它们的数量对于一些请求大相径庭。偶尔我们会看到一个请求,FE nginx logging 说需要 8.3 秒,但是后端 gunicorn 进程说需要 30ms。

我可以 exec 进入 FE pod 并根据 this blog post 中的示例对后端端点执行 curl 以获取计时数据,它看起来像这样:

        time_namelookup:  3.513
           time_connect:  3.513
        time_appconnect:  0.000
       time_pretransfer:  3.513
          time_redirect:  0.000
     time_starttransfer:  3.520
                        ----------
             time_total:  3.520

这么慢似乎是来自 DNS。我们为暂存设置了一个单独的集群,这种事情似乎并没有发生在那里,所以我不确定该怎么做。大多数请求在合理的时间内发生,不到 50 毫秒,但每十分之一左右的请求需要几秒才能解决。

我发现 this thread 这听起来像是 SkyDNS 使用 etcd 的问题,但我不确定如何验证或修复它。而且这种情况发生的频率 太频繁了,不可能定期丢失配置值(我们的流量不是那么高)。

此处修复了一个错误 (https://github.com/kubernetes/kubernetes/pull/13345) that has been shown to cause this problem in Kubernetes clusters 1.0.5 and older. The problem is fixed in the 1.0.6 release

默认情况下,kubernetes 配置 pods 使用 skydns(解析服务名称)以及底层基础设施的解析器(解析外部请求)。 docker 容器内的解析器库将以循环方式向 skydns 或外部解析器发送请求。它还尝试通过首先包含全名(例如 service.namespace.svc.domain)然后生成请求修剪名称(例如 service.namespace.svc;service.namespace)。如果第一个请求发送到错误的服务器,这可能会导致超时时间更长。

如果您不关心外部解析器,您可以使用 kubelet 标志“--resolv-conf”覆盖解析行为,它允许您指定一组备用外部解析器(或 none).