005.Ansible的palybook简单使用
一 Ansible Playbook简介
ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写。playbook命令根据自上而下的顺序依次执行。同时,playbook开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。
playbook通过ansible-playbook命令使用,它的参数和ansible命令类似,如参数-k(–ask-pass) 和 -K (–ask-sudo) 来询问ssh密码和sudo密码,-u指定用户,这些指令也可以通过规定的单元写在playbook 。
ansible-playbook的简单使用方法: ansible-playbook example-play.yml 。
二 Playbook基本语法
下面是一个简单的ansible-playbook示例,可以了解其构成:
# cat user.yml - name: create user hosts: all remote_user: root gather_facts: false vars: user:"test" tasks: - name: create user user: name="{{ user }}"
配置项说明:
- name:对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值
- hosts:指定对哪些被管理机进行操作;
- remote_user:指定在远程被管理机上执行操作时使用什么用户,如不指定,则使用ansible.cfg中配置的remote_user
- gather_facts:指定在执行任务之前,是否先执行setup模块获取主机相关信息,如未用到,可不指定
- vars:定义后续任务中会使用到的变量,如未用到,可不指定
- tasks:定义具体需要执行的任务name:对任务的描述,在执行过程中会打印出来。
- user:指定调用user模块;
- name:user模块里的一个参数,用于指定创建的用户名称
同样,如果想实现把这个新增的用户删除,只需将该playbook文件的最后一行替换为如下行再执行相应的playbook即可:
user: name="{{ user }}" state=absent remove=yes
三 playbook组成
3.1 palybook简单演示
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes
[root@node1 ansible]# ansible-playbook nginx_config.yml
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* changed: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** changed: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** changed: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** changed: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=9 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看192.168.132.133
[root@node3 ~]# rpm -qa |grep epel-release epel-release-7-11.noarch [root@node3 ~]# rpm -qa |grep nginx nginx-mod-http-xslt-filter-1.16.1-1.el7.x86_64 nginx-all-modules-1.16.1-1.el7.noarch nginx-mod-mail-1.16.1-1.el7.x86_64 nginx-mod-http-image-filter-1.16.1-1.el7.x86_64 nginx-mod-stream-1.16.1-1.el7.x86_64 nginx-filesystem-1.16.1-1.el7.noarch nginx-mod-http-perl-1.16.1-1.el7.x86_64 nginx-1.16.1-1.el7.x86_64 [root@node3 ~]# systemctl status nginx ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2020-04-29 14:06:10 CST; 2min 25s ago [root@node3 ~]# systemctl is-enabled nginx
enabled
访问
3.2 yml规则
yml文件它的基本语法规则如下。
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#
表示注释,从这个字符一直到行尾,都会被解析器忽略。
YAML 支持的数据结构有三种。
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
ansible-playbook常用选项
3.3 ansible其他用法
1 打印详细信息
- -v:打印任务运行结果
- -vv:打印任务运行结果以及任务的配置信息
- -vvv:包含了远程连接的一些信息
- -vvvv:Adds extra verbosity options to the connection plug-ins,including the users being used in the managed hosts to execute scripts, and what scripts have been executed
[root@node1 ansible]# ansible-playbook nginx_config.yml -v
2. 校验playbook语法
[root@node1 ansible]# ansible-playbook nginx_config.yml --syntax-check
playbook: nginx_config.yml
3. 测试运行playbook
通过-C选项可以测试playbook的执行情况,但不会真的执行:
[root@node1 ansible]# ansible-playbook -C nginx_config.yml
4 Multiple Plays
# This is a simple playbook with two plays - name: first play hosts: web.example.com tasks: - name: first task yum: name: httpd status: present - name: second task service: name: httpd state: started - name: second play hosts: db.example.com tasks: - name: first task yum: name: mariadb-server status: present - name: second task service: name: mariadb state: started
四 playbook的结构说明
playbook是由一个或多个"play"组成的列表。play的主要功能就是对一组主机应用play中定义好的task。从根本上来讲一个task就是对ansible一个module的调用。而将多个play按照一定的顺序组织到一个playbook中,我们称之为编排。
playbook主要有以下四部分构成:
- Target section: 用于定义将要执行playbook的远程主机组及远程主机组上的用户,还包括定义通过什么样的方式连接远程主机(默认ssh)
- Variable section: 定义playbook运行时需要使用的变量
- Task section: 定义将要在远程主机上执行的任务列表
- Handler section: 定义task执行完成以后需要调用的任务
4.1 Target section
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
Playbook中的远程用户
playbook中的远程用户和ad-hoc中的使用没有区别,默认不定义,则直接使用ansible.cfg配置中的用户相关的配置。也可在playbook中定义如下:
- name: /etc/hosts is up to date hosts: datacenter remote_user: automation become: yes become_mothod: sudo become_user: root tasks: - name: server.example.com in /etc/hosts lineinfile: path: /etc/hosts line: '192.168.0.200 server.exmaple.com server' state: present
Playbook中的hosts
playbook中的hosts即inentory中的定义主机与主机组,在《Ansible Inventory》中我们讲到了如何选择主机与主机组,在这里也完全适用。
4.2 Variable section
定义playbook运行时需要使用的变量
- name : test vars hosts: node2 remote_user: ansible become_user: root become_method: sudo vars: user: name: "user1" address: "IPaddr" tasks: - name: "print" debug: msg: "{{ user }}"
执行
PLAY [test vars] ****************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************ ok: [node2] TASK [print] ********************************************************************************************************************************** ok: [node2] => { "msg": { "address": "IPaddr", "name": "user1" } } PLAY RECAP ************************************************************************************************************************************ node2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.3 Task section
play的主体部分是任务列表。
任务列表中的各任务按次序逐个在hosts中指定的所有主机上执行,在所有主机上完成第一个任务后再开始第二个。在自上而下运行某playbook时,如果中途发生错误,则整个playbook会停止执行,由于playbook的幂等性,playbook可以被反复执行,所以即使发生了错误,在修复错误后,再执行一次即可。
定义task可以使用action: module options
或module: options
的格式,推荐使用后者以实现向后兼容。
tasks: - name: make sure apache is running service: name: httpd state: started - name: disable selinux command: /sbin/setenforce 0
如果命令或脚本的退出码不为零可以使用如下方式替代:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
可以使用ignore_errors来忽略错误信息:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
4.4 Handler section
-
在Ansible Playbook中,handler事实上也是个task,只不过这个task默认并不执行,只有在被触发时才执行。
-
handler通过notify来监视某个或者某几个task,一旦task执行结果发生变化,则触发handler,执行相应操作。
-
handler会在所有的play都执行完毕之后才会执行,这样可以避免当handler监视的多个task执行结果都发生了变化之后而导致handler的重复执行(handler只需要在最后执行一次即可)。
在notify中定义内容一定要和tasks中定义的 - name 内容一样,这样才能达到触发的效果,否则会不生效。
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present notify: restart nginx - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes handlers: - name: restart nginx systemd: name: nginx daemon_reload: yes state: restarted
执行
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* ok: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** ok: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** ok: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** ok: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
没有触发,试音并没有change
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent notify: restart nginx - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes handlers: - name: restart nginx systemd: name: nginx daemon_reload: yes state: restarted
执行
[root@node1 ansible]# ansible-playbook nginx_config.yml
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* ok: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** ok: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** ok: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** ok: [192.168.132.133] RUNNING HANDLER [restart nginx] *************************************************************************************************************** changed: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=10 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
触发执行
一个任务可以触发多个handlers
notify: - restart nginx - restart redis
默认情况下,在一个play中,只要有task执行失败,则play终止,即使是与handler关联的task在失败的task之前运行成功了,handler也不会被执行。如果希望在这种情况下handler仍然能够执行,则需要使用如下配置:
- hosts: all force_handlers: yes tasks: - name: a task which always notifies its handler command: /bin/true notify: restart the database - name: a task which fails because the package doesn't exist yum: name: notapkg state: latest handlers: - name: restart the database service: name: mariadb
如果与handler关联的task还未执行,在其前的task已经失败,整个play终止,则handler未被触发,也不会执行
博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!
---------------------------------------------------------------------------
个性签名:我以为我很颓废,今天我才知道,原来我早报废了。
如果觉得本篇文章最您有帮助,欢迎转载,且在文章页面明显位置给出原文链接!记得在右下角点个“推荐”,博主在此感谢!