puppet-designate

    1. DNS基础知识
    2. 先睹为快—一言不合,立马动手?
    3. designate原理
    4. 小结

    阅读级别:选读

    建议阅读时间 2小时

    想要搞懂Designate项目,没有正确的DNS姿势怎么行?所以先别急,我们先来聊一聊DNS的那些事。

    DNS的全称是Domain Name System,负责主机名和互联网络地址之间的映射。在我们上网或者发送电子邮件的时候,一般都会使用主机名而不是IP地址,因为前者便于我们记忆,但是对于计算机来讲,TCP/IP网络中要求每一个互连的计算机都具有其唯一的IP地址,并基于这个IP地址进行通信。DNS能够帮助我们将主机名转换成具体的IP地址。从而完成主机之间的通信。

    DNS层级结构

    DNS是一个层级的分布式的数据库,以C/S架构工作,它将互联网名称(域名)和IP地址的对应关系记录下来,可以为客户端提供名称解析的功能。它允许对整个数据库的各个部分进行本地控制,借助备份和缓存机制,DNS将具有足够的强壮性。

    DNS数据库以层级的树状结构组织,最顶级的服务器被称为「根」(root),以 . 表示,它是所有子树的根。root将自己划分为多个子域(subdomain),这些子域包括com,net,org,gov,net等等,这些子域被称为顶级域(Top Level Domain, TDL)。再进一步,各顶级域再将自己划分成多个子域,子域还可以在划分子域,最后树的叶子节点就是某个域的主机名。整个结构如下图所示:

    每个域的名称服务器仅负责本域内的主机的名称解析,如果需要解析子域的主机,就需要再向其子域的名称服务器查询。这样一来,无论主机在哪个域内,都可以从根开始一级一级的找到负责解析此主机名称的域,然后完成域名解析。

    BIND DNS 服务器

    BIND是由Berkely大学研发的一款开源DNS服务器程序,它是目前世界上使用最为广泛的DNS服务器软件,支持各种unix平台和windows平台。在CentOS系统中,由bind软件包提供安装。

    Bind的两个配置文件:

    • /etc/named.conf:主要规范主机的设定、zone file 的所在、权限的设定等;
      主要配置如下:
    • 正反解资料库档案(zone file):/var/named/目录下,一个zone file由多条资源记录组成。
    1. @ IN SOA LinuxMaster.test.com. admin.test.com. (
    2. 2016092605 ; serial
    3. 21600 ; refresh
    4. 3600 ; retry
    5. 604800 ; expire
    6. 86400 ) ; minimum
    7. IN NS LinuxMaster

    DNS服务器类型

    缓存服务器需要配置:

    1. options {
    2. forward only; //所有请求转发到forwarders列表
    3. forwarders {
    4. 8.8.8.8;8.8.4.4; //定义转发请求目的IP
    5. };
    6. };

    Master DNS服务器需要配置:

    1. zone "test.com" IN {
    2. type master;
    3. file "test.com.zone";
    4. };

    Slave DNS服务器需要配置:

    1. zone "test.com" IN {
    2. type slave;
    3. masters {ip;};
    4. file "slaves/test.com.zone";
    5. };

    Slave必须要与Master相互搭配,当要修改一条记录时,只要手动更改Master那部机器的zone file,重新启动BIND这个服务后(或者等待一定时间),slave会自动同步这条更改的记录。
    基本上,不论Master 还是Slave 的资料库,都会有一个代表该资料库新旧的『序号』,这个序号数值的大小,会影响是否要更新的动作。至于更新的方式主要有两种:

    • Master主动告知:例如在Master在修改了资料库内容,并且加大资料库序号后,重新启动DNS服务,那master会主动告知slave来更新资料库,此时就能够达成资料同步;
    • 由Slave主动提出要求:基本上, Slave会定时的向Master察看资料库的序号,当发现Master资料库的序号比Slave自己的序号还要大(代表比较新),那么Slave就会开始更新。如果序号不变,那么就判断资料库没有更动,因此不会进行同步更新。

    资源记录:
    标准的资源记录具有其基本格式:[name]   [ttl]   IN  type  rdata

    每个区域数据库文件都是由资源记录构成的。type的值主要有:SOA记录、NS记录、A记录、CNAME记录、MX记录和PTR记录。

    DNS客户端

    dig是Linux下常用的DNS查询工具,在CentOS系统中,由bind-utils软件包提供,它的使用方法为:

    dig -t RRT NAME [@NAME_SERVER]

    例如,查询www.kernel.org的IP地址:

    1. dig -t A www.kernel.org @114.114.114.114
    2. ; <<>> DiG 9.8.3-P1 <<>> -t A www.kernel.org @114.114.114.114
    3. ;; global options: +cmd
    4. ;; Got answer:
    5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55431
    6. ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
    7. ;; QUESTION SECTION:
    8. ;www.kernel.org. IN A
    9. ;; ANSWER SECTION:
    10. www.kernel.org. 36 IN CNAME pub.all.kernel.org.
    11. pub.all.kernel.org. 36 IN A 149.20.4.69
    12. pub.all.kernel.org. 36 IN A 198.145.20.140
    13. pub.all.kernel.org. 36 IN A 199.204.44.194
    14. ;; Query time: 28 msec
    15. ;; SERVER: 114.114.114.114#53(114.114.114.114)
    16. ;; WHEN: Tue Feb 7 11:15:11 2017
    17. ;; MSG SIZE rcvd: 102

    基础知识

    Designate介绍

    Designate是OpenStack的DNSaaS组件,它为OpenStack提供了以下服务:

    • 域和备案管理的REST API
    • 多租户
    • 集成了Keystone认证
    • 在框架中整合了Nova和Neutron通知(自动生成相应记录)
    • 支持PowerDNS和Bind9开箱

    Designate的架构图如下:

    puppet-designate - 图2

    DNS服务器的池划管理

    Designate kilo版本所引入的pool manager机制将DNS服务器群划分成多个服务器池(pool),如下图所示,每个服务器池可以配置包含1台或多台DNS服务器。而且,池中的DNS服务器选型还可以不同,也就是说在一个服务器池中,可以有1台BIND服务器,还可以有1台PowerDNS服务器,这是完全支持的。

    服务器池的引入目的:

    1. 细化域名托管的颗粒度。用户请求托管的域名可以委派到某一个服务器池,而不需要在所有服务器上管理用户的域名和资源记录,降低了管理和运维的复杂度。例如,abc.com委派给pool 1的DNS服务器来管理,xyz.com委派到pool N的DNS服务器来管理。
    2. 每个服务器池可以包含多台DNS服务器,实现了高可用性和冗余备份。
    3. 服务器池的划分不受地域的限制,可以将分布在不同地域的DNS服务器划归到同一个池中,通过GLB和anycast路由技术可以实现就近DNS查询和负载均衡,加快DNS查询速度。

    官方文档上给了一个多个池的使用场景:

    The idea is that we’ll configure our pools to support different usage levels. We’ll define a gold and standard level and put zones in each based on the tenant.

    Our gold level will provide 6 nameservers that users have access to where our standard will only provide 2. Both pools will have one master target we write to.
    即通过配置不同的池来支持不同的用户等级。

    黄金等级的池提供六个nameservers ,而标准等级的池只提供两个。

    在mitaka版本,实现了CLI的方法来更新池,即通过创建一个yaml文件来定义池,然后通过desigante-manage来更新池,在后面的designate原理部分,贴出了一个yaml,仅供参考。

    在讲解designate模块之前让我们先使用puppet把我们的实验环境部署起来,请根据你的具体环境修改learn_designate.pp

    在终端执行以下命令:

    1. puppet apply -v learn_designate.pp

    ok,接下来快创建一个domain试试吧。

    1. designate domain-create --name example.com. --email root@example.com
    2. designate domain-list

    核心代码讲解

    Designate backend支持如BIND,PowerDNS等多种类型的DNS服务器,下面只以BIND为例来讲解

    1. class designate::backend::bind9 (
    2. $rndc_host = '127.0.0.1',
    3. $rndc_port = '953',
    4. $rndc_config_file = '/etc/rndc.conf',
    5. $rndc_key_file = '/etc/rndc.key'
    6. ) {
    7. include ::designate
    8. #安装bind相关的包,更改bind相关配置项
    9. include ::dns
    10. #配置rndc监听的host,port,configkey的目录
    11. designate_config {
    12. 'backend:bind9/rndc_host' : value => $rndc_host;
    13. 'backend:bind9/rndc_port' : value => $rndc_port;
    14. 'backend:bind9/rndc_config_file' : value => $rndc_config_file;
    15. }
    16. #更改named.conf(或者named.options)文件,允许创建新的zone
    17. concat::fragment { 'dns allow-new-zones':
    18. target => $::dns::optionspath,
    19. content => 'allow-new-zones yes;',
    20. order => '20',
    21. }
    22. }

    puppet-designate的安装简单来说做了三件事:

    • 后端DNS服务器的安装和配置,这一点上面已经有过讲解
    • designate相关软件包的安装
    1. package { 'designate-common':
    2. ensure => $package_ensure,
    3. name => $common_package_name,
    4. tag => ['openstack', 'designate-package'],
    5. }
    6. designate::generic_service { 'api':
    7. enabled => $enabled,
    8. manage_service => $service_ensure,
    9. ensure_package => $package_ensure,
    10. package_name => $api_package_name,
    11. service_name => $::designate::params::api_service_name,
    12. }
    13. ...
    • desingate配置文件的管理
      除了权限的相关配置,其它的配置项都在/etc/designate/designate.conf中
      [oslo_messaging_rabbit]下面是rabbitmq的相关参数,由class designate管理:
    1. designate_config {
    2. 'oslo_messaging_rabbit/rabbit_userid' : value => $rabbit_userid;
    3. 'oslo_messaging_rabbit/rabbit_password' : value => $rabbit_password, secret => true;
    4. 'oslo_messaging_rabbit/rabbit_virtual_host' : value => $rabbit_virtual_host_real;
    5. 'oslo_messaging_rabbit/rabbit_use_ssl' : value => $rabbit_use_ssl;
    6. 'oslo_messaging_rabbit/kombu_ssl_ca_certs' : value => $kombu_ssl_ca_certs;
    7. 'oslo_messaging_rabbit/kombu_ssl_certfile' : value => $kombu_ssl_certfile;
    8. 'oslo_messaging_rabbit/kombu_ssl_keyfile' : value => $kombu_ssl_keyfile;
    9. 'oslo_messaging_rabbit/kombu_ssl_version' : value => $kombu_ssl_version;
    10. 'oslo_messaging_rabbit/kombu_reconnect_delay' : value => $kombu_reconnect_delay;
    11. }

    [service:api] [service:central] [serivce:mdns] [service:pool_manager] 中的配置项分别由class designate::api designate::central designate::mdns designate::manager管理

    此处以具体的环境为例来介绍designate的原理
    实验环境:

    • designate-api, designate-central, designate-pool-manager, designate-mdns, rabbitmq, mysql, keystone 均部署在10.0.2.250
    • bind分别部署在10.0.2.250 10.0.2.249

    下面贴出pools.yaml的配置:

    Designate工作流程:

    • 用户请求designate-api,添加record或者domain
    • designate-api发送请求至mq中
    • designate-central接收到mq请求,写入db,同时通过mq触发pool_manager进行更新操作
    • pool_manager通过rndc(addzone/delzone/notifyzone)三个操作来通知pool_targets中定义的bind来进行操作
    • bind使用axfr来请求同步mdns
    • mdns从数据库中读取相应的domain信息来响应axfr请求

    Target vs. Nameserver

    当通过designate 增加/修改/删除记录时,会通过target 去write changes。
    当dns客户端去查询记录时,则会通过nameserver.
    以本次实验环境为例,当通过designate创建一个名为example.com的domain时,按照上面的pool.yaml配置,相当于执行了这两条命令:

    1. rndc -s 127.0.0.1 -p 953 -c /etc/rndc.conf -k /etc/rndc.key addzone example.com '{ type slave; masters { 10.0.2.250 port 5354; }; file "slave.example.com.75c9e003-a8f4-4771-a94e-4481ee019f1f"; };'
    2. rndc -s 10.0.2.249 -p 953 -c /etc/rndc.conf -k /etc/rndc.key addzone example.com '{ type slave; masters { 10.0.2.250 port 5354; }; file "slave.example.com.75c9e003-a8f4-4771-a94e-4481ee019f1f"; };'

    可以看到这些配置项都是在target中定义的。
    一个要解析的域名就是一个zone,一个zone对应/var/named/目录下的一个zone_file.在250和249机器上,都能找到新创建的这个文件:

    1. [root@server-250.2.stage.polex.io named ]$ ll
    2. total 32
    3. -rw-r--r--. 1 named named 544 Nov 3 17:50 3bf305731dd26307.nzf
    4. drwxrwx---. 3 named named 70 Nov 3 17:35 data
    5. drwxrwx---. 2 named named 58 Nov 4 16:32 dynamic
    6. -rw-r-----. 1 root named 2076 Jan 28 2013 named.ca
    7. -rw-r-----. 1 root named 152 Dec 15 2009 named.empty
    8. -rw-r-----. 1 root named 168 Dec 15 2009 named.loopback
    9. drwxr-x---. 2 root named 6 Oct 19 14:03 puppetstore
    10. -rw-r--r--. 1 named named 409 Nov 4 19:12 slave.example.com.75c9e003-a8f4-4771-a94e-4481ee019f1f
    11. drwxrwx---. 2 named named 6 Mar 16 2016 slaves

    通过dig 查询创建的server1.example.com记录时,返回信息为:

    1. [root@server-250.2.stage.polex.io ~ ]$ dig server1.example.com @10.0.2.250
    2. ; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.3 <<>> server1.example.com @10.0.2.250
    3. ;; global options: +cmd
    4. ;; Got answer:
    5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31922
    6. ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1
    7. ;; OPT PSEUDOSECTION:
    8. ; EDNS: version: 0, flags:; udp: 4096
    9. ;; QUESTION SECTION:
    10. ;server1.example.com. IN A
    11. ;; ANSWER SECTION:
    12. server1.example.com. 3600 IN A 1.2.3.4
    13. ;; AUTHORITY SECTION:
    14. example.com. 3600 IN NS server-249.2.stage.polex.io.
    15. example.com. 3600 IN NS server-250.2.stage.polex.io.
    16. ;; Query time: 0 msec
    17. ;; SERVER: 10.0.2.250#53(10.0.2.250)
    18. ;; WHEN: Fri Nov 04 18:45:55 CST 2016
    19. ;; MSG SIZE rcvd: 130

    Hidden Master

    前面有提到过,当我们创建一个名为example.com的domain时,执行的rndc命令都指定master host:10.0.2.250, port:5354
    在designate.conf的定义中,我们可以看到:

    1. [service:mdns]
    2. threads = 1000
    3. host = 0.0.0.0
    4. port = 5354
    5. tcp_backlog = 100
    6. tcp_recv_timeout = 0.5
    7. query_enforce_tsig = False

    5354是service designate-mdns监听的端口。
    所以说,250,249两台机器上的bind都是使用axfr来请求同步mdns,它们的记录都是同步过来的(所以某种意义上讲,它们都是slave节点)。
    这样的好处就是,如果250,249有公网ip,它的53接口能被访问,那么它的记录是不能通过外网来更改的(外网只能查询),对于dns记录的更改只能通过内网(10.0.2.250)designate api的方式。

    使用场景

    解析私有域名

    1. #创建一个domain
    2. designate domain-create --name example03.com. --email root@example.com
    3. #创建一条记录
    4. designate record-create --name server1.example03.com. --type A --data 1.2.3.4 ec5818c9-c9ca-4bd2-8ad4-4a964a39a24b
    5. #使用dig测试
    6. [root@server-250.2.stage.polex.io named ]$ dig @10.0.2.250 server1.example03.com
    7. ; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.3 <<>> @10.0.2.250 server1.example03.com
    8. ; (1 server found)
    9. ;; global options: +cmd
    10. ;; Got answer:
    11. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51643
    12. ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1
    13. ;; OPT PSEUDOSECTION:
    14. ; EDNS: version: 0, flags:; udp: 4096
    15. ;; QUESTION SECTION:
    16. ;server1.example03.com. IN A
    17. ;; ANSWER SECTION:
    18. server1.example03.com. 3600 IN A 1.2.3.4
    19. ;; AUTHORITY SECTION:
    20. example03.com. 3600 IN NS server-250.2.stage.polex.io.
    21. example03.com. 3600 IN NS server-249.2.stage.polex.io.
    22. ;; Query time: 0 msec
    23. ;; SERVER: 10.0.2.250#53(10.0.2.250)
    24. ;; WHEN: Fri Nov 04 19:20:58 CST 2016
    25. ;; MSG SIZE rcvd: 132

    designate-sink 通过nova handler 和 neutron handler,自动生成域名资源记录,比如当监听到Nova的compute.instance.create.end事件通知后,自动创建一条对应于刚创建的实例的A记录;当监听到Nuetron的floatingip.update.end事件通知后,自动更新一条相应的A记录。
    一个domain如下:

    当创建一个虚拟机后,自动创建一条A记录:

    1. designate record-list 98775b46-c868-4dd8-94fd-6bd789a5dbaa
    2. +--------------------------------------+------+------------------------+--------------------------------------------------------------------------------+
    3. | id | type | name | data |
    4. +--------------------------------------+------+------------------------+--------------------------------------------------------------------------------+
    5. | 680eb3f5-016f-45a3-ac34-e79ff46bf8df | SOA | bluesky.edu.au. | hurricane109.in.vpac.org. hostmaster.v3.org.au. 1412739659 3600 600 86400 3600 |
    6. | c66481bd-bd4f-4f90-976a-67b6654c4c60 | A | phobos.bluesky.edu.au. | 10.0.0.7 |
    7. +--------------------------------------+------+------------------------+--------------------------------------------------------------------------------+

    puppet-designate需要配置的文件仅有designate.conf,为了方便管理与配置,puppet把使用到的四个服务都分别写为了一个.pp的类,这样也方便我们管理这些配置项。这里讲解到功能没有涉及到跟nova,neutron的集成,集成之后的效果是当创建虚拟机或创建浮动IP后,创建的虚拟机或浮动ip的A记录记录会自动同步相应的zone 中 ,有兴趣的同学可以在官网查看。

    动手练习

    1.部署分布式的backend后端,并使用不同的DNS Server(BIND,PowerDNS,MysqlBIND)作存储后端。

    2.手动配置多个pool,不同的pool管理的各自的DNS Server(通过创建yaml文件,使用designate-manage命令实现)。

    3.安装designate-sink服务,修改nova.conf和neutron.conf相应配置,创建虚拟机或floating ip ,观察designate record的变化。