背景:最近公司有个需求,要在POD应用容器里面能够访问到一些外部域名,这些域名都在一台自建的DNS服务器上做了解析绑定。如果直接在Pod容器里的/etc/hosts文件中设置域名解析,或修改/etc/resolv.conf中的nameserver指向这台DNS服务器,这两种方式都不太方便管理,因为每次重新创建Pod或后续还有新Pod要创建时,都需要重新设置一遍,这时就需要有一个统一的地方设置域名解析,不需要到每个Pod里设置,这个地方就是coredns。

CoreDNS是一个DNS解析的组件,作为集群内的DNS服务器,为集群内部提供域名解析服务。比如当集群内Pod要访问某个service name时,就会用到coredns的解析服务。

DNS解析原理:

当部署好coredns后,集群中会有一个名为kube-dns的service,以及这个service下还有两个名为CoreDNS的Pod后端。

$ kubectl get svc kube-dns -n kube-system
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   172.17.0.10   <none>        53/UDP,53/TCP   471d$ kubectl get deployment coredns -n kube-system
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
coredns   2         2         2            2           471d

当集群中的Pod,需要访问集群内的nginx服务,会经过以下两个步骤:

                                     .------> Pod1(nginx1)(2)                    /.------------------> Service(nginx)---------> Pod2(nginx2)|
Pod(Client)|           '------------------> Service(kube-dns) ---------> Pod(coredns)(1)  UDP

(1)Pod Client要访问nginx服务时,会先请求本地DNS配置文件(/etc/resolv.conf)中指向的DNS服务器,然后DNS服务器再将nginx service解析后的IP返回给Pod。

(2)Pod Client获取到nginx服务的IP后,会再次直接向这个IP发起请求,请求最终会经过Nginx Service转发到后端POD容器上(nginx1和nginx2)。

Pod的DNS配置策略:

每个Pod所使用的DNS策略,是通过pod.spec.dnsPolicy字段设置的,共有4种DNS策略:

  • ClusterFirst:默认策略,表示使用集群内部的CoreDNS来做域名解析,Pod内/etc/resolv.conf文件中配置的nameserver是集群的DNS服务器,即kube-dns的地址。
  • Default:Pod直接继承集群node节点的域名解析配置,也就是,Pod会直接使用宿主机上的/etc/resolv.conf文件内容。
  • None:忽略k8s集群环境中的DNS设置,Pod会使用其dnsConfig字段所提供的DNS配置,dnsConfig字段的内容要在创建Pod时手动设置好。
  • ClusterFirstWithHostNet:如果Pod的hostNetwork字段设置为true,则表示Pod与宿主机共用同一个网络命名空间,此时Pod的DNS策略默认使用的是Default,不能访问集群内的服务。若希望Pod在host网络模式下还能访问集群内的服务,可以将dnsPolicy设置成ClusterFirstWithHostNet。

场景1:使用k8s集群提供的CoreDNS来做域名解析

将dnsPolicy字段设置为ClusterFirst,或者省略dnsPolicy字段,默认也是ClusterFirst。

apiVersion: v1
kind: Pod
metadata:name: nginx-demonamespace: default
spec:containers:- image: nginx:1.7.9name: nginxports:- containerPort: 80protocol: TCPdnsPolicy: ClusterFirst      #该字段要设置为ClusterFirst(若省略该字段默认也是ClusterFirst)

创建好Pod后,查看Pod内/etc/resolv.conf文件内容,nameserver指向的是kube-dns service地址,也就是使用CoreDNS来做域名解析。

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 172.17.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

场景2:Pod层面自定义DNS配置

将dnsPolicy设置为None,同时添加dnsConfig字段手动配置DNS解析内容。

apiVersion: v1
kind: Pod
metadata:name: nginx-demonamespace: mytest
spec:containers:- image: nginx:1.7.9name: nginxports:- containerPort: 80protocol: TCPdnsPolicy: NonednsConfig:nameservers: ["192.168.1.1","192.168.2.2"]        #最多可指定3个IP,当Pod的dnsPolicy设置为None时,列表必须至少包含一个IP地址searches:                                         #Pod中主机名查找的DNS搜索域列表- default.svc.cluster.local- svc.cluster.local- cluster.localoptions:- name: ndotsvalue: "5"

