5、playbook

  1. > playbook是由一个或多个"play"组成的列表
  2. > play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。
  3. Task实际是调用ansible的一个module,将多个play组织在一个playbook中,
  4. 即可以让它们联合起来,按事先编排的机制执行预定义的动作
  5. > Playbook采用YAML语言编写

5.1、playbook图解

image.png

  1. 用户通过ansible命令直接调用yml语言写好的playbook,playbook由多条play组成
  2. 每条play都有一个任务(task)相对应的操作,然后调用模块modules,应用在主机清单上,通过ssh远程连接
  3. 从而控制远程主机或者网络设备

5.2、YAML介绍

  1. YAML是一个可读性高的用来表达资料序列的格式。
  2. YAML参考了其他多种语言,包括:XMLC语言、PythonPerl以及电子邮件格式RFC2822等。
  3. Clark Evans2001年在首次发表了这种语言,另外Ingy döt NetOren Ben-Kiki也是这语言的共同设计者
  4. YAML Ain't Markup Language,即YAML不是XML。
  5. 不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)
  6. 特性
  7. YAML的可读性好
  8. YAML和脚本语言的交互性好
  9. YAML使用实现语言的数据类型
  10. YAML有一个一致的信息模型
  11. YAML易于实现
  12. YAML可以基于流来处理
  13. YAML表达能力强,扩展性好
  14. 更多的内容及规范参见:http://www.yaml.org

5.2.1、YAML语法简介

  1. > 在单一档案中,可用连续三个连字号(——)区分多个档案。
  2. 另外,还有选择性的连续三个点号( ... )用来表示档案结尾
  3. > 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  4. > 使用#号注释代码
  5. > 缩进必须是统一的,不能空格和tab混用
  6. > 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
  7. > YAML文件内容是区别大小写的,k/v的值均需大小写敏感
  8. > 多个k/v可同行写也可换行写,同行使用:分隔
  9. > v可是个字符串,也可是另一个列表[]
  10. > 一个完整的代码块功能需最少元素需包括 name task
  11. > 一个name只能包括一个task
  12. > YAML文件扩展名通常为ymlyaml
  1. List:列表,其所有元素均使用“-”打头
  2. 列表代表同一类型的元素
  3. 示例:
  4. # A list of tasty fruits
  5. - Apple
  6. - Orange
  7. - Strawberry
  8. - Mango
  9. Dictionary:字典,通常由多个keyvalue构成 键值对
  10. 示例:
  11. ---
  12. # An employee record
  13. name: Example Developer
  14. job: Developer
  15. skill: Elite
  16. 也可以将key:value放置于{}中进行表示,用,分隔多个key:value
  17. 示例:
  18. ---
  19. # An employee record
  20. {name: Example Developer, job: Developer, skill: Elite} 有空格

5.2.2、YAML语法

  1. YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。
  2. 其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔
  3. 示例
  4. name: John Smith
  5. age: 41
  6. gender: Male
  7. spouse:
  8. name: Jane Smith
  9. age: 37
  10. gender: Female
  11. children:
  12. - name: Jimmy Smith
  13. age: 17
  14. gender: Male
  15. - name: Jenny Smith
  16. age 13
  17. gender: Female

5.2.3、三种常见的数据交换格式

image.png

5.3、playbook核心元素

  1. Hosts 执行的远程主机列表(应用在哪些主机上)
  2. Tasks 任务集
  3. Variables 内置变量或自定义变量在playbook中调用
  4. Templates模板 可替换模板文件中的变量并实现一些简单逻辑的文件
  5. Handlersnotify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  6. tags标签 指定某条任务执行,用于选择运行playbook中的部分代码。
  7. ansible具有幂等性,因此会自动跳过没有变化的部分,
  8. 即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。
  9. 此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
  10. ansible-playbook -t tagsname useradd.yml

