理解OpenShift网络:RoutervsRoute
OpenShift集群中,至少有三个地方需要用到DNS:
一是Pod中的应用通过域名访问外网的时候,需要DNS来解析外网的域名
二是在集群内部(pod中或者宿主机上)通过服务的域名来访问集群内服务的时候,这也是通常所说的服务发现功能,需要通过服务域名来先发现(获取其IP地址)再使用该服务
三是从集群外部通过域名访问部署在OpenShiftpod中的服务的时候,需要DNS来解析服务的外网域名
本文就从这三点出发,解释OpenShift是如何实现这三种DNS功能的。
一、OpenShift中的DNS相关组件及其配置
1.1Pod中的DNS配置
在Linux系统上,当一个应用通过域名连接远端主机时,DNS解析会通过系统调用来进行,比如getaddrinfo()。和任何Linux操作系统一样,Pod的DNS定义在文件中,其示例如下:
$cat/etc/:5
其中,
nameserver字段是pod所在的宿主机的主网卡的IP地址。也就是说pod中发起的所有DNS查询请求都会被转发到运行在宿主机的53端口上的DNS服务器上。
search字段指定当解析一个非FQDN域名时被附加的搜索域(searchdomain)列表。其解释如下:
域名(DomainName)分为两种,一种是绝对域名(AbsoluteDomainName,也称为Fully-QualifiedDomainName,简称FQDN),另一种是相对域名(RelativeDomainName,也称为PartiallyQualifiedDomainName,简称PQDN)。FQDN是完整域名,它能够唯一地在DNS名字空间中确定一个记录。比如最高级别的域名A包括子域名B它又包括子域名C,那么FQDN是,比如。有时候我们也会使用PQDN,它是不完全的、模糊的。
FQDN能被直接到DNS名字服务器中查询;而PQDN需要先转化为FQDN再进行查询。其做法是将PQDN附加一个搜索域名(searchdomain)来生成一个FQDN。在域名系统中,域名结尾是否是『.』被用来区分FQDN和PQDN。比如表示一个Apple公司的FQDN,而apple则表示一个PQDN,它的FQDN可能是;仍然是一个PQDN,它的FQDN可能是。
optionsndots:5
默认地,许多DNS解析器如果发现被解析的域名中有任何的点(.)就把它当做一个FQDN来解析;如果域名中没有任何点,就把它当做PQDN来处理,并且会加上系统的默认domainname和最后的点,来组成FQDN。如果没有指定默认的domainname(通过domain字段)或查询失败,则会将search字段的第一个值当做默认domainname,如果解析不成功,则依次往下试,直到有一个成功或者全部失败为止。
这个行为是通过optionsndots来指定的,其默认值为1,这意味着只要被解析域名中有任何一个点(.),那么它就会被当做FQDN,而不会附加任何searchdomain,直接用来查询。OpenShift环境中,这个值被设置为5。这意味着,只要被解析域名中包含不超过五个点,该域名就会被当做PQDN,然后挨个使用searchdomain,来组装成FQDN来做DNS查询。如果全部不成功过,则会尝试将它直接作为FQDN来解析。
因此,这某些场景中,pod中的DNS查询速度会降低应用的性能。解决方法主要有两种,要么直接使用FQDN,要么减小ndots的值,具体请查看Kubernetes和DNS的有关文档。
1.2Pod所在宿主机上的DNS配置及服务
1.2.1文件
[root@node2cloud-user]nameserverupdatedby/etc/NetworkManager//99-=1enable-dbusdns-forward-max=10000cache-size=10000bind-dynamicmin-port=1024except-interface==172.22.122.3server=172.22.122.2server=172.22.122.4
这些上游服务器的地址是从DHCP服务器中获取到的(我的OpenShift环境搭建在OpenStack虚拟机中。前两个地址是OpenStackneutron网络的DNSmasq地址,最后一个是单独搭建的bind9DNS服务器地址)。
在早期版本中(我的OpenShift版本是3.11),还有一个配置文件:
server=//127.0.0.1server=//127.0.0.1
这意味着所有以和结尾的域名,都会被转到127.0.0.1:53上被解析。而其它的解析请求,会被转到在中定义的上游DNS服务器。
我的3.11版本环境中并没有生成该文件。
从代码,OpenShift中的dnsmasq在启动时会自动添加这两条记录:
而dnsIP和dnsDomain应该是在/etc/origin/node/中的如下配置:
dnsBindAddress:127.0.0.1:53dnsDomain:
从dnsmasq日志中也能看到相关记录:
Dec314:10:57dnsmasq[29595]:
从上面的分析可见,在node节点上的dnsmasq,其实只是一个DNS查询转发器(转到上游DNS服务器或者本机上的SkyDns)和结果缓存器,它本身并不保存域名的原始记录。
1.2.3SkyDNS及其配置
关于SkyDNS:它是一个开源的构建在etcd之上的分布式服务宣告(announcement)和发现(discovery)服务。利用它,可以通过DNS查询来发现可用的服务。其开源社区的地址是。社区版本的SkyDns将记录保存在etcd中,在做查询时从etcd获取数据并封装成DNS结果格式给客户端。
SkyDNS的server部分支持被作为库文件使用,此时可以为其实现其它后端。在OpenShift中并没有采用默认的etcd后端,而是基于OpenShiftAPI服务实现了新的后端,其代码在。SkyDns调用OpenShiftAPI服务来获取主机名、IP地址等信息,然后封装成标准DNS记录并返回给查询客户端。
在127.0.0.1:53上,包装在openshift进程中的SkyDNS在侦听。
:530.0.0.0:*LISTEN17182/openshift
Node节点上的SkyDN要么从cache中直接回答DNS查询,要么调用OpenShiftAPI服务来获取数据并返回。
1.3Master节点上的DNS服务
文件同Node节点上的:
[root@master1cloud-user]nameserverupdatedby/etc/NetworkManager//99-:50:41dnsmasq[10607]::03:44dnsmasq[17788]::03:49dnsmasq[17788]:query[A]:03:49dnsmasq[17788]::03:49dnsmasq[17788]::03:49dnsmasq[17788]::03:49dnsmasq[17788]:
能看到node上的dnsmasq直接将查询请求转发给上游DNS名字服务器。因为存在多个名字服务器,所以是依次查询,直到成功为止。从日志看,其查询顺序和配置文件中的顺序是相反的。
2.2Pod内应用通过服务域名查找其IP地址
流程示意图如上图中的1+2.2+3部分所示。
日志实例:
(1)从一个pod中pingregistry-console服务的域名。
(2)Node宿主机(IP地址为172.22.122.13)上的dnsmasq收到该查询。
(3)dnsmasq将查询转到127.0.0.1:53上的SkyDns服务。
(4)SkyDNS做查询。SkyDNS能接收的域名格式:_(svc|points|pod).base,这意味着它支持查询服务(svc)、端点(points)和pod的DNS信息。
查询结果:
[root@node2cloud-user]53(172.22.122.9);;WHEN:MonDec0311:43:01CST2018;;MSGSIZErcvd:62
dnsmasq日志:
Dec314:19:44dnsmasq[29595]:query[A]:19:44dnsmasq[29595]::19:44dnsmasq[29595]:
(5)其它实验:查询服务的所有端点
查询结果:
[root@node2cloud-user];;QUESTIONSECTION:;172-30-162-172.;;ANSWERSECTION:172-30-162-172.;;Querytime:1msec;;SERVER:172.22.122.9(172.30.162.172)56(84)bytesofdata.
而这个FQDN被直接做DNS查询,结果查询失败,未能获取IP地址:
[root@node2cloud-user]#::Nameorservicenotknown
2.3从外网通过服务域名访问pod中运行的服务
可以看出,该过程中只涉及到外部DNS将服务的公共域名解析为OpenShiftRouter所在节点的公网地址,后面HAProxy作为代理,直接通过IP访问pod,并将结果返回客户端。
参考文档:
作者:SammyLiu
版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。