kubernetes dns 解析超时问题排查

简介: kubernetes dns 解析超时问题排查

事故发起方

  • 在客户内网机器环境内部署的 grafana 一直获取不到 prometheus 的数据,导致页面一直展示 no data
  • 通过 grafana 页面测试 prometheus 数据源验证了这个问题,grafana 一直链接不上 prometheus 数据源

事故处理流程

grafana 容器访问 prometheus 的 svc

配置 curl-format 获取接口访问时间

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

获取 prometheus 的 svc 信息(这里理解逻辑就好,namespace 和 svc 的名字大家自己替换成自己的就好)

kubectl get svc -n tool | grep prometheus

返回结果类似下面的样子

prometheus-svc      ClusterIP   10.102.38.55     <none>        9090/TCP             41d
  • /dev/null 表示空设备,即丢弃一切写入的数据,但显示写入操作成功
  • -s 表示静默输出
curl -s -w "@curl-format.txt" \
-o /dev/null \
-l "http://10.102.38.55"

返回的结果如下,耗时非常的短

time_namelookup: 0.000
time_connect: 0.000
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.000
time_starttransfer: 0.001
----------
time_total: 0.001
使用 svc 域名获取请求时间
curl -s -w "@curl-format.txt" \
-o /dev/null \
-l "http://prometheus-svc.tool.svc.cluster.local"

返回结果如下,耗时 15秒之久

time_namelookup: 15.522
time_connect: 15.522
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 15.522
time_starttransfer: 15.523
----------
time_total: 15.523
容器内安装 bind-utils 工具

bind-utils 工具内有一个 host 命令,可以查看域名解析过程

host -v prometheus-svc.tool.svc.cluster.local

可以看到,总共尝试了五个域名,解析五次才达到我们需要使用的域名

Trying "prometheus-svc.tool.svc.cluster.local.tool.svc.cluster.local"
Trying "prometheus-svc.tool.svc.cluster.local.svc.cluster.local"
Trying "prometheus-svc.tool.svc.cluster.local.cluster.local"
Trying "prometheus-svc.tool.svc.cluster.local.openstacklocal"
Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59444
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN A
;; ANSWER SECTION:
prometheus-svc.tool.svc.cluster.local. 5 IN A   10.102.38.55
Received 108 bytes from 10.96.0.10#53 in 0 ms
Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26804
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN AAAA
;; AUTHORITY SECTION:
cluster.local.          30      IN      SOA     ns.dns.cluster.local. hostmaster.cluster.local. 1679994755 7200 1800 86400 30
Received 148 bytes from 10.96.0.10#53 in 0 ms
Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2668
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN MX
;; AUTHORITY SECTION:
cluster.local.          30      IN      SOA     ns.dns.cluster.local. hostmaster.cluster.local. 1679994764 7200 1800 86400 30
Received 148 bytes from 10.96.0.10#53 in 0 ms

翻看一系列文档

k8s 官方文档中,看到一句话:

DNS 查询可以使用 Pod 中的 /etc/resolv.conf展开。 Kubelet 为每个 Pod 配置此文件。 例如,对data的查询可能被展开为data.test.svc.cluster.local。 search 选项的取值会被用来展开查询。要进一步了解 DNS 查询,可参阅 resolv.conf 手册页面

在 resolv.conf 手册中,看到一个参数:

  • ndots:n

Sets a threshold for the number of dots which must appear in a name given to res_query(3) (see resolver(3)) before an initial absolute query will be made.

The default for n is 1, meaning that if there are any dots in a name, the name will be tried first as an absolute name before any search list elements are appended to it.

  • The value for this option is silently capped to 15.
  • 意思就是,在进行绝对查询前,必须要为出现的点数设置一个阈值
  • 这个阈值默认为1,意味着优先当前域名先做解析,也就是绝对查询
  • 这个选项的值,默认上限为 15
分析 kubernetes svc 的域名结构

kubernetes 默认的 svc 域名结构为:

  • <svc-name>.<namespace>.svc.cluster.local
  • <pod-name>.<svc-name>.<namespace>.svc.cluster.local

可以看到,不带 pod 名称时,域名中有四个点,带 pod 名称时,域名中有五个点

在容器内,通过查看 /etc/resolv.conf 文件可以看到当前的 ndots 设定的值

nameserver 10.96.0.10
search tool.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options ndots:5

在容器内尝试访问来验证

host -v prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local
  • 当域名内出现的点数和 ndots 设定的值一致时,走的绝对查询
  • 当域名内出现的点数小于 ndots 设定的值,就会走 /etc/resolv.conf 文件内 search 指定的 dns 服务器,并且逐一拼接到域名后面,最后才会进行绝对查询
Trying "prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local"
Received 175 bytes from 10.96.0.10#53 in 0 ms
Trying "prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local.tool.svc.cluster.local"
Trying "prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local.svc.cluster.local"
Trying "prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local.cluster.local"
Trying "prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local.openstacklocal"
Host prometheus-f9dd6964b-wzbk4.prometheus-svc.tool.svc.cluster.local.openstacklocal not found: 2(SERVFAIL)
Received 97 bytes from 10.96.0.10#53 in 2 ms

配置 pod 的 dnsConfig

既然问题出在 ndots 参数上,那就尝试修改 pod 的 yaml 文件,通过 kubernetes 官网可以看到 dns 相关的策略

Pod 的 DNS 策略 [ 这些策略可以在 Pod 规约中的 dnsPolicy 字段设置 ]

  • Default: Pod 从运行所在的节点继承名称解析配置
  • ClusterFirst: 与配置的集群域后缀不匹配的任何 DNS 查询(例如"www.kubernetes.io") 都会由 DNS 服务器转发到上游名称服务器。
  • 集群管理员可能配置了额外的存根域和上游 DNS 服务器

