前言

在kubernets环境中,服务发现大都是基于内部域名的方式。那么就涉及到内部域名的解析。从1.11版本开始,kubeadm已经使用第三方的CoreDNS替换官方的kubedns作为集群内部域名的解析组件。

kubernets中的4种DNS策略

None

表示空的DNS设置,这种方式一般用于想要自定义 DNS 配置的场景,往往需要和 dnsConfig 配合一起使用达到自定义 DNS 的目的。

Default

此种方式是让kubelet来决定使用何种DNS策略。而kubelet默认的方式,就是使用宿主机的/etc/resolv.conf文件。

同时,kubelet也可以配置指定的DNS策略文件,使用kubelet参数即可,如:–resolv-conf=/etc/resolv.conf

ClusterFirst

此种方式是使用kubernets集群内部中的kubedns或coredns服务进行域名解析。若解析不成功,才会使用宿主机的DNS配置来进行解析。

ClusterFistWithHostNet

在某些场景下,我们的 POD 是用 HOST 模式启动的(HOST模式,是共享宿主机网络的),一旦用 HOST 模式,表示这个 POD 中的所有容器,都要使用宿主机的 /etc/resolv.conf 配置进行DNS查询,但如果你想使用了 HOST 模式,还继续使用 Kubernetes 的DNS服务,那就将 dnsPolicy 设置为 ClusterFirstWithHostNet。

策略配置示例

DNS策略,需要在Pod,或者Deployment、RC等资源中,设置 dnsPolicy 即可,以 Pod 为例:

apiVersion: v1
kind: Pod
metadata:
labels:
name: cadvisor-nodexxxx
hostip: 192.168.x.x
name: cadvisor-nodexxxx
namespace: monitoring
spec:
containers:
- args:
- --profiling
- --housekeeping_interval=10s
- --storage_duration=1m0s
image: google/cadvisor:latest
name: cadvisor-nodexxxx
ports:
- containerPort:
name: http
protocol: TCP
resources: {}
securityContext:
privileged: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
nodeName: nodexxxx

kubernets中域名解析流程

# Pod中的resolv.conf的解析配置

[root@l-k8s01 ~]# kubectl exec -it nginx-deploy-5754944d6c-dtzpj cat /etc/resolv.conf

nameserver 10.96.0.2
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:

[root@l-k8s01 ~]# kubectl get svc -n kube-system |grep dns

kube-dns   ClusterIP  10.96.0.2   <none>   /UDP,/TCP,/TCP   158d

a)文件中配置的 nameserver 一般是k8s集群内部的dns服务的ClusterIP,无法ping,但是可以访问。

b)意味着集群Pod内部的所有域名的解析,都要经过kubedns的虚拟ip 10.96.0.2 进行解析。

c)resolv.conf中search域分别是default.svc.cluster.local svc.cluster.local cluster.local,在kubernets中,域名的全称必须是 service-name.namespace.svc.cluster.local 。

d)假如集群中有一个svc(Service)名为a,在某个Pod中执行命令 curl a 时,在此Pod中会根据/etc/resolv.conf进行解析流程。选择nameserver 10.96.0.2进行解析,将字符串'a'带入到/etc/resolv.conf文件中不同的search域,依次进行查找,如下:

a.default.svc.cluster.local -> a.svc.cluster.local -> a.cluster.local

先查找 a.default.svc.cluster.local ,若找不到,则再查找 a.svc.cluster.local ,依次往下进行,直到找到为止。

curl效率分析

在集群中若存在一个名为a的svc,在Pod中curl a和curl a.default都能实现请求,那么两种方式哪个的效率高呢?

那肯定是curl a啦,因为发起此请求时,通过/etc/resolv.conf中第一列的search域就能直接找到 a.default.svc.cluster.local ,直接避免了下一级的查找。

容器中访问外部域名讲述

下文将通过示例说明Pod访问外部域名时发起的相应的请求信息。

以请求baidu.com为例,因为DNS容器一般不具备bash,所以无法通过docker exec的方式进入容器抓包,所以此处采用 进入到DNS容器的网络中(不是发起DNS请求的容器)的姿势去抓包,抓包姿势准备好后,同时在某容器中访问baidu.com,即可看到在进行的DNS查找的过程中都产生了什么样的数据包。

### 实操

# 进入dns容器网络,准备好抓包姿势

# 查看Pod所在具体的node节点

[root@master1 ~]# kubectl get pods -n kube-system -o wide|grep dns

coredns-5c48579f88-8wprg  /   Running      30d   10.244.4.120   node1
coredns-5c48579f88-rsnpr / Running 30d 10.244.5.142 node2

# 这里以node1上的容器为操作对象,所以到node1节点上进行操作

# 找到容器并打印对应的NS ID

[root@node1 ~]# docker ps |grep dns

