文档章节

3.playbook基础

eddy_linux
 eddy_linux
发布于 2017/08/03 13:28
字数 4355
阅读 15
收藏 0
Playbooks 是 Ansible的配置,部署,编排语言.他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合.

如果 Ansible 模块你是工作室中的工具,那么 playbooks 就是你设置的方案计划.

在基础层面, playbooks 可以被用来管理用于部署到远程主机的配置文件.在更高的层面上,playbooks 可以依次对多层式架构上的服务器执行上线包括滚动更新在内的操作并可以将操作委托给其他主机包括在此过程中发生的与监视服务器,负载均衡服务器的交互操作在内.
Playbooks 被设计的非常简单易懂和基于text language二次开发.有多种办法来组织 playbooks 和其附属的文件,同时我们也会提供一些关于学习 Ansible 的建议.
一些例子
https://github.com/ansible/ansible-examples
Playbooks 简介
Playbooks 与 adhoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的.

简单来说,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.

Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务.
我们使用 adhoc 时,主要是使用 /usr/bin/ansible 程序执行任务.而使用 playbooks 时,更多是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范.
Playbooks 的格式是YAML

YAML语法:
对于 Ansible, 每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对, 通常它们被称为一个 “哈希” 或 “字典”. 所以, 我们需要知道如何在 YAML 中编写列表和字典.
YAML 还有一个小的怪癖. 所有的 YAML 文件(无论和 Ansible 有没有关系)开始行都应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的开始.

列表中的所有成员都开始于相同的缩进级别, 并且使用一个 "- " 作为开头(一个横杠和一个空格):
---
# 一个美味水果的列表
- Apple
- Orange
- Strawberry
- Mango
一个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格):
---
# 一位职工的记录
name: Example Developer
job: Developer
skill: Elite
字典也可以使用缩进形式来表示, 如果你喜欢这样的话:
---
# 一位职工的记录
{name: Example Developer, job: Developer, skill: Elite}
Ansible并不是太多的使用这种格式, 但是你可以通过以下格式来指定一个布尔值(true/fase):
---
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
让我们把目前所学到的 YAML 例子组合在一起. 这些在 Ansible 中什么也干不了, 但这些格式将会给你感觉:
---
# 一位职工记录
name: Example Developer
job: Developer
skill: Elite
employed: True
foods:
    - Apple
    - Orange
    - Strawberry
    - Mango
languages:
    ruby: Elite
    python: Elite
    dotnet: Lame

这就是你开始编写 Ansible playbooks 所需要知道的所有 YAML 语法.
需要注意的是:,-这些后面都要有一个空格,还有就是对齐很重要

语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型.
playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表.
在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible 模块的调用,这在前面章节学习过.
‘plays’ 好似音符,playbook 好似由 ‘plays’ 构成的曲谱,通过 playbook,可以编排步骤进行多机器的部署,比如在 webservers 组的所有机器上运行一定的步骤, 然后在 database server 组运行一些步骤,最后回到 webservers 组,再运行一些步骤,诸如此类.
“plays” 算是一个体育方面的类比,你可以通过多个 plays 告诉你的系统做不同的事情,不仅是定义一种特定的状态或模型.你可以在不同时间运行不同的 plays.

对初学者,这里有一个 playbook,其中仅包含一个 play:
---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

主机与用户
你可以为 playbook 中的每一个 play,个别地选择操作的目标机器是哪些,以哪个用户身份去完成要执行的步骤(called tasks).

hosts 行的内容是一个或多个组或主机的 patterns,以逗号为分隔符
remote_user 就是账户名:

---
- hosts: webservers
  remote_user: root
再者,在每一个 task 中,可以定义自己的远程用户:
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: yourname
也支持从 sudo 执行命令:
---
- hosts: webservers
  remote_user: yourname
  sudo: yes
同样的,你可以仅在一个 task 中,使用 sudo 执行命令,而不是在整个 play 中使用 sudo:
---
- hosts: webservers
  remote_user: yourname
  tasks:
    - service: name=nginx state=started
      sudo: yes
你也可以登陆后,sudo 到不同的用户身份,而不是使用 root:
---
- hosts: webservers
  remote_user: yourname
  sudo: yes
  sudo_user: postgres

