DNS解析-K8S coreDNS

作用

coreDNS的作用是在集群内提供ServicePod的域名解析服务。coreDNS会监听集群中Service和Pod的创建销毁事件,当Service或Pod被创建时,记录对应的解析记录。当其他Pod需要通过域名访问集群中的Service或Pod时,会向coreDNS服务查询解析记录,然后访问解析到的IP地址。整个流程如下

image.png

K8S服务在部署好coreDNS服务后,会对外暴露一个Service,集群内就可以通过访问该Service的ClusterIP+53端口获取域名解析服务。ClusterIP一般是固定的,在安装kubelet时,会传递--cluster-dns=<cluster-ip> --cluster-domain=<default-local-domain>(默认为cluster.local)参数给kubelet,kubelet在创建Pod时,就会把这两个配置写入到Pod的/etc/resolv.conf文件中。
cat /etc/kubernetes/kubelet可以看到kubelet的配置。

目前k8s支持正向查找(A记录),端口查找(SRV记录),反向IP地址查找(PTR记录)。

K8S中一般只有service和headless service后端的statefulset创建的Pod域名是固定的,其他Pod域名中都带有Pod IP,Pod重启后IP改变域名也会改变,不推荐通过域名访问。

coreDNS配置说明

Corefile配置

Corefile 是 CoreDNS 的配置文件,它定义了:

  • server 以什么协议监听在哪个端口(可以同时定义多个 server 监听不同端口)
  • server 负责哪个 zone 的权威(authoritative)DNS 解析
  • server 将加载哪些插件

Corefile的配置格式如下

zone:port {
 plugin1
 plugin2
}

其中zone表示监听的域名,可以是根域名.,顶级域名com等(一般省略前面的.);port表示server提供服务的端口,未配置使用默认的53端口。

server和端口是1对1的关系,server和zone是1对多的关系,即一个server只监听一个端口,一个server可以负责多个zone的DNS解析。

正向解析

.: {
  log
  errors
}
com: {
  log
}
.:54 {
 log
}

上面的coreDNS配置表示,起两个server,一个监听53端口,提供根域和com域的解析,另一个监听54端口,负责根域的解析。

域名解析使用贪心算法。当我们访问53端口,请求www.baidu.com的解析时,会匹配到第二个,即com域的解析。匹配成功后,开始执行里面配置的插件,此处记录一个log就结束了。

反向解析

in-addr.arpa (反向域名解析,从IP地址到域名的映射)
 in-addr是inverse address, arpa 的标准名称对应为Address and Routing Parameter Area, 即“地址路由参数域”。
由于在域名系统中,一个IP地址可以对应多个域名,因此从IP出发去找域名,理论上应该遍历整个域名树,但这在 Internet上是不现实的。为了完成逆向域名解析,系统提供一个特别域,该特别域称为逆向解析域in-addr.arpa。这样欲解析的IP地址就会被表达成一种像域名一样的可显示串形式,后缀以逆向解析域域名“in-addr.arpa”结尾。例如一个IP地址:218.30.103.170,其逆向域名表达方式为:170.103.30.218.in-addr.arpa。两种表达方式中IP地址部分顺序恰好相反,因为域名结构是自底向上(从子域到域),而IP地址结构是自顶向下(从网络到主机)的。实质上逆向域名解析是将IP地址表达成一个域名,以地址做为索引的域名空间,这样逆向解析的很大部分可以纳入正向解析中。

