Ansible 实战案例--Playbook 详解 之 Playbook 的构成

前言

playbook 是 Ansible 进行配置管理的组件, 虽然 Ansible 的日常 Ad-Hoc 命令功能很强大, 能完成一
些基本配置管理工作, 但是 Ad-Hoc 命令无法支撑复杂环境的配置管理工作。 在我们实际使用 Ansible
的工作中, 大部分时间都是在编写 playbook 。


提示:本篇文章所使用的环境为centos-8.2基于ansible-2.8.0 搭建
具体环境搭建,请参考:ansible-2.8.0 搭建链接

一、Playbook 结构介绍

  • Playbook 核心元素

Tasks:任务,由模板定义的操作列表
Variables:变量
Templates:模板,即使用模板语法的文件
Handlers:处理器 ,当某条件满足时,触发执行的操作
Roles:角色

  • Playbook 基本语法

Ansible 的 playbook 文 件 格 式 为 YAML 语 法
首先先了解一下YAML,默认的SLS文件的renderer是YAML renderer。YAML是一个有很多强大特性的标记性语言。Salt使用了一个YAML的小型子集,映射非常常用的数据结构,像列表和字典。
YAML renderer的工作是将YAML数据格式的结构编译成为Python数据结构给Salt使用。
YAML语法有三个注意事项,具体如下

1、使用空白字符为文件缩排表示结构,不过不能使用TAB
2、注释用#号
3、字符串平常不使用引号,如果有需要,可以使用单引号或双引号。使用双引号表示字符串时,特殊字符可以通过倒斜线(\)来进行定义
YAML编写技巧
1 、缩进
YAML使用一个固定的缩进风格表示数据层结构关系。建议使用2个空格。
不要使用table键。
2 、冒号
冒号两边表示key和value。
3 、短横线
想要表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表的一部分。

  • Playbook语法基本特性

1 ) 需要以 “----”( 3 个减号) 开始, 且需顶行首写。
2 ) 次行开始正常写 Playbook 的内容, 但笔者建议写明该 Playbook 的功能。
3 ) 使用 # 号注释代码。
4 ) 缩进必须是统一的, 建议使用两个空格,不能将空格和 Tab 混用。
5 ) 缩进的级别必须是一致的, 同样的缩进代表同样的级别, 程序判别配置的级别是通过缩进结合换行来
实现的。
6 ) YAML 文件内容和 Linux 系统大小写判断方式保持一致, 是区别大小写的, k/v 的值均需大小写敏
感。
7 ) k/v 的值可同行写也可换行写。 同行使用“:” 分隔, 换行写需要以分隔。
8 ) 一个完整的代码块功能需最少元素, 需包括 name: task。
9 ) 一个 name 只能包括一个 task。

二、Playbook 案例实施流程

  • 编辑 Playbook 文件
#编辑yaml文件
[root@Ansible-Server ansible]# vim install_nginx.yaml
---
- hosts: all
  tasks:
    - name: Insatll nginx
      yum:
        name: nginx
        state: present
  • Playbook 配置文件检测环节
#语法检查
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --syntax-check

playbook: install_nginx.yaml

#查看Playbook 文件中所有的task名称
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --list-task

playbook: install_nginx.yaml

  play #1 (all): all	TAGS: []
    tasks:
      Insatll nginx	TAGS: []

#查看Playbook 文件中针对的主机
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml  --list-hosts

playbook: install_nginx.yaml

  play #1 (all): all	TAGS: []
    pattern: ['all']
    hosts (4):
      node01
      node3
      node02
      node04

#空运行,但是存在依赖关系,检查结果会报错
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --check

PLAY [all] ***********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [node04]
ok: [node01]
ok: [node02]
ok: [node03]

TASK [Insatll nginx] *************************************************************************************************
changed: [node04]
changed: [node02]
changed: [node03]
changed: [node01]

PLAY RECAP ***********************************************************************************************************
node01                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

#限定Playbook 执行范围,即使Playbook中设置了hosts的值为all
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --limit node01

PLAY [all] ***********************************************************************************************************

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

TASK [Insatll nginx] *************************************************************************************************
changed: [node01]

PLAY RECAP ***********************************************************************************************************
node01                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
  • 执行任务
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml 

PLAY [all] ***********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [node02]
ok: [node04]
ok: [node03]
ok: [node01]

TASK [Insatll nginx] *************************************************************************************************
ok: [node01]
changed: [node03]
changed: [node02]
changed: [node04]

PLAY RECAP ***********************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
  • 验证
