PlayBook即"剧本","兵书"之意,PlayBook是由以下部分组成的 play(host): 定义的是主机的角色。(主角还是配角) Book(task): 定义的是具体执行的任务。(角色的台词和动作) playbook: 由一个或多个play(角色)组成,一个play(角色)可以包含多个task(台词,动作)。 简单理解为: 使用很多不同的模块指定主机完成一系列动作 在Ansible中"剧本文件"是以yml结尾的文件。 在SaltStack中"剧本文件"是以sls结尾的文件。 但是语法,使用的都是yaml语法
playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。
[root@m01 ~]# vim touch.yml - hosts: web_group #定义要执行动作的主机或主机组 remote_user: root #定义远端操作的用户 vars: #开始定义变量 file_name: lhd #变量:变量的值 tasks: #指定主机的动作 - name: Touch New File #动作的注释 shell: touch /tmp/{{ file_name }} #使用shell模块执行动作 #模拟执行 [root@m01 ~]# ansible-playbook -C touch.yml #验证语法 [root@m01 ~]# ansible-playbook --syntax-check touch.yml #注意:只能验证语法,验证不了逻辑
格式
ansible-playbook <filename.yml> ... [options]Copy to clipboardErrorCopied
常见选项
--syntax-check #语法检查 -C --check #只检测可能会发生的改变,但不真正执行操作 --list-hosts #列出运行任务的主机 --list-tags #列出tag --list-tasks #列出task --tags # 只run 一个tag --skip-tags # 跳过某个task --limit 主机列表 #只针对主机列表中的特定主机执行 -v -vv -vvv #显示过程Copy to clipboardErrorCopied
特点 | PlayBook | ad-hoc |
---|---|---|
完整性 | √ | ✘ |
持久性 | √ | ✘ |
执行效率 | 低 | 高 |
变量 | 支持 | 不支持 |
耦合度 | 低 | 高 |
1.PlayBook功能比ad-hoc更全,是对ad-hoc的一种编排. 2.PlayBook能很好的控制先后执行顺序,以及依赖关系. 3.PlayBook语法展现更加的直观. 4.playbook可以持久使用,ad-hoc无法持久使用.
playbook使用yml标记语言,这是一种标记语言,这种标记语言在文件的最开始需要使用三个“-”来说明文件开始,然后使用缩进来说明代码块的范围。下面通过一个简易的实例,来说明playbook的语法。
YAML 官方网站:http://www.yaml.org
语法 | 描述 |
---|---|
缩进 | YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用TAB |
冒号 | 以冒号结尾的除外,其他所有冒号后面所有必须有空格 |
短横线 | 表示列表项,使用一个短横杠加一个空格,多个项使用同样的缩进级别作为同一列表 |
[root@m01 ~]# vim yufa.yaml --- #标记文件的开始 - hosts: webservers #指定该playbook在哪个服务器上执行 vars: #表示下面是定义的变量, http_port: 80 #变量的形式,key: value,这里http_port是变量名,80是值 max_clients: 200 remote_user: root #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。 tasks: #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。 - name: ensure apache is at the latest version #指定该任务的名称。 yum: pkg=httpd state=latest #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。 - name: write the apache config file #每个task之间可以使用空行来做区分。 template: src=/srv/httpd.j2 dest=/etc/httpd.conf #需要说明的是缩进的意义和python中缩进的意义是一样,是来区分代码块的。 # 检查语法 [root@m01 ~]# ansible-playbook -C yufa.yaml
YAML 支持以下常用几种数据类型:
可以用工具互相转换,参考网站:
https://www.json2yaml.com/
http://www.bejson.com/json/json2yaml/
一个playbook 中由列表组成,其中所用到的常见组件类型如下:
Hosts 执行的远程主机列表
Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中。
one.example.com one.example.com:two.example.com 192.168.1.50 192.168.1.* public:private #或者,两个组的并集 public:&private #与,两个组的交集 public:!private #在public组,但不在private组Copy to clipboardErrorCopied
- 案例
- hosts: public:!private
Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task
Variables 内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。触发器使用注意事项:
1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。
2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。
3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。
4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。
5.不能使用handlers替代tasks
[root@m01 ~]# cat nginx.yml - hosts: nginx remote_user: root gather_facts: no tasks: - name: Install httpd yum: name=httpd state=present - name: Install configure file copy: src=httpd.conf dest=/etc/httpd/conf/ notify: restart httpd - name: ensure apache is running service: name=httpd state=started enabled=yes handlers: - name: restart httpd service: name=httpd state=restarted
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件。
打标签的方式:
1.对一个task打一个标签
2.对一个task打多个标签
3.对多个task打一个标签- hosts: public remote_user: root gather_facts: no tasks: - name: Install httpd yum: name=httpd state=present tags: install - name: Install configure file copy: src=httpd.conf dest=/etc/httpd/conf/ notify: restart httpd - name: ensure apache is running service: name=httpd state=started enabled=yes handlers: - name: restart httpd service: name=httpd state=restarted ansible-playbook –t install httpd.yml
Ansible facts 是在被管理主机上通过Ansible自动采集发现的变量。facts包含每台特定的主机信息。比如:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。 1.通过facts缓存检查CPU,来生成对应的nginx配置文件 2.通过facts缓存检查主机名,生成不同的redis配置文件 3.通过facts缓存检索物理机的内存大小来生成不通的mysql配置文件 综上所述的Ansible facts类似于saltstack中的grains对于做自动化的小伙伴是非常有用滴。 #关闭facts缓存 [root@m01 ~]# vim facts.yml - hosts: web_group gather_facts: no #关闭信息采集 tasks: #如果不使用内置变量,可以关闭会提高剧本的执行速度,如果使用内置变量,那么不能关闭facts缓存
remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。
- hosts: public remote_user: root gather_facts: no #不收集对应主机的信息,这样运行会快点。 tasks: - name: test connection ping: remote_user: dan sudo: yes #默认sudo为root sudo_user: xiaomian #sudo为xiaomian
playbook的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task。
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
如果未提供name,则action的结果将用于输出
--- - hosts: public remote_user: root gather_facts: no tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started enabled=yes
[root@m01 ~]# cat mysql.yaml - hosts: web remote_user: root gather_facts: no tasks: - name: Create Group group: name=mysql system=yes gid=666 - name: Create User user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=666 home=/home/mysql create_home=no
[root@m01 ~]# cat nginx.yaml - hosts: web remote_user: root gather_facts: no tasks: - name: Create Group group: name=nginx system=yes gid=666 - name: Create User user: name=nginx shell=/sbin/nologin system=yes group=nginx uid=666 home=/home/nginx create_home=no - name: Install nginx yum: name=nginx state=present - name: Start Nginx service: name=nginx state=started enabled=yes
[root@m01 ~]# cat httpd.yaml # 安装httpd - hosts: public remote_user: root gather_facts: no tasks: - name: Create Group group: name=www system=yes gid=777 - name: Create User user: name=www shell=/sbin/nologin system=yes group=www uid=777 home=/home/www create_home=no - name: Install nginx yum: name=httpd state=present - name: Start Nginx service: name=httpd state=started enabled=yes # 卸载httpd - hosts: public remote_user: root tasks: - name: remove httpd package yum: name=httpd state=absent - name: remove apache user user: name=www state=absent - name: remove config file file: name=/etc/httpd state=absent - name: remove web html file: name=/var/html/ state=absent
#1.安装ansible [root@m01 ~]# yum install -y ansible #2.配置ansible [root@m01 ~]# vim /etc/ansible/ansible.cfg host_key_checking = False #3.配置主机清单 [root@m01 ~]# cat /etc/ansible/hosts [web_group] web01 ansible_ssh_pass='1' web02 ansible_ssh_pass='1' [nfs_server] nfs ansible_ssh_pass='1' [rsync_server] backup ansible_ssh_pass='1' [lb_server] lb01 ansible_ssh_pass='1' lb02 ansible_ssh_pass='1' [db_server] db01 ansible_ssh_pass='1' [nginx:children] web_group lb_server #4.配置hosts [root@m01 ~]# vim /etc/hosts 172.16.1.5 lb01 172.16.1.6 lb02 172.16.1.7 web01 172.16.1.8 web02 172.16.1.31 nfs 172.16.1.41 backup 172.16.1.51 db01 172.16.1.61 m01 #5.确定配置完能通 [root@m01 ~]# ansible all -m ping #6.创建统一目录 [root@m01 ~]# mkdir /dan [root@m01 ~]# cd /dan/
#官方源方式 1.配置官方源 2.推送官方源 copy 3.安装nginx yum
#1.准备nginx的官方文档 并下载nginx [root@m01 ~]# cat /etc/yum.repos.d/nginx.repo [nginx-stable] name = nginx stable repo baseurl = http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck = 1 enabled = 1 gpgkey = https://nginx.org/keys/nginx_signing.key module_hotfixes = true [nginx-mainline] name = nginx mainline repo baseurl = http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck = 1 enabled = 0 gpgkey = https://nginx.org/keys/nginx_signing.key module_hotfixes = true [nginx.repo] baseurl = http://nginx.org/packages/centos/7/$basearch/ enabled = 1 gpgcheck = 1 name = nginx stable repo #2.准备nginx配置文件 ,比创建id [root@m01 ~]# vim /etc/nginx/nginx.conf user www; [root@m01 ~]# groupadd www -g 666 [root@m01 ~]# useradd www -u666 -g666 #3.准备php的安装包,解压并安装 [root@m01 ~] mkdir package [root@m01 package]# rz [root@m01 package]# ll -rw-r--r-- 1 root root 19889622 Apr 28 10:39 php.tar.gz #4.准备php配置文件 [root@m01 dan]# mkdir conf [root@m01 dan]# mv /etc/php.ini conf/ [root@m01 dan]# cp /etc/php-fpm.d/www.conf conf/ [root@m01 dan]# vim conf/php.ini upload_max_filesize = 200M post_max_size = 300M [root@m01 dan]# vim conf/www.conf user = www group = www #5.准备discuze包 [root@m01 package]# ls Discuz-DiscuzX-master.zip Discuz-DiscuzX-master.zip [root@m01 package]# mkdir /code [root@m01 package]# unzip -d /code/Discuz-DiscuzX-master.zip #6.准备discuz配置文件 [root@m01 dan]# vim conf/discuz.conf server { listen 80; server_name discuz.com; root /code/discuz; index index.php; location ~* \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
[root@m01 dan]# cat base.yml --- - hosts: all tasks: - name: stop firewalld systemd: name=firewalld state=stopped enabled=no - name: stop selinux selinux: state=disabled - name: create www gruop group: name=www gid=666 state=present - name: create www user user: name=www uid=666 group=www shell=/bin/bash create_home=false state=present - hosts: nginx tasks: - name: scp nginx.repo copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/nginx.repo - name: install nginx yum: name=nginx state=present - name: cfg nginx server copy: src=/etc/nginx/nginx.conf dest=/etc/nginx - name: start nginx server systemd: name=nginx state=started enabled=yes - hosts: web_group tasks: - name: tar php unarchive: src=/package/php.tar.gz dest=/opt/ - name: install php server shell: "yum localinstall -y /opt/*.rpm" - name: cfg php copy: src=/dan/conf/php.ini dest=/etc/ - name: sfg php copy: src=/dan/conf/www.conf dest=/etc/php-fpm.d/ - name: start php systemd: name=php-fpm state=started - name: create code dir file: path=/code owner=www group=www state=directoy recurse=yes - name: cfg nginx discuz copy: src=/dan/conf/discuz.conf dest=/etc/nginx/conf.d/ - name: restart nginx systemd: name=nginx state=restarted - hosts: db01 tasks: - name: install db yum: name=mariadb-server state=present - name: install mysql-py yum: name=MySQL-python state=present - name: start db systemd: name=mariadb state=stared enabled=yes - name: create discuz database mysql_db: name=discuz state=present - name: create discuz user mysql_user: name="discuz" host="172.16.1.%" password="111" priv='*.*:ALL' state=present