a964bbb43534 c0f6e815079e "/coredns -conf /etc…"  days ago Up  days k8s_coredns_coredns-5c48579f88-8wprg_kube-system_b1e7f3c3-98eb--b156-1d203f98bd74_16
fbd12d2f9c7c k8s.gcr.io/pause:3.1 "/pause" days ago Up days k8s_POD_coredns-5c48579f88-8wprg_kube-system_b1e7f3c3-98eb--b156-1d203f98bd74_3

[root@node1 ~]# docker inspect --format "{{.State.Pid}}"  a964bbb43534


# 进入此容器的网络Namespace

[root@node1 ~]# nsenter -n -t 21617

# 抓包姿势就绪

[root@node1 ~]# tcpdump -i eth0 udp dst port 53|grep 'baidu.com'

# 在另外的某容器中,进行域名查找操作

说明:一般pod中没有nslookup命令,故需要手动安装,根据不同环境自选以下操作。

### Centos

]# cat /etc/redhat-release

CentOS Linux release 7.5.1804 (Core)

]# yum -y install bind-utils

### Debian

# cat /etc/issue

Debian GNU/Linux 9

# apt-get install dnsutils -y

root@jenkins-7d66bf7977-cm4x4:~# nslookup baidu.com 10.244.4.120

注意:10.244.4.120是node1上的dns pod在kubernets集群中的内部通信ip地址。因为环境中有两个dns pod,将其指定要单个具体的容器,能够使抓包数据完整。

# 随后,在前面就绪的抓包姿势窗口就能看到数据包的出现

[root@node1 ~]# tcpdump -i eth0 udp dst port 53|grep 'baidu.com'

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size bytes
::50.791154 IP 10.244.4.127. > node1.domain: + A? baidu.com.infra.svc.cluster.local. ()
::50.792540 IP 10.244.4.127. > node1.domain: + A? baidu.com.svc.cluster.local. ()
::50.793439 IP 10.244.4.127. > node1.domain: + A? baidu.com.cluster.local. ()
::50.799463 IP 10.244.4.127. > node1.domain: + A? baidu.com. ()

说明:

a)数据包中显示的 infra 是执行nslookup的pod的NameSpace;

b)根据数据显示,在真正解析到 baidu.com 之前,经历了baidu.com.infra.svc.cluster.local. > baidu.com.svc.cluster.local. > baidu.com.cluster.local. 三次DNS请求。

请求浪费的原因

上文在正确请求到baidu.com之前,有过三次无效请求,即意味着请求浪费,那为什么会出现那种情况呢,请继续往下看。

# Pod中的resolv.conf的解析配置

root@jenkins-7d66bf7977-cm4x4:/# cat /etc/resolv.conf
nameserver 10.96.0.2
search infra.svc.cluster.local svc.cluster.local cluster.local host.com
options ndots:

# options ndots:5 解释

如果查询的域名包含的点".",不到5个,那么进行DNS查找,将使用非完全限定名称(或者叫绝对域名),如果你查询的域名包含点数大于等于5,那么DNS查询,默认会使用绝对域名进行查询。

如果我们请求的域名是,a.b.c.d.e,这个域名中有4个点,那么容器中进行DNS请求时,会使用非绝对域名进行查找,使用非绝对域名,会按照 /etc/resolv.conf 中的 search 域,走一遍追加匹配:

a.b.c.d.e.cicd.svc.cluster.local. ->

a.b.c.d.e.svc.cluster.local. ->

a.b.c.d.e.cluster.local.

直到找到为止。如果走完了search域还找不到,则使用 a.b.c.d.e. ,作为绝对域名进行DNS查找。

说明:

a)请求域名中点数少于5个时,先走search域,最后将其视为绝对域名进行查询;

b)请求域名中点数大于等于5个时,直接视为绝对域名进行查找,只有当查询不到的时候,才继续走 search 域。

优化请求浪费

使用全限定域名

当访问某域名时,以 '.' 为后缀,即使用 完全限定域名(绝对域名),这样发起的域名请求时将不会走search域进行匹配,而是直接使用整个原始域名字符串为个体进行解析。

如:

nslookup baidu.com.

配置特定ndots

在kubernets中,ndots值默认是5。是因为,Kubernetes 认为,内部域名,最长为5,要保证内部域名的请求,优先走集群内部的DNS,而不是将内部域名的DNS解析请求,有打到外网的机会,Kubernetes 设置 ndots 为5是一个比较合理的行为。

如果有特定业务需求,也可配置ndots,如下:

apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsConfig:
options:
- name: ndots
value: ""