如果你需要在使用 sudo 时指定密码,可在运行 ansible-playbook 命令时加上选项 --ask-sudo-pass (-K). 如果使用 sudo 时,playbook 疑似被挂起,可能是在 sudo prompt 处被卡住,这时可执行 Control-C 杀死卡住的任务,再重新运行一次.
当使用 sudo_user 切换到 非root 用户时,模块的参数会暂时写入 /tmp 目录下的一个随机临时文件. 当命令执行结束后,临时文件立即删除.这种情况发生在普通用户的切换时,比如从 ‘bob’ 切换到 ‘timmy’, 切换到 root 账户时,不会发生,如从 ‘bob’ 切换到 ‘root’,直接以普通用户或root身份登录也不会发生. 如果你不希望这些数据在短暂的时间内可以被读取(不可写),请避免在 sudo_user 中传递未加密的密码. 其他情况下,’/tmp’ 目录不被使用,这种情况不会发生.Ansible 也有意识的在日志中不记录密码参数.

Tasks 列表
每一个 play 包含了一个 task 列表(任务列表).一个 task 在其所对应的所有主机上(通过 host pattern 匹配的所有主机)执行完毕之后,下一个 task 才会执行.有一点需要明白的是(很重要),在一个 play 之中,所有 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task.
在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除. 如果发生执行失败的情况,请修正 playbook 中的错误,然后重新执行即可.
每个 task 的目标在于执行一个 moudle, 通常是带有特定的参数来执行.在参数中可以使用变量(variables).
modules 具有”幂等”性,意思是如果你再一次地执行 moudle(比如遇到远端系统被意外改动,需要恢复原状),moudle 只会执行必要的改动,只会改变需要改变的地方.所以重复多次执行 playbook 也很安全.
对于 command module 和 shell module,重复执行 playbook,实际上是重复运行同样的命令.如果执行的命令类似于 ‘chmod’ 或者 ‘setsebool’ 这种命令,这没有任何问题.也可以使用一个叫做 ‘creates’ 的 flag 使得这两个 module 变得具有”幂等”特性 (不是必要的).
每一个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个 task 的. 如果没有定义 name,‘action’ 的值将会用作输出信息中标记特定的 task.
如果要声明一个 task,以前有一种格式: “action: module options” (可能在一些老的 playbooks 中还能见到).现在推荐使用更常见的格式:”module: options” ,本文档使用的就是这种格式.
下面是一种基本的 task 的定义,service moudle 使用 key=value 格式的参数,这也是大多数 module 使用的参数格式:
tasks:
  - name: make sure apache is running
    service: name=httpd state=running
比较特别的两个 modudle 是 command 和 shell ,它们不使用 key=value 格式的参数,而是这样:
tasks:
  - name: disable selinux
    command: /sbin/setenforce 0

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True
如果 action 行看起来太长,你可以使用 space(空格) 或者 indent(缩进) 隔开连续的一行:
tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
            owner=root group=root mode=0644

在 action 行中可以使用变量.假设在 ‘vars’ 那里定义了一个变量 ‘vhost’ ,可以这样使用它:
tasks:
  - name: create a virtual host file for {{ vhost }}
    template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
在一个基础的 playbook 中,所有的 task 都是在一个 play 中列出,稍后将介绍一种更合理的安排 task 的方式:使用‘include:’ 指令
Action Shorthand
在 0.8 及以后的版本中,ansible 更喜欢使用如下的格式列出 modules:
template: src=templates/foo.j2 dest=/etc/foo.conf
Handlers: 在发生改变时执行的操作
上面我们曾提到过,module 具有”幂等”性,所以当远端系统被人改动时,可以重放 playbooks 达到恢复的目的. playbooks 本身可以识别这种改动,并且有一个基本的 event system(事件系统),可以响应这种改动.
(当发生改动时)’notify’ actions 会在 playbook 的每一个 task 结束时被触发,而且即使有多个不同的 task 通知改动的发生, ‘notify’ actions 只会被触发一次.
举例来说,比如多个 resources 指出因为一个配置文件被改动,所以 apache 需要重新启动,但是重新启动的操作只会被执行一次.
这里有一个例子,当一个文件的内容被改动时,重启两个 services:
- name: template configuration file
  template: src=template.j2 dest=/etc/foo.conf
  notify:
     - restart memcached
     - restart apache
‘notify’ 下列出的即是 handlers.
Handlers 也是一些 task 的列表,通过名字来引用,它们和一般的 task 并没有什么区别.Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行.不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次.