5.4、playbook基础组件

  1. Hosts
  2. > playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。
  3. hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
  4. > 可以是如下形式:
  5. one.example.com
  6. one.example.com:two.example.com
  7. 192.168.1.50
  8. 192.168.1.*
  9. > Websrvs:dbsrvs 或者,两个组的并集
  10. > Websrvs:&dbsrvs 与,两个组的交集
  11. > webservers:!phoenix websrvs组,但不在dbsrvs
  12. 示例: - hosts: websrvsdbsrvs
  13. remote_user:
  14. 可用于Hosttask中。
  15. 也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;
  16. 此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
  17. - hosts: websrvs
  18. remote_user: root (可省略,默认为root) root身份连接
  19. tasks: 指定任务
  20. - name: test connection
  21. ping:
  22. remote_user: magedu
  23. sudo: yes 默认sudoroot
  24. sudo_user:wang sudowang
  25. task列表和action
  26. 任务列表task:由多个动作,多个任务组合起来的,每个任务都调用的模块,一个模块一个模块执行
  27. 1> play的主体部分是task listtask list中的各任务按次序逐个在hosts中指定的所有主机上执行,
  28. 即在所有主机上完成第一个任务后,再开始第二个任务
  29. 2> task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。
  30. 模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
  31. 3> 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
  32. 如果未提供name,则action的结果将用于输出
  1. tasks:任务列表
  2. 两种格式:
  3. (1) action: module arguments
  4. (2) module: arguments 建议使用 模块: 参数
  5. 注意:shellcommand模块后面跟命令,而非key=value
  6. 某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers
  7. 任务可以通过"tags"打标签,可在ansible-playbook命令上使用-t指定进行调用
  8. 示例:
  9. tasks:
  10. - name: disable selinux 描述
  11. command: /sbin/setenforce 0 模块名: 模块对应的参数
  1. 如果命令或脚本的退出码不为零,可以使用如下方式替代
  2. tasks:
  3. - name: run this command and ignore the result
  4. shell: /usr/bin/somecommand || /bin/true
  5. 转错为正 如果命令失败则执行 true
  6. 或者使用ignore_errors来忽略错误信息
  7. tasks:
  8. - name: run this command and ignore the result
  9. shell: /usr/bin/somecommand
  10. ignore_errors: True 忽略错误

5.5、playbook命令

  1. 运行playbook的方式
  2. ansible-playbook <filename.yml> ... [options]
  3. 常见选项
  4. --check -C 只检测可能会发生的改变,但不真正执行操作
  5. (只检查语法,如果执行过程中出现问题,-C无法检测出来)
  6. (执行playbook生成的文件不存在,后面的程序如果依赖这些文件,也会导致检测失败)
  7. --list-hosts 列出运行任务的主机
  8. --list-tags 列出tag (列出标签)
  9. --list-tasks 列出task (列出任务)
  10. --limit 主机列表 只针对主机列表中的主机执行
  11. -v -vv -vvv 显示过程
  12. 示例
  13. ansible-playbook hello.yml --check 只检测
  14. ansible-playbook hello.yml --list-hosts 显示运行任务的主机
  15. ansible-playbook hello.yml --limit websrvs 限制主机

5.6、Playbook VS ShellScripts

安装httpd

  1. SHELL脚本
  2. #!/bin/bash
  3. # 安装Apache
  4. yum install --quiet -y httpd
  5. # 复制配置文件
  6. cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
  7. cp/tmp/vhosts.conf /etc/httpd/conf.d/
  8. # 启动Apache,并设置开机启动
  9. service httpd start
  10. chkconfig httpd on
  1. Playbook定义
  2. ---
  3. - hosts: all
  4. remote_user: root
  5. tasks:
  6. - name: "安装Apache"
  7. yum: name=httpd yum模块:安装httpd
  8. - name: "复制配置文件"
  9. copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/ copy模块: 拷贝文件
  10. - name: "复制配置文件"
  11. copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
  12. - name: "启动Apache,并设置开机启动"
  13. service: name=httpd state=started enabled=yes service模块: 启动服务

5.7、Playbook 示例

5.7.1、创建用户

  1. 示例:sysuser.yml
  2. ---
  3. - hosts: all
  4. remote_user: root
  5. tasks:
  6. - name: create mysql user
  7. user: name=mysql system=yes uid=36
  8. - name: create a group
  9. group: name=httpd system=yes

5.7.2、安装httpd服务

  1. 示例:httpd.yml
  2. - hosts: websrvs
  3. remote_user: root
  4. tasks:
  5. - name: Install httpd
  6. yum: name=httpd state=present
  7. - name: Install configure file
  8. copy: src=files/httpd.conf dest=/etc/httpd/conf/
  9. - name: start service
  10. service: name=httpd state=started enabled=yes