#查看nginx是否成功安装
[root@Ansible-Server ansible]# ansible all -m shell -a 'yum list installed nginx'
[WARNING]: Consider using the yum module rather than running 'yum'.  If you need to use command because yum is
insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to
get rid of this message.
node01 | CHANGED | rc=0 >>
Installed Packages
nginx.x86_64          1:1.14.1-9.module_el8.0.0+184+e34fea82          @AppStream
node02 | CHANGED | rc=0 >>
Installed Packages
nginx.x86_64          1:1.14.1-9.module_el8.0.0+184+e34fea82          @AppStream
node04 | CHANGED | rc=0 >>
Installed Packages
nginx.x86_64          1:1.14.1-9.module_el8.0.0+184+e34fea82          @AppStream
node03 | CHANGED | rc=0 >>
Installed Packages
nginx.x86_64          1:1.14.1-9.module_el8.0.0+184+e34fea82          @AppStream

#检查worker_processes 设置
[root@Ansible-Server ansible]# ansible all -m shell -a 'grep worker_processes /etc/nginx/nginx.conf'
node04 | CHANGED | rc=0 >>
worker_processes auto;
node02 | CHANGED | rc=0 >>
worker_processes auto;
node01 | CHANGED | rc=0 >>
worker_processes auto;
node03 | CHANGED | rc=0 >>
worker_processes auto;


##修改Playbook文件
---
- hosts: all
  tasks:
    - name: Insatll nginx
      yum:
        name: nginx
        state: present
    - name: Start nginx
      service:
        name: nginx
        state: started
        enabled: yes


#执行指定name对应的任务
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --start-at-task='Start nginx'

PLAY [all] ***********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [node03]
ok: [node02]
ok: [node01]
ok: [node04]

TASK [Start nginx] ***************************************************************************************************
changed: [node03]
changed: [node02]
changed: [node04]
changed: [node01]

PLAY RECAP ***********************************************************************************************************
node01                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

#查看http服务是否启动成功
[root@Ansible-Server ansible]# ansible all -m shell -a 'systemctl is-active nginx' 
node03 | CHANGED | rc=0 >>
active
node01 | CHANGED | rc=0 >>
active
node02 | CHANGED | rc=0 >>
active
node04 | CHANGED | rc=0 >>
active
#查看http服务是否开机自启
[root@Ansible-Server ansible]# ansible all -m shell -a 'systemctl is-enabled nginx' 
node03 | CHANGED | rc=0 >>
enabled
node04 | CHANGED | rc=0 >>
enabled
node01 | CHANGED | rc=0 >>
enabled
node02 | CHANGED | rc=0 >>
enabled

ansible 支持幂等性–绝大多数ansible模块支持,命令已经执行成功了,再次执行返回结果不会报错

三、Playbook 实战案例


示例1:写一个剧本: 在webservers主机组中安装httpd服务,并且配置防火墙等等操作

#编辑Playbook文件
[root@Ansible-Server ansible]# vim install_nginx.yaml 
---
- hosts: all
  tasks:
    - name: 1.Insatll nginx
      yum:
        name: nginx
        state: present

    - name: 2.Copy index.html
      copy:
        src: file/index.html
        dest: /usr/share/nginx/html

    - name: 3.Configure nginx.conf
      lineinfile:
        path: /etc/nginx/nginx.conf
        regexp: '        listen       80 default_server;'
        line: '        listen       8080 default_server;'
        state: present
      notify:
        - restart nginx

    - name: 4.Start nginx
      service:
        name: nginx
        state: started
        enabled: yes

    - name: 5.Config firewalld
      firewalld:
        port: 8080/tcp
        permanent: yes
        state: enabled
        immediate: yes

  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

#检查语法
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml --syntax-check

playbook: install_nginx.yaml

#执行Playbook
[root@Ansible-Server ansible]# ansible-playbook install_nginx.yaml 

PLAY [all] ***********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [node04]
ok: [node02]
ok: [node01]
ok: [node03]

TASK [1.Insatll nginx] ***********************************************************************************************
ok: [node02]
ok: [node04]
ok: [node03]
ok: [node01]

TASK [2.Copy index.html] *********************************************************************************************
ok: [node04]
ok: [node03]
ok: [node02]
ok: [node01]

TASK [3.Configure nginx.conf] ****************************************************************************************
ok: [node03]
ok: [node01]
ok: [node04]
ok: [node02]

TASK [4.Start nginx] *************************************************************************************************
ok: [node03]
ok: [node01]
ok: [node02]
ok: [node04]

TASK [5.Config firewalld] ********************************************************************************************
ok: [node04]
ok: [node03]
ok: [node02]
ok: [node01]

PLAY RECAP ***********************************************************************************************************
node01                     : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#测试
[root@Ansible-Server ansible]# for i in {4..7}; do  curl  http://192.168.5.$i:8080; done
hello ansible
hello ansible
hello ansible
hello ansible

示例2:使用ansible安装并配置nfs服务

--->nfs_server     node02:192.168.5.5
--->nfs-client     node03:192.168.5.6