创建好Pod后,查看Pod内/etc/resolv.conf文件内容,nameserver是dnsConfig字段中配置的IP。

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 192.168.1.1
nameserver 192.168.2.2
search mytest.svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local
options ndots:5

如果dnsPolicy字段不是设置为None,而是ClusterFirst,则coredns的地址也会加入到Pod的/etc/resolv.conf文件中,该文件内容会变成如下:

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 172.17.0.10
nameserver 192.168.1.1
nameserver 192.168.2.2
search mytest.svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local
options ndots:5

场景3:继承node节上的DNS配置

将dnsPolicy字段设置为Default。Pod会继承宿主机上的/etc/resolv.conf内容,如果宿主机上/etc/resolv.conf文件中没有定义指向coredns地址的nameserver,则Pod容器内是无法访问到service name的。

apiVersion: v1
kind: Pod
metadata:name: nginx-demonamespace: default
spec:containers:- image: nginx:1.7.9name: nginxports:- containerPort: 80protocol: TCPdnsPolicy: Default

但注意,这个要先在宿主机上配置好/etc/resolv.conf的内容,如下:

$ cat /etc/resolv.conf
options timeout:2 attempts:3 rotate single-request-reopen
; generated by /usr/sbin/dhclient-script
nameserver 192.168.10.156
nameserver 192.168.10.157
nameserver 10.100.1.1

创建好Pod后,查看Pod内/etc/resolv.conf文件内容,跟宿主机上的是一样的,说明从宿主机上继承过来了。

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 192.168.10.156
nameserver 192.168.10.157
nameserver 10.100.1.1
options timeout:2 attempts:3 rotate single-request-reopen

场景4:Pod在HostNetwork网络模式下访问集群内的服务

如果Pod的hostNetwork字段设置为true,也就是Pod与宿主机共享同一个网络命名空间,则此时Pod的dnsPolicy默认策略是Default,即Pod会继承宿主机上的resolv.conf文件内容。若宿主机上的resolv.conf文件中没有配置coredns地址作为域名解析服务器,则此时的Pod容器内是无法访问集群内部其他的service name的,所以要访问集群内的service name,就要将dnsPolicy字段设置为ClusterFirstWithHostNet。

apiVersion: v1
kind: Pod
metadata:name: nginx-demonamespace: default
spec:containers:- image: nginx:1.7.9name: nginxports:- containerPort: 80protocol: TCPhostNetwork: truednsPolicy: ClusterFirstWithHostNet

创建好Pod后,查看Pod内/etc/resolv.conf文件内容,nameserver指向的还是coredns的地址。

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 172.17.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

如果不设置dnsPolicy字段,默认使用的策略是Default,则resolv.conf里就是宿主机上的内容,这时Pod内无法解析service name的。

$ kubectl exec nginx-demo cat /etc/resolv.conf
nameserver 192.168.10.156
nameserver 192.168.10.157
nameserver 10.100.1.1
options timeout:2 attempts:3 rotate single-request-reopen

集群CoreDNS配置:

coredns是k8s集群的一个DNS解析组件,不仅为集群内部的Pod应用提供域名解析服务,还支持集群内部的自定义服务域名、集群外部域名等。

常见的用法是,可以在coredns配置文件中,添加一些自定义DNS解析配置,它会对集群内部的所有Pod生效(前提是这个Pod的nameserver指向的是coredns)。

比如说,集群内部有很多个Pod应用,这个集群中的所有Pod应用都要能够访问到一个集群外部的域名a.test.com,如果此时逐个登录到Pod容器里修改/etc/hosts文件,添加一条a.test.com域名解析记录,要是真的这样做,估计会累死,另外如果后面还有源源不断的Pod要创建,每个Pod创建时又要配置好这个域名的解析,这样做实在太麻烦了。这时我们就可以通过coredns,修改它的corefile配置文件,添加一条a.test.com域名解析记录,这样只要Pod的nameserver指向的是coredns,这个Pod就不用做任何修改,就能访问到这个a.test.com域名。

