playboook简介:
playbook是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色,从根本上讲,所谓tasks是调用ansible的一个module,将多个play组织在一个palybook中,可以让他们联合起来按事先编排的机制唱一台大戏。
playbook的基础组件
hosts和users
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务,hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔的主机组:
remote_user则是用于指定远程主机上执行任务的用户,不过,remote_user也可用于各task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其用于play全局或某任务;此外甚至可以在sudo时使用sudo_user指定sudo时切换的用户
playbook中的相关参数:
(1)Ignore_errors:true:这表示当我们的任务出错时可以使用这一参数忽略错误
如果命令或脚本的退出码不为零,可以使用如下方式代替
(2)tasks:
- name: run this command and ignore the result
shell:/usr/bin/somecommand || /bin/true 假如命令执行错误,我们可以强制让他输出成功。
playbook的简单实例:
我准备了三台主机:
主机 | ip |
---|---|
node2(ansible) | 10.5.100.208 |
node1 | 10.5.100.207 |
node4 | 10.5.100.146 |
(1)进行密钥认证。要求ansible主机登录node1和node4时不要认证。因为我们的ansible在管理主机时基于插件connection plugins连ssh链接被管理主机。
[root@node2 .ssh]# ssh-keygen //生成一对密钥。
[root@node2 .ssh]# ssh-copy-id 10.5.100.146
[root@node2 .ssh]# ssh-copy-id 10.5.100.207
(2)创建一个简单的实例:为我们所管理主机创建用户。
[root@node2 ~]# vim /etc/ansible/hosts //添加我们所需要管理的主机。
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
10.5.100.208
[webserver] []定义主机组,可以将多个主机加到主机组中。
10.5.100.146
10.5.100.207
[dbserver]
10.5.100.146
[root@node2 ~]# mkdir playbook/ 创建一个工作目录
[root@node2 playbook]# vi play.yml
- hosts: webserver
remote_user: root
tasks:
- name: create user18 group
group: name=user18 gid=1005
- name: create user18 user
user: name=user18 uid=1005 group=user18
- hosts: dbserver
remote_user: root
tasks:
- name: copy file to dbserver
copy: src=/etc/fstab dest=/tmp/test
~
[root@node2 playbook]# ansible-playbook play.yml 我们使用ansible-playbook来运行我们的yaml计划文件
[root@node2 playbook]# ansible-playbook play.yml
PLAY [webserver] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [10.5.100.146]
ok: [10.5.100.207]
TASK [create user18 group] **********************************************************************************************************************
changed: [10.5.100.207]
changed: [10.5.100.146]
TASK [create user18 user] ***********************************************************************************************************************
changed: [10.5.100.207]
changed: [10.5.100.146]
PLAY [dbserver] *********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [10.5.100.146]
TASK [copy file to dbserver] ********************************************************************************************************************
changed: [10.5.100.146]
PLAY RECAP **************************************************************************************************************************************
10.5.100.146 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.5.100.207 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(2.1)创建简单实例,在playbook中应用一些变量;
[root@node2 ~]# ansible webserver -m setup 我们通过setup查询被管理主机的相关信息。
10.5.100.207 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.20.8",
"10.5.100.207"
],
[root@node2 ~]# vi /etc/ansible/hosts
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
10.5.100.208
[webserver]
10.5.100.146 testvar="100.146" 我们可以在主机组中为主机定义变量。
10.5.100.207
[dbserver]
10.5.100.146
[root@node2 playbook]# vi test.yml
- hosts: webserver
remote_user: root
tasks:
- name: copy file
copy: content="{{ ansible_all_ipv4_addresses }},{{ testvar }}" dest=/tmp/vars.ans
~
[root@node2 playbook]# ansible-playbook test.yml
PLAY [webserver] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [10.5.100.146]
ok: [10.5.100.207]
TASK [copy file] ********************************************************************************************************************************
ok: [10.5.100.207]
ok: [10.5.100.146]
PLAY RECAP **************************************************************************************************************************************
10.5.100.146 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.5.100.207 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node2 playbook]#
[root@node2 playbook]# ansible webserver -m shell -a 'cat /tmp/vars.ans'
10.5.100.207 | CHANGED | rc=0 >>
([u'192.168.20.8', u'10.5.100.207'], 100.207)
10.5.100.146 | CHANGED | rc=0 >>
([u'10.5.100.146'], 100.146)
(2.2):创建简单示例,playbook中条件测试。when的使用以及vars变量的使用
[root@node2 playbook]# vi cond.yml
- hosts: all 在这里我虽然指明的所有主机
remote_user: root
vars:
- username: user20
tasks:
- name: create {{ username }} user
user: name={{ username }} state=present
when: ansible_fqdn == "node4.yan.com" 这个语句是当主机域名为node4.yan.com才执行tasks任务。
~
[root@node2 playbook]# ansible-playbook cond.yml
PLAY [all] **************************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [10.5.100.146]
ok: [10.5.100.208]
ok: [10.5.100.207]
TASK [create user20 user] ***********************************************************************************************************************
skipping: [10.5.100.208]
skipping: [10.5.100.207]
changed: [10.5.100.146]
PLAY RECAP **************************************************************************************************************************************
10.5.100.146 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.5.100.207 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
10.5.100.208 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@node2 playbook]#
(2.3)在playbook中我们可以定义循环列表:with_items
例如:迭代
所谓迭代:重复同类task时使用。当有需要重复执行的任务时,可以使用迭代级制,其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可
[root@node2 playbook]# vi item1.yml
- hosts: webserver
remote_user: root
tasks:
- name: add user
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
[root@node2 playbook]# ansible-playbook item1.yml
PLAY [webserver] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [10.5.100.146]
ok: [10.5.100.207]
TASK [add user] *********************************************************************************************************************************
changed: [10.5.100.207] => (item=testuser1)
changed: [10.5.100.207] => (item=testuser2)
changed: [10.5.100.146] => (item=testuser1)
changed: [10.5.100.146] => (item=testuser2)
PLAY RECAP **************************************************************************************************************************************
10.5.100.146 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.5.100.207 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
另外一种定义方式:字典的定义格式
[root@node2 playbook]# vi item.yml
- hosts: webserver
remote_user: root
tasks:
- name: add serveral users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
~
(2.4)playbook中tags标签和handlers触发器的使用。
[root@node2 playbook]# vi apache.yml
- hosts: webserver
remote_user: root
tasks:
vars:
- package: httpd
- service: httpd
- name: install httpd package
yum: name=[[ package ]] state=latest
- name: install configuration file for httpd
template: src=/root/template/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf tem
tags: tags定义标签,可以我们在管理主机时指明要运行的标签是什么。
-conf
notify: 定义notifiy表示当我们的上述配置文件发生改变时,会触发handlers
- restart httpd
- name: start httpd serivce
service: enabled=true name=[[ service ]] state=started
handlers: 这是处理器,当上述文件发生改变时,触发notify执行handlers;
- name: restart httpd
service: name=httpd state=restarted
[root@node2 playbook]# ansible-playbook apache.yml --tags="conf" 有tags标签我们可以指定带有tags标签的计划任务。
(3)如何定义role,ansible自1.2版本引入的新特性,用于层次性,结构化组织playbook,roles能够根据层次结构自动装载配置文件,task以及handlers等,要使用roles只需要在playbook中使用include指令即可,简单来讲,roles就是通过分别将变量,文件,任务,模板及处理器放置于单独的目录中,并可以便捷地include他们的一种机制,角色一般用于基于主机构建服务的场景中。
(3.1)定义role
[root@node2 ~]# mkdir -pv roles/{webserver,dbserver}/{tasks,files,templates,meta,handlers,vars}
[root@node2 ~]# tree ansible-playbooks/
ansible-playbooks/
├── roles
│ ├── dbserver
│ │ ├── files
│ │ ├── handlers
│ │ ├── meta
│ │ ├── tasks
│ │ ├── templates
│ │ └── vars
│ └── webserver
│ ├── files
│ │ └── httpd.conf
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
└── site.yml
15 directories, 4 files
[root@node2 ~]#
[root@node2 ~]# cd ansible-playbooks/roles/ 我们定义两个角色,一个为webserver,一个为dbserver
[root@node2 roles]# ls
dbserver webserver
[root@node2 roles]#
[root@node2 webserver]# ls
files handlers meta tasks templates vars
[root@node2 webserver]# cd files/ 先为webserver准备一个文件
[root@node2 files]# ls
httpd.conf
[root@node2 webserver]# cd tasks/ 为webserver定义任务,成为webserver要执行什么任务。
[root@node2 tasks]# ls
main.yml
[root@node2 tasks]# vim main.yml
- name: install httpd package
yum: name=httpd
- name: install configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags:
- conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
[root@node2 webserver]# cd handlers/
[root@node2 handlers]# ls
main.yml
[root@node2 handlers]# vi main.yml
- name: restart httpd
service: name=httpd state=started
~
我们已经定义好成为webserver的角色需要的所有就绪工作。现在我们就可以定义一个yml文件。
[root@node2 ~]# cd ansible-playbooks/
[root@node2 ansible-playbooks]# ls
roles site.yml
[root@node2 ansible-playbooks]# vi site.yml
- hosts: 10.5.100.207 在我们这里面只需定义那台主机角色为什么就ok了。
remote_user: root
roles:
- webserver
- hosts: 10.5.100.146
remote_user: root
roles:
- dbserver
总结:playbook可以将我们需要安装的软件包,及一些工具时按特定的步骤组合起来,写到一个yml文件中来依次执行,
而role(角色)可以使我们不同的主机分别扮演不同的角色。