5.7.3、 安装nginx服务

  1. 示例 nginx.yml
  2. - hosts: all
  3. remote_user: root
  4. tasks:
  5. - name: add group nginx
  6. user: name=nginx state=present
  7. - name: add user nginx
  8. user: name=nginx state=present group=nginx
  9. - name: Install Nginx
  10. yum: name=nginx state=present
  11. - name: Start Nginx
  12. service: name=nginx state=started enabled=yes

5.8、handlers和notify

5.8.1、handlers和notify结合使用触发条件

  1. Handlers 实际上就是一个触发器
  2. task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作
  3. Notifyaction可用于在每个play的最后被触发,
  4. 这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。
  5. notify中列出的操作称为handler,也即notify中调用handler中定义的操作

5.8.2、Playbook中handlers使用

  1. - hosts: websrvs
  2. remote_user: root
  3. tasks:
  4. - name: Install httpd
  5. yum: name=httpd state=present
  6. - name: Install configure file
  7. copy: src=files/httpd.conf dest=/etc/httpd/conf/
  8. notify: restart httpd
  9. - name: ensure apache is running
  10. service: name=httpd state=started enabled=yes
  11. handlers:
  12. - name: restart httpd
  13. service: name=httpd state=restarted
  1. - hosts: webnodes
  2. vars:
  3. http_port: 80
  4. max_clients: 256
  5. remote_user: root
  6. tasks:
  7. - name: ensure apache is at the latest version
  8. yum: name=httpd state=latest
  9. - name: ensure apache is running
  10. service: name=httpd state=started
  11. - name: Install configure file
  12. copy: src=files/httpd.conf dest=/etc/httpd/conf/
  13. notify: restart httpd
  14. handlers:
  15. - name: restart httpd
  16. service: name=httpd state=restarted
  1. - hosts: websrvs
  2. remote_user: root
  3. tasks:
  4. - name: add group nginx
  5. tags: user
  6. user: name=nginx state=present
  7. - name: add user nginx
  8. user: name=nginx state=present group=nginx
  9. - name: Install Nginx
  10. yum: name=nginx state=present
  11. - name: config
  12. copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
  13. notify:
  14. - Restart Nginx
  15. - Check Nginx Process
  16. handlers:
  17. - name: Restart Nginx
  18. service: name=nginx state=restarted enabled=yes
  19. - name: Check Nginx process
  20. shell: killall -0 nginx > /tmp/nginx.log

5.9、Playbook中tags使用

  1. tage: 添加标签
  2. 可以指定某一个任务添加一个标签,添加标签以后,想执行某个动作可以做出挑选来执行
  3. 多个动作可以使用同一个标签
  4. 示例:httpd.yml
  5. - hosts: websrvs
  6. remote_user: root
  7. tasks:
  8. - name: Install httpd
  9. yum: name=httpd state=present
  10. tage: install
  11. - name: Install configure file
  12. copy: src=files/httpd.conf dest=/etc/httpd/conf/
  13. tags: conf
  14. - name: start httpd service
  15. tags: service
  16. service: name=httpd state=started enabled=yes
  17. ansible-playbook t install,conf httpd.yml 指定执行install,conf 两个标签

5.9.1、示例

  1. //heartbeat.yaml
  2. - hosts: hbhosts
  3. remote_user: root
  4. tasks:
  5. - name: ensure heartbeat latest version
  6. yum: name=heartbeat state=present
  7. - name: authkeys configure file
  8. copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
  9. - name: authkeys mode 600
  10. file: path=/etc/ha.d/authkeys mode=600
  11. notify:
  12. - restart heartbeat
  13. - name: ha.cf configure file
  14. copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
  15. notify:
  16. - restart heartbeat
  17. handlers:
  18. - name: restart heartbeat
  19. service: name=heartbeat state=restarted
  1. - hosts: testsrv
  2. remote_user: root
  3. tags: inshttpd 针对整个playbook添加tage
  4. tasks:
  5. - name: Install httpd
  6. yum: name=httpd state=present
  7. - name: Install configure file
  8. copy: src=files/httpd.conf dest=/etc/httpd/conf/
  9. tags: rshttpd
  10. notify: restart httpd
  11. handlers:
  12. - name: restart httpd
  13. service: name=httpd status=restarted
  14. ansible-playbook t rshttpd httpd2.yml