比如说,现在集群中的Pod要访问的不只是a.test.com这一个域名,还有b.test.com、c.test.com 等很多外部域名要访问,而这些域名都在10.10.10.1这台外部的nameserver上做了解析绑定。那为了让集群内的Pod能访问到这些域名,就算在corefile里逐个添加这些域名的解析记录,也会很麻烦。这时可以在corefile里面,直接配置成10.10.10.1这个nameserver地址,供集群中的所有Pod使用,只要Pod的nameserver指向的是coredns,就能通过这个nameserver访问到集群外部的这些域名。

详细用法可参考官方手册:CoreDNS: DNS and Service Discovery

CoreDNS的默认配置:

如果k8s集群安装了coredns插件,在命名空间kube-system下,会有一个CoreDNS配置项。

$ kubectl -n kube-system get configmaps coredns
NAME      DATA   AGE
coredns   1      475d

这个配置项中,有一个data.Corefile字段,默认配置内容如下:

$ kubectl -n kube-system get configmaps coredns -o yaml
apiVersion: v1
data:Corefile: |.:53 {errorshealthreadykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecureupstreamfallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.confcache 30loopreloadloadbalance}
kind: ConfigMap
metadata:annotations:
...

配置字段说明:

error:错误信息到标准输出。
health:CoreDNS自身健康状态报告,默认监听端口8080,一般用来做健康检查。可通过http://localhost:8080/health获取健康状态。
ready:CoreDNS插件状态报告,默认监听端口8181,一般用来做可读性检查。可通过http://localhost:8181/ready读取状态。
kubernetes:CoreDNS kubernetes插件,提供集群内服务解析能力。
prometheus:CoreDNS自身metrics数据接口。可过http://localhost:9153/metrics获取prometheus格式的监控数据。
forward(或proxy):将域名查询请求转到预定义的DNS服务器。
cache:DNS缓存。
loop:环路检测,如果检测到环路,则停止CoreDNS。
reload:允许自动重新加载已更改的Corefile。编辑ConfigMap配置后,最好等几分钟以使更改生效。
loadbalance:循环负载均衡器。

CoreDNS的扩展配置:

场景1:特定域名使用指定的自定义DNS服务器

比如a.test.com域名需要经过自建DNS服务器(IP为10.10.10.1)进行解析,可为域名配置一个单独的服务块,示例配置如下:

a.test.com:53 {errorscache 30forward . 10.10.10.1
}

也可以匹配指定后缀为test.com的域名,都经过自建DNS服务器进行解析,如下:

test.com:53 {errorscache 30forward . 10.10.10.1
}

完整配置如下:

Corefile: |-.:53 {errorshealthkubernetes cluster.local in-addr.arpa ip6.arpa {pods insecureupstreamfallthrough in-addr.arpa ip6.arpa}prometheus :9153proxy . /etc/resolv.confcache 30loopreloadloadbalance}test.com:53 {errorscache 30forward . 10.101.1.3}

场景2:所有外部域名都使用自建DNS服务器

如果要访问的外部域名没有统一后缀,也可以直接指定自建的DNS服务器(IP为10.10.10.1、10.10.10.2).