这里是一个 handlers 的示例:
handlers:
    - name: restart memcached
      service:  name=memcached state=restarted
    - name: restart apache
      service: name=apache state=restarted

Handlers 最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了.
handlers 会按照声明的顺序执行
需要指出的是,handlers 会在 ‘pre_tasks’, ‘roles’, ‘tasks’, 和 ‘post_tasks’ 之间自动执行. 如果你想立即执行所有的 handler 命令,在1.2及以后的版本,你可以这样做:
tasks:
   - shell: some tasks go here
   - meta: flush_handlers
   - shell: some other tasks

在以上的例子中,任何在排队等候的 handlers 会在执行到 ‘meta’ 部分时,优先执行.这个技巧在有些时候也能派上用场.
执行一个 playbook
既然现在你已经学习了 playbook 的语法,那要如何运行一个 playbook 呢?这很简单,这里的示例是并行的运行 playbook,并行的级别是10
ansible-playbook playbook.yml -f 10

Ansible-Pull(拉取配置而非推送配置)
我们可不可以将 ansible 的体系架构颠倒过来,让托管节点从一个 central location 做 check in 获取配置信息,而不是推送配置信息到所有的托管节点?是可以的.
Ansible-pull 是一个小脚本,它从 git 上 checkout 一个关于配置指令的 repo,然后以这个配置指令来运行 ansible-playbook.
假设你对你的 checkout location 做负载均衡,ansible-pull 基本上可以无限的提升规模.
可执行 ansible-pull --help 获取详细的帮助信息.
也有一个叫做 clever playbook 的东西: clever playbook . 这个可以通过crontab来配置ansible-pull(from push mode).
提示与技巧
在 playbook 执行输出信息的底部,可以找到关于托管节点的信息.也可看到一般的失败信息,和严重的 “unreachable” 信息.这两个是分开计数的.
如果你想看到执行成功的 modules 的输出信息,使用 --verbose flag(否则只有执行失败的才会有输出信息).这在 0.5 及以后的版本中可用.
如果安装了 cowsay 软件包,ansible playbook 的输出已经进行了广泛的升级.可以尝试一下!
在执行一个 playbook 之前,想看看这个 playbook 的执行会影响到哪些 hosts,你可以这样做:
ansible-playbook playbook.yml --list-hosts

Playbook Roles and Include Statements
当 playbook 文件越来越大的时候(你可以跳出来去学习 playbooks 了),最后一定会有文件重用时候,此刻就需要我们来重新组织 playbooks 了.
从最基本来讲, task files 请允许我们拆分配置策略到多个小文件. Task 可以从其它文件中读取 tasks. 因为 handler 也是tasks, 所以你也可以在在 ‘handlers:’ 区域引用 handler 文件.
Playbooks 也可以引用其它 playbooks 文件中的命令条目.当所有文件均读取完毕后, 所有的命令条目将被插入到一个 playbook 中组合成一条长的命令列表.
当你开始思考 – tasks, handlers, variables等 – 开始形成大的想法概念,当你开始创造一些东西,而非模仿某些东西. It’s no longer “apply this handful of THINGS to these hosts” ,你决定 “这些 hosts 是 dbservers” 或者 这些 hosts 是 webservers”. 在编程语言中,我们称之为”封装”.举个例子,你会开车但不需要知道发动机工作原理.
Roles 在 Ansible中起到的宗旨是把配置文件整合到一起并最大程度保证其干净整洁,可重用 – 他允许我们把重点放在大局上只有在需要的时候才再深入了解.
了解includes对深入 roles 有重要意义,但我们最终的目标是理解 roles – roles是非常伟大的产品,所以当我们写 playbooks 时一定要使用 roles.
Task Include Files 和鼓励重用机制
猜想你希望在不同 tasks 之间plays 和 playbooks 可以重复调用. include files可以达成目的. 系统通过使用 include task 来完美实现 role 定义. 记住, playbook 中的 play 最终目的是映射系统群到多 roles中
只简单包括 tasks 的 task 文件如下示例:
---
# possibly saved as tasks/foo.yml

- name: placeholder foo
  command: /bin/foo

- name: placeholder bar
  command: /bin/bar
Include 指令类似如下,可以像普通 tasks 命令一样在 playbook 中混合使用:
tasks:
  - include: tasks/foo.yml