ClusterFirstWithHostNet: 对于以 hostNetwork 方式运行的 Pod,应将其 DNS 策略显式设置为 ClusterFirstWithHostNet

  • 否则,以 hostNetwork 方式和 ClusterFirst 策略运行的 Pod 将会做出回退至 “Default” 策略的行为
  • 注意:这在 Windows 上不支持
  • None: 此设置允许 Pod 忽略 Kubernetes 环境中的 DNS 设置
  • Pod 会使用其 dnsConfig 字段所提供的 DNS 设置

Pod 的 DNS 配置 [dnsConfig 字段是可选的,它可以与任何 dnsPolicy 设置一起使用。 但是,当 Pod 的 dnsPolicy 设置为 “None” 时,必须指定 dnsConfig 字段 ]

nameservers:将用作于 Pod 的 DNS 服务器的 IP 地址列表。

  • 最多可以指定 3 个 IP 地址
  • 当 Pod 的 dnsPolicy 设置为 “None” 时, 列表必须至少包含一个 IP 地址,否则此属性是可选的。
  • 所列出的服务器将合并到从指定的 DNS 策略生成的基本名称服务器,并删除重复的地址

searches:用于在 Pod 中查找主机名的 DNS 搜索域的列表。

  • 此属性是可选的
  • 指定此属性时,所提供的列表将合并到根据所选 DNS 策略生成的基本搜索域名中
  • 重复的域名将被删除
  • Kubernetes 最多允许 6 个搜索域
  • options:可选的对象列表,其中每个对象可能具有 name 属性(必需)和 value 属性(可选)
  • 此属性中的内容将合并到从指定的 DNS 策略生成的选项
  • 重复的条目将被删除
  • 通过 dnsConfig 来控制 ndots 的值,可以先设定到 4 来验证
dnsConfig:
  options:
    - name: ndots
      value: "4"

重启完容器后,再次进入容器查看 /etc/resolv.conf 文件的内容,可以看到 ndots 的值被修改成 4 了

nameserver 10.96.0.10
search tool.svc.cluster.local svc.cluster.local cluster.local openstacklocal
options ndots:4

继续用 host 命令查看域名解析过程

host -v prometheus-svc.tool.svc.cluster.local

可以看到,直接就走了绝对查询

Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45608
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN A
;; ANSWER SECTION:
prometheus-svc.tool.svc.cluster.local. 30 IN A  10.102.38.55
Received 108 bytes from 10.96.0.10#53 in 0 ms
Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10840
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN AAAA
;; AUTHORITY SECTION:
cluster.local.          30      IN      SOA     ns.dns.cluster.local. hostmaster.cluster.local. 1680002970 7200 1800 86400 30
Received 148 bytes from 10.96.0.10#53 in 0 ms
Trying "prometheus-svc.tool.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48585
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;prometheus-svc.tool.svc.cluster.local. IN MX
;; AUTHORITY SECTION:
cluster.local.          30      IN      SOA     ns.dns.cluster.local. hostmaster.cluster.local. 1680002961 7200 1800 86400 30
Received 148 bytes from 10.96.0.10#53 in 0 ms

用 curl 查看请求时间 [ 容器重启后,之前配置的 curl-format 记得重新生成一次 ]

curl -s -w "@curl-format.txt" \
-o /dev/null \
-l "http://prometheus-svc.tool.svc.cluster.local"

这个时候就跟吃了德福一样丝滑了

time_namelookup: 0.004
time_connect: 0.004
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.005
time_starttransfer: 0.006
----------
time_total: 0.006

这个时候,再去 grafana 去测试 prometheus 的数据源就不会报错了

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
域名解析 存储 网络协议
域名解析的终极指南:从基础到进阶,彻底搞懂 DNS 记录
域名解析是网站运行的基础,正确配置DNS记录至关重要。本文从基础到进阶全面解析DNS知识,涵盖A、AAAA、CNAME、MX、TXT、CAA等常见记录类型及其应用场景。通过学习,你将了解DNS的工作原理,掌握如何优化域名配置,确保网站与邮件服务高效运行。无论搭建个人博客还是企业官网,本文都能助你轻松搞定域名解析!
3357 0
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
12月前
|
域名解析 缓存 网络协议
DNS更新后不生效?快速排查攻略
本文介绍了修改DNS后不生效,其主因是DNS传播延迟。TTL值、ISP缓存及服务器位置影响传播速度。提前调小TTL、清除本地缓存、更换公共DNS可加速。通过nslookup、Dig或Myssl工具可检测全球解析状态,确保更新完成。
1887 1
|
Kubernetes 监控 API
深入解析Kubernetes及其在生产环境中的最佳实践
深入解析Kubernetes及其在生产环境中的最佳实践
971 93
|
域名解析 网络协议 网络安全
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
1486 2
|
域名解析 存储 缓存
深入学习 DNS 域名解析
在平时工作中相信大家都离不开 DNS 解析,因为 DNS 解析是互联网访问的第一步,无论是使用笔记本浏览器访问网络还是打开手机APP的时候,访问网络资源的第一步必然要经过DNS解析流程。
1682 31
|
网络协议 安全 Linux
阿里云服务器国际站dns服务器不可用怎么办?dns可以随便改吗?
阿里云服务器国际站dns服务器不可用怎么办?dns可以随便改吗?
5482 0
|
负载均衡 网络协议 容灾
【飞天技术沙龙】云解析 DNS 上海站《多云+IDC 融合场景下的 DNS 最佳实践》圆满落幕
【飞天技术沙龙】云解析 DNS 上海站《多云+IDC 融合场景下的 DNS 最佳实践》圆满落幕
417 0
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
域名解析 缓存 网络协议
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手

推荐镜像

更多
  • DNS