coreDNS在K8S中的配置

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        log
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        hosts {
            10.20.31.104 www.google.com
            fallthrough
        }
        prometheus :9153
        forward . /etc/resolv.conf {
            prefer_udp
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
...... 

插件调用说明

匹配域名后,会按照域内的插件顺序,依次调用插件。插件处理逻辑有以下四种:

  • 插件处理完成后,直接返回结果。如kubernetes,hosts,如果没有加fallthrough,则调用结束本插件后,就返回了。
  • 不被该插件处理,流转到下一个插件,如果所有插件不处理,则返回错误。
  • 插件内有fallthrough关键字,fallthrough到下一个插件。fallthrough关键字的含义是,继续调用下一个插件处理。
  • 插件处理后,打上hint,流转到下一个插件。
参数 说明
errors 打印/存储错误日志
log 将CoreDNS每次域名解析的日志打印出来
health CoreDNS自身健康状态报告,默认监听端口8080,一般用来做健康检查。您可以通过http://localhost:8080/health获取健康状态(coredns Pod配置的存活探针使用此接口获取CoreDNS自身健康)。
ready CoreDNS插件状态报告,默认监听端口8181,一般用来做可读性检查。可以通过http://localhost:8181/ready获取可读状态。当所有插件都运行后,ready状态为200(coredns Pod配置的就绪探针使用此接口获取CoreDNS插件的就绪状况)。
kubernetes kubernetes: CoreDNS Kubernetes插件,提供集群内服务解析能力。该插件实现了基于Kubernetes DNS的服务发现。

其中cluster.local in-addr.arpa ip6.arpa表示kubernetes插件会处理域名后缀为cluster.local的所有域名以及处理所有的in-addr.arpa中的反向dns查找和ip6.arpa形式域名,其中kubernetes集群域名后缀是在kubelet参数中配置的,默认值为cluster.local。

pods参数用于设置基于pods ip的A记录,例如default namespace下存在一个pod,ip为10.233.64.2,此Pod的A记录为10-233-64-2.default.pod.cluster.local ->10.233.64.2,pods参数有三个值,其中disabled表示关闭pod ip的A记录;insecure总是从请求中返回一个带有IP的A记录(不检查k8s)(例如:1-2-3-4.ns.pod.cluster.local. in A 1.2.3.4);verified表示如果在同一命名空间中,则存在匹配IP的pod。

fallthrough:指定特定区域查询失败,如果in-addr.arpa和ip6.arpa形式的域名在kubernetes插件没有匹配成功的话则进入下一个 plugin 继续。

ttl参数为响应客户端请求设置的自定义 TTL。更多参数配置见:https://coredns.io/plugins/kubernetes/
hosts 相当于主机/etc/hosts 文件里面的解析信息。如果一个域名在 hosts中存在,则优先使用这个信息返回,在本例中一定要注意hosts插件的位置,如果放在了forward插件之后,那么hosts插件即没有匹配的机会;
prometeus CoreDNS自身metrics数据接口。可以通过http://localhost:9153/metrics获取prometheus格式的监控数据。
forward 将域名查询请求转到预定义的DNS服务器。默认配置中,当域名不在Kubernetes域时,将请求转发到预定义的解析器(/etc/resolv.conf)中。默认使用宿主机的/etc/resolv.conf配置。

forward . /etc/resolv.conf中的"."表示匹配所有域名。
cache 溯源得到的结果,缓存指定时间。类似 TTL 的概念;TTL以秒为单位。如果未指定,将使用最大 TTL,对于 NOERROR 响应为 3600,对于拒绝存在响应为 1800。将 TTL 设置为 30表示缓存记录长达 30 秒。
loop 环路检测,如果检测到环路,则停止CoreDNS。例如,forward . /etc/resolv.conf中配置的dns server地址和coredns地址一致,客户端请求解析in-addr.arpa类型域名,在kubernetes插件中解析in-addr.arpa类型域名失败,由于配置了fallthrough in-addr.arpa ip6.arpa,那么就会进入到forward插件继续解析,由于forward . /etc/resolv.conf中配置的dns server地址和coredns地址一致,那么又会传到dns server进行解析,这么就陷入了一个死循环,通过loop插件可以避免环路问题。
reload 允许自动重新加载已更改的Corefile。编辑ConfigMap配置后,请等待两分钟以使更改生效,无需重启coredns对应的Pod。
loadbalance 循环DNS负载均衡器,可以在答案中随机A、AAAA、MX记录的顺序。

其他典型场景

  • 特定域名使用自定义DNS服务器
    example.com:53 {
        errors
        cache 30
        forward . 10.10.0.10
    }
  • 外部域名完全使用自建DNS服务器
  Corefile: |
    .:53 {
...
        forward . 10.10.0.10 10.10.0.20{
          prefer_udp
        }
...
    }
  • 禁止CoreDNS对IPv6类型的AAAA记录查询返回
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 15s
        }
        #新增以下一行Template插件,其它数据请保持不变。
        template IN AAAA .
    
    }
  • 统一域名访问服务或是在集群内对域名的做CNAME解析
Corefile: |
    .:53 {
        errors
        health {
           lameduck 15s
        }
        ready
        
        rewrite stop {
          name regex foo.example.com foo.default.svc.cluster.local
          answer name foo.default.svc.cluster.local foo.example.com 
        }

        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
          ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
          prefer_udp
        }
        cache 30
        loop
        reload
        loadbalance
    }

此处的含义是请求域名符合正则表达式foo.example.com时,重定向到foo.default.svc.cluster.local处理;处理完返回时,把response的foo.default.svc.cluster.local改写为foo.example.com,否则client端可能会认为返回结果无效,因为client请求的地址和接收到的answer的地址不是同一个,会认为存在中间人攻击。
rewrite的好处是,在公网(默认使用域名foo.example.com)、内网(默认使用域名foo.example.com)、集群内部(默认使用域名foo.default.svc.cluster.local),都可以使用同一个域名foo.example.com访问服务。(前提:该服务在公网和内网都通过LB暴露并绑定了域名。)
rewrite用法参考

参考

https://www.cnblogs.com/zhangmingcheng/p/15680815.html
https://help.aliyun.com/document_detail/380963.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容