你也可以传输变量到 includes 指令, 我们称之为 ‘parameterized include’.

例如,如何分发多个 wordpress 实例,我可以包涵所有 wordpress 命令到一个 wordpress.yml 文件,按如下方式使用:
tasks:
  - include: wordpress.yml wp_user=timmy
  - include: wordpress.yml wp_user=alice
  - include: wordpress.yml wp_user=bob
如果你使用的是 Ansible 1.4以上版本(包括1.4), include 语法简化了匹配 roles, 同时允许传递参数列表和字典:

tasks:
 - { include: wordpress.yml, wp_user: timmy, ssh_keys: [ 'keys/one.txt', 'keys/two.txt' ] }
使用任意一种语法, 变量传递均可以在 included 文件中被使用.你可以这样引用他们:
{{ wp_user }}
从1.0开始, ansible 还支持另外一种变量传参到 include files 的方式-结构化变量,方式如下
tasks:
  - include: wordpress.yml
    vars:
        wp_user: timmy
        ssh_keys:
          - keys/one.txt
          - keys/two.txt

Includes 功能也可以被用在用 handlers 区域,例如,如果你希望定义如何重启apache,你只需要定义一个playbook,只需要做一次.编辑类似如下样例的 handers.yml:
---
# this might be in a file like handlers/handlers.yml
- name: restart apache
  service: name=apache state=restarted
然后像如下方式在 main playbook 的询问引用play即可:
handlers:
  - include: handlers/handlers.yml
Includes也可以在常规不包含 included 的tasks和handlers文件中混合引用. Includes常被用作将一个playbook文件中的命令导入到另外一个playbook.这种方式允许我们定义由其它playbooks组成的顶层playbook(top-level playbook).
- name: this is a play at the top level of a file
  hosts: all
  remote_user: root

  tasks:
  - name: say hi
    tags: foo
    shell: echo "hi..."

- include: load_balancers.yml
- include: webservers.yml
- include: dbservers.yml
注意: 引用playbook到其它playbook时,变量替换功能将失效不可用.
你不能有条件的指定位置的 include 文件,就像在你使用 ‘vars_files’ 时一样. 如果你发展你必须这么做,那请重新规划调整 playbook 的class/role 编排.这样 说其实是想明确告诉你不要妄想 include 指定位置的file. 所有被包含在 play 中的主机都将执行相同的tasks.(‘when‘提供了一些指定条件来跳过tasks)

 

© 著作权归作者所有

上一篇: 4.playbook应用
下一篇: 2.常用模块
eddy_linux
粉丝 22
博文 135
码字总数 188789
作品 0
成都
程序员
私信 提问
Excel 2010基础应用技巧大全

在Excel基础大全里面,我全部透彻讲解Excel所有功能技术特点和应用方法,从Excel基础操作开始,逐步讲解公式与函数、格式设置、数据高级分析、模拟分析、数据透视表、图表、后期打印以及宏与V...

么么哒lalala
2016/01/05
67
0
思途旅游CMS V6.0.201708.03

更新包 产品名 描述 kb2017080303 思途CMS_基础 1、移动端积分商城; 优化 kb2017080201 思途CMS_基础 1、修复缓存目录无法创建问题; 修复 kb2017080103 思途CMS_基础 1、解决部分服务器限制...

谢二公子
2017/08/04
1
0
关于自动化脚本黑盒话的进度

在很久之前就想将自动化脚本编程黑盒化,让黑盒来编制自动化case 这样,我就可以有更多时间去面对以及完善我的自动化测试框架,毕竟总是在一个地方徘徊,终难有出路。 今天excel终于搞定了 ...

测试-雨
2015/09/06
137
0
JAVA多线程-基础篇-目录

刚忙完双十一,本系列内容也恰好告一段落,总共分为11个章节,希望对大家有所帮助 JAVA多线程01-基础篇-基本概念 JAVA多线程02-基础篇-线程创建方式 JAVA多线程03-基础篇-线程运行 JAVA多线程...

x_coder
2017/11/14
0
0
Android面试笔记基础篇

基础一:安卓四大组件。 问题一:安卓四大组件是什么?应该怎么描述它们?生命周期?优先级? 答:四大组件就是Activity Service BroadCastReciver ContentProvider Activity:与用户交互等界...

一阵啪啪啪
2018/01/15
12
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
38分钟前
4
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
4
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
13
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
14
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部