#配置nfs_server
[root@Ansible-Server ansible]# vim nfs_server.yaml
---
- hosts: dev
  tasks:
    - name: 1.Install nfs-utils
      yum:
        name: nfs-utils
        state: present

    - name: 2.Configure nfs server
      copy:
        src: ./file/exports
        dest: /etc/exports
        backup: yes

    - name: 3.Create group www
      group:
        name: www
        gid: 666
        system: yes
        state: present

    - name: 4.Create user www
      user:
        name: www
        group: www
        uid: 666
        system: yes
        state: present
        create_home: no
        shell: /bin/nologin

    - name: 5.Create nfs share directory
      file:
        path: /ansible_data
        owner: www
        group: www
        mode: '0755'
        recurse: yes
        state: directory

    - name: 6.Start nfs server
      systemd:
        name: nfs-server
        state: started
        enabled: yes

    - name: 7.Modify firewall rule
      firewalld:
        service: '{{ item }}'
        permanent: yes
        state: enabled
        immediate: yes
      with_items:
        - nfs
        - rpc-bind
        - mountd
#语法检查
[root@Ansible-Server ansible]# ansible-playbook nfs_server.yaml --syntax-check

playbook: nfs_server.yaml


#配置nfs_client
[root@Ansible-Server ansible]# vim nfs_client.yaml
---
- hosts: test
  tasks:
    - name: 1.Install nfs-utils
      yum:
        name: nfs-utils
        state: present

    - name: 2.Create mount point directory
      file:
        path: /mnt/nfs
        state: directory

    - name: 3.Mount nfs
      mount:
        src: node02:/ansible_data
        path: /mnt/nfs
        fstype: nfs
        state: mounted
#语法检查
[root@Ansible-Server ansible]# ansible-playbook nfs_client.yaml --syntax-check

playbook: nfs_client.yaml


#查看nfs 挂载情况
[root@Ansible-node03 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
devtmpfs              379M     0  379M   0% /dev
tmpfs                 396M     0  396M   0% /dev/shm
tmpfs                 396M  5.7M  391M   2% /run
tmpfs                 396M     0  396M   0% /sys/fs/cgroup
/dev/mapper/cl-root    17G  1.9G   16G  11% /
/dev/sda1             976M  130M  780M  15% /boot
tmpfs                  80M     0   80M   0% /run/user/0
node02:/ansible_data   17G  1.9G   16G  11% /mnt/nfs

示例3:Playbook 多剧本实现

-->node01  192.168.5.4  安装httpd
-->node02  192.168.5.5  安装mariadb

#编辑Playbook 文件
---
- name: Install and Start httpd
  hosts: node01
  tasks:
    - name: 1.install httpd
      yum:
        name: httpd
        state: present

    - name: 2.Start httpd
      service:
        name: httpd
        state: started
        enabled: yes

    - name: 3.Configure firewall
      firewalld:
        service: http
        state: enabled
        immediate: yes
        permanent: yes

- name: Install and start mariadb
  hosts: node02
  tasks:
    - name: 1.Install mariadb
      yum:
        name: mariadb-server
        state: latest

    - name: 2.Start service
      service:
        name: mariadb
        enabled: yes
        state: started

    - name: 3.Configure firewall
      firewalld:
        service: mysql
        state: enabled
        immediate: yes
        permanent: yes

#检查语法
[root@Ansible-Server ansible]# ansible-playbook muti_playbook.yml --syntax-check

playbook: muti_playbook.yml

#执行Playbook
[root@Ansible-Server ansible]# ansible-playbook muti_playbook.yml 

PLAY [Install and Start httpd] *************************************************************************************

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

TASK [1.install httpd] *********************************************************************************************
changed: [node01]

TASK [2.Start httpd] ***********************************************************************************************
changed: [node01]

TASK [3.Configure firewall] ****************************************************************************************
changed: [node01]

PLAY [Install and start mariadb] ***********************************************************************************

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

TASK [1.Install mariadb] *******************************************************************************************
changed: [node02]

TASK [2.Start service] *********************************************************************************************
changed: [node02]

TASK [3.Configure firewall] ****************************************************************************************
changed: [node02]

PLAY RECAP *********************************************************************************************************
node01                     : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  


#检测结果
--node01
[root@Ansible-node01 ~]# systemctl is-active httpd
active
[root@Ansible-node01 ~]# systemctl is-enabled httpd
enabled
[root@Ansible-node01 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources: 
  services: cockpit dhcpv6-client http ssh
  ports: 8080/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
	
--node02
[root@Ansible-node02 ~]# systemctl is-active mysql
active
[root@Ansible-node02 ~]# systemctl is-enabled mysql
enabled
[root@Ansible-node02 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33
  sources: 
  services: cockpit dhcpv6-client mountd mysql nfs rpc-bind ssh
  ports: 8080/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值