欢迎光临
我们一直在努力

Ansible案例:使用ansible配置DNS服务器

请结合作者xike__的专栏Ansible食用。

一、任务规划

  • 准备一台虚拟机作为dns服务器
  • 挂载并编辑本地仓库
  • 安装bind域名管理安装包
  • 修改配置文件,将域名设置为gqian.com
  • 放行防火墙,重启服务
  • 测试
  • 二、准备一台虚拟机做实验

    被控机器的ip

    [root@dnsserver ~]# ifconfig
    enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 192.168.122.101 netmask 255.255.255.0 broadcast 192.168.122.255
    inet6 fe80::5054:ff:fee8:1ac6 prefixlen 64 scopeid 0x20<link>
    ether 52:54:00:e8:1a:c6 txqueuelen 1000 (Ethernet)
    RX packets 7153 bytes 408370 (398.7 KiB)
    RX errors 0 dropped 6152 overruns 0 frame 0
    TX packets 820 bytes 66910 (65.3 KiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
    inet 127.0.0.1 netmask 255.0.0.0
    inet6 ::1 prefixlen 128 scopeid 0x10<host>
    loop txqueuelen 1000 (Local Loopback)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    三、安装bind包

    3.1. 控制节点ansible的结构

    3.1.1. 项目文件结构

    [root@server demo0]# tree
    .
    ├── ansible.cfg
    ├── copy_yy.yml
    ├── file_yy.yml
    └── inventory
    └── hosts

    1 directory, 4 files

    3.1.2. 主机文件

    [root@server inventory]# cat hosts
    [client0]
    192.168.122.18
    [dnsserver]
    192.168.122.101
    [web:children]
    client0
    dnsserver

    3.1.3. 配置文件 ansible.cfg

    [root@server demo0]# cat ansible.cfg
    [defaults]
    inventory=./inventory/hosts

    3.2. 编写剧本文件

    3.2.1. 挂载被控节点的仓库

    要用到mount模块

    – name: 挂在/dev/sr0设备
    mount:
    src: /dev/sr0
    path: /mnt
    fstype: iso9660
    opts: defaults
    state: mounted

    3.2.2. 配置仓库文件

    使用copy模块将本地local.repo文件copy到被控节点

    [root@server yum.repos.d]# cat /etc/yum.repos.d/local.repo
    [baseos]
    name=baseos
    baseurl=/mnt/BaseOS
    gpgcheck=0
    enable=1
    [appstream]
    name=baseos
    baseurl=/mnt/AppStream
    gpgcheck=0
    enable=1

    – name: 配置仓库配置文件
    copy:
    src: /etc/yum.repos.d/local.repo
    dest: /etc/yum.repos.d/local.repo
    owner: root
    group: root
    mode: '0644'

    3.2.3. 在dnsserver上安装bind包。

    要用到dnf模块,

    注意: 这里使用ansible-doc dnf 查询dnf模块的用法,详情请见[[Ansible#三、ansible中模块及其使用方法|ansible-doc 输出信息解读]]

    EXAMPLES:

    – name: Install the latest version of Apache
    ansible.builtin.dnf:
    name: httpd
    state: latest

    稍作修改一下

    – name: 安装bind软件
    dnf:
    name: bind
    state: latest

    写到这里时,如果使用ansible-playbook dns.yml –check永远回报错,报错的地方是dnf模块,因为前面的几个没有先决条件,而dnf必须要远程主机仓库配置好才行。但是ansible有幂等性,我们可以直接执行,但这在生产环境是不安全的,一定要三思。

    [root@server demo0]# cat dns.yml
    – name: 远程配置dns服务器
    hosts: dnsserver
    become: yes

    tasks:
    – name: 将/dev/sr0设备挂载到/mnt
    mount:
    src: /dev/sr0
    path: /mnt
    fstype: iso9660
    opts: defaults
    state: mounted
    – name: 配置仓库配置文件
    copy:
    src: /etc/yum.repos.d/local.repo
    dest: /etc/yum.repos.d/local.repo
    owner: root
    group: root
    mode: '0644'
    – name: 安装bind软件
    dnf:
    name: bind
    state: latest
    [root@server demo0]# ansible-playbook dns.yml

    PLAY [远程配置dns服务器] *************************************************************************************************************************

    TASK [Gathering Facts] ***************************************************************************************************************************
    ok: [192.168.122.101]

    TASK [将/dev/sr0设备挂载到/mnt] ******************************************************************************************************************
    changed: [192.168.122.101]

    TASK [配置仓库配置文件] **************************************************************************************************************************
    ok: [192.168.122.101]

    TASK [安装bind软件] ******************************************************************************************************************************
    changed: [192.168.122.101]

    PLAY RECAP ***************************************************************************************************************************************
    192.168.122.101 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

    四、修改named的配置文件

    一个非常重要的模块

    做下面的实验,主要使用的是copy模块,这个模块有参数非常重要的参数validate
    详情参见[[Ansible/提问日志/提问日志#3.|提问日志]]

    Ansible 的 validate 工作原理:

  • 先复制文件到目标主机的临时位置

  • 然后执行 validate 命令检查这个临时文件

  • 只有 validate 成功,才会用临时文件替换目标文件

  • 如果 validate 失败,不会替换原文件,任务失败

  • 修改目标主机的思路

    将编写好的配置文件放到控制节点的file文件夹里

    [root@server demo0]# tree file
    file
    ├── gqian.zone
    ├── named.conf
    ├── named.rfc1912.zones
    └── zone.gqian

    让后使用copy模块将编写好的配置文件替换掉被控节点上的配置文件,就完成配置了

    4.1. 修改主配置文件/etc/named.conf

    – name: 配置主配置文件
    copy:
    src: file/named.conf
    dest: /etc/named.conf
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'

    4.2. 修改/etc/named.rfc1912.zones

    – name: 配置区域配置文件
    copy:
    src: file/named.rfc1912.zones
    dest: /etc/named.rfc19212.zones
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'

    4.3. 在目录/var/named/下添加区域解析文件

    – name: 配置区域文件
    copy:
    src: file/gqian.zone
    dest: /var/named/gqian.zone
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkzone %s'


    4.4. 最终形态

    4.4.1. playbook的最终形态

    [root@server demo0]# cat dns.yml
    – name: 远程配置dns服务器
    hosts: dnsserver
    become: yes

    tasks:
    – name: 将/dev/sr0设备挂载到/mnt
    mount:
    src: /dev/sr0
    path: /mnt
    fstype: iso9660
    opts: defaults
    state: mounted
    – name: 配置仓库配置文件
    copy:
    src: /etc/yum.repos.d/local.repo
    dest: /etc/yum.repos.d/local.repo
    owner: root
    group: root
    mode: '0644'
    – name: 安装bind软件
    dnf:
    name: bind
    state: latest
    – name: 配置主配置文件
    copy:
    src: file/named.conf
    dest: /etc/named.conf
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'
    – name: 配置区域配置文件
    copy:
    src: file/named.rfc1912.zones
    dest: /etc/named.rfc19212.zones
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'
    – name: 配置区域文件
    copy:
    src: file/gqian.zone
    dest: /var/named/gqian.zone
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkzone gqian.com. %s'

    4.4.2. 执行ansible-playbook dns.yml

    [root@server demo0]# ansible-playbook dns.yml

    PLAY [远程配置dns服务器] *************************************************************************************************************

    TASK [Gathering Facts] ***************************************************************************************************************
    ok: [192.168.122.101]

    TASK [将/dev/sr0设备挂载到/mnt] ******************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置仓库配置文件] **************************************************************************************************************
    ok: [192.168.122.101]

    TASK [安装bind软件] ******************************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置主配置文件] ****************************************************************************************************************
    changed: [192.168.122.101]

    TASK [配置区域配置文件] **************************************************************************************************************
    changed: [192.168.122.101]

    TASK [配置区域文件] ******************************************************************************************************************
    changed: [192.168.122.101]

    PLAY RECAP ***************************************************************************************************************************
    192.168.122.101 : ok=7 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

    五、启动服务,测试服务是否成功

    5.1. 放行防火墙

    dns服务需要放行的流量清单

  • dns服务
  • – name: 防火墙放行服务
    firewalld:
    service: dns
    permanent: yes
    state: enabled
    immediate: yes

    5.2. 重新启动dns服务

    – name: 重新启动dns服务
    systemd:
    name: named
    state: restarted
    daemon_reload: yes

    六、验证实验是否成功

    6.1. 完整的dns.ymlplaybook内容

    – name: 远程配置dns服务器
    hosts: dnsserver
    become: yes

    tasks:
    – name: 将/dev/sr0设备挂载到/mnt
    mount:
    src: /dev/sr0
    path: /mnt
    fstype: iso9660
    opts: defaults
    state: mounted
    – name: 配置仓库配置文件
    copy:
    src: /etc/yum.repos.d/local.repo
    dest: /etc/yum.repos.d/local.repo
    owner: root
    group: root
    mode: '0644'
    – name: 安装bind软件
    dnf:
    name: bind
    state: latest
    – name: 配置主配置文件
    copy:
    src: file/named.conf
    dest: /etc/named.conf
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'
    – name: 配置区域配置文件
    copy:
    src: file/named.rfc1912.zones
    dest: /etc/named.rfc1912.zones
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkconf %s'
    – name: 配置区域文件
    copy:
    src: file/gqian.zone
    dest: /var/named/gqian.zone
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkzone gqian.com. %s'
    copy:
    src: file/zone.gqian
    dest: /var/named/zone.gqian
    owner: root
    group: named
    mode: '0640'
    validate: '/usr/sbin/named-checkzone 122.168.192.in-addr.arpa %s'
    – name: 防火墙放行服务
    firewalld:
    service: dns
    permanent: yes
    state: enabled
    immediate: yes
    – name: 重新启动dns服务
    systemd:
    name: named
    state: restarted
    daemon_reload: yes

    6.2. 执行剧本

    [root@server demo0]# ansible-playbook dns.yml
    [WARNING]: While constructing a mapping from /root/demo0/dns.yml, line 40, column 7, found a duplicate dict key (copy). Using last
    defined value only.

    PLAY [远程配置dns服务器] *************************************************************************************************************

    TASK [Gathering Facts] ***************************************************************************************************************
    ok: [192.168.122.101]

    TASK [将/dev/sr0设备挂载到/mnt] ******************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置仓库配置文件] **************************************************************************************************************
    ok: [192.168.122.101]

    TASK [安装bind软件] ******************************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置主配置文件] ****************************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置区域配置文件] **************************************************************************************************************
    ok: [192.168.122.101]

    TASK [配置区域文件] ******************************************************************************************************************
    changed: [192.168.122.101]

    TASK [防火墙放行服务] ****************************************************************************************************************
    ok: [192.168.122.101]

    TASK [重新启动dns服务] ***************************************************************************************************************
    changed: [192.168.122.101]

    PLAY RECAP ***************************************************************************************************************************
    192.168.122.101 : ok=9 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

    6.3. 使用dig命令测试dns服务是否成功。

    [root@server demo0]# dig @192.168.122.101 www.gqian.com A

    ; <<>> DiG 9.16.23-RH <<>> @192.168.122.101 www.gqian.com A
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; –>>HEADER<<- opcode: QUERY, status: NOERROR, id: 35119
    ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    ;; WARNING: recursion requested but not available

    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 1232
    ; COOKIE: 30082c134184840001000000699ab89cf8e1c8cf736e54d9 (good)
    ;; QUESTION SECTION:
    ;www.gqian.com.INA

    ;; ANSWER SECTION:
    www.gqian.com.86400INA192.168.122.18

    ;; Query time: 3 msec
    ;; SERVER: 192.168.122.101#53(192.168.122.101)
    ;; WHEN: Sun Feb 22 16:04:44 CST 2026
    ;; MSG SIZE rcvd: 86

    总结

    1. 核心流程:四步循环法

    在实验过程中,我们反复践行了高效的 Playbook 开发逻辑:

    • 分析需求:明确 DNS 部署涉及的挂载、配置仓库、安装软件、分发配置、防火墙放行及服务启动。

    • 锁定模块:通过功能匹配查找到 mount、copy、dnf、firewalld 和 systemd 模块。

    • 自学文档:利用 ansible-doc 快速获取参数(如 dnf 的 state,firewalld 的 immediate)。

    • 编写剧本:将零散的模块组合成具备逻辑先后顺序的 YAML 流程。

    2. 技术亮点:安全与稳健性

    • 配置校验 (Validate):这是本实验最大的亮点。通过 copy 模块的 validate 参数(如 /usr/sbin/named-checkconf %s),实现了“先校验、后替换”。这保证了即便配置文件有语法错误,也不会破坏远程主机的现有服务,是生产环境的金标准。

    • 环境自愈:剧本包含了从挂载光盘到配置本地 YUM 源的全过程,确保了在没有互联网环境的 RHEL 主机上也能实现自动化安装。

    • 状态闭环:通过 firewalld 放行流量和 systemd 重启服务,确保了部署完成后服务是立即对外可用的,而非死配置。

    3. 经验总结与注意事项(避坑指南)

    • 语法陷阱(重复键):在执行过程中出现的 WARNING: found a duplicate dict key (copy) 提示你:在同一个 Task 块中不能有两个并列的 copy 关键字。如果要拷贝多个文件,应分为两个 Task 或使用 loop 循环。

    • 前置依赖:实验中发现 dnf 模块在 –check 模式下会报错。这提醒我们:Ansible 剧本中的任务往往存在强上下文依赖(不配仓库就装不了包)。在复杂实验中,有时需要先确保基础环境任务执行成功。

    • 权限管理:在拷贝 DNS 区域文件时,你注意到了 group: named 和 mode: '0640',这体现了对 RHEL 安全权限体系的深入理解,防止了 DNS 信息泄露。

    赞(0)
    未经允许不得转载:171主机测评 » Ansible案例:使用ansible配置DNS服务器
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址