Kubernetes内部域名解析的那些事儿的更多相关文章

  1. 当你创建了一个 Deployment 时,Kubernetes 内部发生了什么?

    我们通常使用 kubectl 来管理我们的 Kubernetes 集群. 当我们需要一个 Nginx 服务时,可以使用以下命令来创建: kubectl create deployment nginx ...

  2. 配置内网DNS实现内部域名解析

    服务器 实战目的: ü 配置内网的DNS服务器实现内网服务器的域名解析. ü 配置内网的DNS服务器减少到Internet的域名解析流量. ü 配置内网的DNS服务器实现Internet上服务器的域名 ...

  3. Docker(二):理解容器编排工具Kubernetes内部工作原理

    一.Kubernetes是什么 要说到Docker就不得不说说Kubernetes.当Docker容器在微服务的环境下数量一多,那么统一的,自动化的管理自然少不了.而Kubernetes就是一个这样的 ...

  4. 通过Wireshark抓包分析谈谈DNS域名解析的那些事儿

    文/朱季谦 本文主要想通过动手实际分析一下是如何通过DNS服务器来解析域名获取对应IP地址的,毕竟,纸上得来终觉浅,绝知此事要躬行. 域名与IP地址 当在浏览器上敲下"www.baidu.c ...

  5. 当一个 Pod 被调度时,Kubernetes 内部发生了什么?

    在 Kubernetes 中,调度是指将 Pod 放置到合适的 Node 上,然后对应 Node 上的 Kubelet 才能够运行这些 Pod . kube-scheduler 是集群控制平面的主要组 ...

  6. 采坑指南——k8s域名解析coredns问题排查过程

    正文 前几天,在ucloud上搭建的k8s集群(搭建教程后续会发出).今天发现域名解析不了. 组件版本:k8s 1.15.0,coredns:1.3.1 过程是这样的: 首先用以下yaml文件创建了一 ...

  7. 二进制部署kubernetes集群(下篇)

    1.k8S核心资源管理方法 1.1.陈述式资源管理方法 1.1.1.管理名称空间资源 1.1.1.1.查看名称空间 [root@hdss7-21 ~]# kubectl get namespace N ...

  8. kubernetes进阶(三)服务发现-coredns

    服务发现,说白了就是服务(应用)之间相互定位的过程. 服务发现需要解决的问题: 1.服务动态性强--容器在k8s中ip变化或迁移 2.更新发布频繁--版本迭代快 3.支持自动伸缩--大促或流量高峰 我 ...

  9. K8S(04)核心插件-coredns服务

    K8S核心插件-coredns服务 目录 K8S核心插件-coredns服务 1 coredns用途 1.1 为什么需要服务发现 2 coredns的部署 2.1 获取coredns的docker镜像 ...

随机推荐

  1. 「雕爷学编程」Arduino动手做(33)——ESP-01S无线WIFI模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  2. 虚拟机安装 Linux 最完整攻略

    工作中如果你是Linux运维,或者程序员,一定经常需要一个Linux的环境来让你折腾.这个时候使用虚拟机对我们来说是一个不错的选择. 虚拟化技术目前主要有两种:一.原生架构,这种虚拟机产品直接安装在计 ...

  3. 剑指Offer02之替换空格

    剑指Offer02之替换空格 题目描述 实现一个方法,将输入的字符串中的空格替换成%20. 例子如下 hello world --> hello%20world 代码实现 //方法一 采用Jav ...

  4. Jenkins-插件开发(简单demo)

    推荐:官网创建插件案例:https://jenkins.io/doc/developer/tutorial/run/ 官方的这篇文章讲的很详细了,我就补充补充其中遇到的一些问题. 前置条件:maven ...

  5. 【Mac】pip自定义源【永久有效】

    鉴于国内网络环境,pip安装比较慢已成为不争的事实,通过以下几步轻松解决 1.创建文件夹   mkdir -/.pip 2.创建配置文件  vim -/.pip/pip.conf mkdir ~/.p ...

  6. ATX插件机制-学习学习

    添加插件:记录一下 https://testerhome.com/topics/16074 webview操作: https://testerhome.com/topics/12599

  7. 使用websocket开发智能聊天机器人

    前面我们学习了异步web框架(sanic)和http异步调用库httpx,今天我们学习websocket技术. websocket简介 我们知道HTTP协议是:请求->响应,如果没有响应就一直等 ...

  8. 从Student类和Teacher类多重派生Graduate类 代码参考

    #include <iostream> #include <cstring> using namespace std; class Person { private: char ...

  9. 一篇文章看清楚 Linux 的职业发展方向

    手机.汽车.甚至宇宙飞船,在今天的科技世界中,你几乎到处都能看到 Linux 的身影.前两天 SpaceX 成功将宇航员送入太空的猎鹰9号火箭与龙飞船用的也是 Linux的操作系统.身处与 Linux ...

  10. (linux)Centos 7 xfsdump文件系统的备份和恢复

         XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据.xfsdump 按inode顺序备份一个XFS文件系统. centos7选择xfs格式作为默认文件 ...