Corefile: |-.:53 {errorshealthkubernetes cluster.local in-addr.arpa ip6.arpa {pods insecureupstreamfallthrough in-addr.arpa ip6.arpa}prometheus :9153forward . 10.10.10.1 10.10.10.2     #直接指定DNS服务器IP,可以有多个cache 30loopreloadloadbalance}

场景3:自定义hosts

也可以在coredns上配置ip与域名的绑定关系,比如a.test.com指定IP为192.168.1.100。

Corefile: |-.:53 {errorshealthhosts {     #设置hosts绑定192.168.1.100 a.test.comfallthrough}kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecureupstreamfallthrough in-addr.arpa ip6.arpa}prometheus :9153proxy . /etc/resolv.confcache 30loopreloadloadbalance}

场景4:集群外部访问集群内服务

集群node节点上的进程,如果希望能够访问到集群内的服务,可以修改node节点上的/etc/resolv.conf文件中的nameserver配置,将nameserver指定为集群kube-dns的ClusterIP来达到目的。

k8s篇-集群内的DNS原理与配置相关推荐

  1. k8s篇-集群内的DNS原理与配置和K8s hosts 解析 HostAliases

    背景:最近公司有个需求,要在POD应用容器里面能够访问到一些外部域名,这些域名都在一台自建的DNS服务器上做了解析绑定.如果直接在Pod容器里的/etc/hosts文件中设置域名解析,或修改/etc/ ...

  2. Kubernetes(K8s)集群安装部署

    Kubernetes(K8s)集群安装 Kubernetes(K8s)集群安装 1 .基本环境配置 1.1.Kubernetes集群规划 1.2.基础环境配置(所有节点) 1.2.1.Host文件修改 ...

  3. 这一篇 K8S(Kubernetes)集群部署 我觉得还可以

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 国内安装K8S的四种途径 Kubernetes 的安装其实并不复杂,因为Kubernetes 属 ...

  4. Kubernetes学习-K8S安装篇-集群安装网段划分

    Kubernetes学习-K8S安装篇-集群安装网段划分 1. 集群安装网段划分 2. 网段IP常用设置 3. 集群安装网段划分注意事项 1. 集群安装网段划分 集群安装时会涉及到三个网段: 宿主机网 ...

  5. k8s简单集群搭建和应用(包括虚拟机的开启)①

    1.三台虚拟机搭建 开三台虚拟机.使用Centos7 系统,网络模式使用NAT模式(校园网应该是用不了桥接模式) 在虚拟机里设置主机名 #依次设置主机名 hostnamectl set-hostnam ...

  6. 自动化运维之k8s——Kubernetes集群部署、pod、service微服务、kubernetes网络通信

    目录 一.Kubernetes简介 1.Kubernetes简介 2.kubernetes设计架构 3.Kubernetes核心组件 4.kubernetes设计结构 二.Kubernetes部署 1 ...

  7. 【Elasticsearch】我在 Elasticsearch 集群内应该设置多少个分片?

    1.概述 转载:https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster Ela ...

  8. Elasticsearch 集群内应该设置多少个分片(shard)?

    我应该设置多少个分片? 我应该设置多大的分片? Elasticsearch 是一个功能十分丰富的平台,支持各种用例,能够在数据整理和复制战略方面提供很大的灵活性.然而这一灵活性有时也会带来困扰,让您在 ...

  9. Sentinel 集群限流设计原理

    本节目录 1.集群限流使用场景 2.集群限流与单机限流的异同思考 3.探究集群限流实现原理 3.1 ClusterBuilderSlot 详解 3.2 集群限流模式实现原理 3.2.1 Default ...

最新文章

  1. 【Redfin SDE intern】跪经
  2. 软件设计之 数据库设计
  3. Could not find com.android.support.constraint:constraint-layout的问题解决
  4. 【SpringCloud】配置中心简介及其搭建
  5. 记住一个道理:只要自己变优秀了,其他的事情才会跟着好起来。
  6. golang中的并发服务器
  7. 无责任畅想:云原生中间件的下一站
  8. Android studio 克隆分支
  9. 2014届华为校园招聘机试题
  10. optaplanner_OptaPlanner –具有真实道路距离的车辆路线
  11. mysql8.0.19初始密码输入错误_MySQL 8.0.19支持输入3次错误密码锁定账户功能(例子)...
  12. PCB布局中丝印大小及位置调节方法
  13. SQL练习之两个列值的交换
  14. Google I/O 2019大会 Android主题会议
  15. Linux之安装虚拟机/虚拟操作系统[VisualBox]
  16. eNSP 华为模拟器更新说明
  17. 19华为软件精英挑战赛止步复赛
  18. 移动端(一)—— 移动端概念
  19. C语言中,1U<<29的意思
  20. IFR报告显示过去五年全球工业机器人销量翻番

热门文章

  1. 证券基础-------------------------债券
  2. CK基本使用和常见问题
  3. pytorch中的nn.Bilinear
  4. python iterable对象_Python迭代器Iterable判断方法解析
  5. C/C++中部分我不太了解的函数和头文件——iomanip和setw和setfill() 函数
  6. linux命令使用vim报错,LINUX中使用VIM替换报错:pattern not found
  7. git stash详解
  8. 案例解读 |核心业务沉淀不足,传统能源企业如何补上这一课
  9. 2022-2027年中国数码印花墨水行业市场全景评估及发展战略规划报告
  10. 十二、Linux文件 - fseek函数讲解