3、Ansible playbooks

Ansible playbooks

playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。下面是一个简单示例。

- hosts: webnodes    //webnodes定义一个主机组,表示应用的目标主机。下面定义的任务只对此组内的主机生效

vars:   //这里是一个键值对,vars是键,它的值是一个字典

http_port: 80

max_clients: 256

remote_user:root   //表示链接远程主机以哪个主机的身份进行

tasks:  //定义接下来要执行的任务

- name: ensure apache is at the latest version  //第一个任务,

yum: name=httpd state=latest                         //基于yum模块安装httpd程序包

- name: ensure apache is running                    //第二个任务

service: name=httpd state=started                 //基于service模块启动httpd服务

handlers:

- name: restart apache

service: name=httpd state=restarted

1、playbook基础组件

1.1 Hosts和Users

playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机(这些主机一定是在Inventory定义的主机),其可以是一个或多个由冒号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的

- hosts: webnodes

remote_user: root

不过,remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。

编写playbooks定义了hosts和users之后,接下来就是定义任务列表。任务可以有多个,所以每一个都要使用“-”引导。

在playbooks中一个剧本应用于不同主机上操作有很多,所以每一个主机组都应该使用"-"来引导

- hosts: webnodes

remote_user: mageedu

tasks:

- name: test connection

ping:

remote_user: dongshi   //此tasks中定义了在远程主机主机上执行任务的用户,这里的优先级最高,不再使用全局中定义的remote_user。

sudo: yes   //表示以dongshi用户的身份切入到远程主机上,以dongshi这个用户的身份sudo到root用户在远程主机来运行命令,这样做的好处是在管控端保存的普通用户身份、                      //权限信息在遭到泄露时不知道导致太大的风险。

基本结构:

- host:websrvs

remote_user:

tasks:      //play的主题部分

- task1    //在所有主机上完成第一个任务,才开始在所有主机上执行第二个任务

module_name:module_args

- task2

1.2 任务列表和action

play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。

在运行自下而下某playbook时,如果中途发生错误,所有已执行任务都可能将回滚(有些任务无法回滚),因此,在更正playbook后重新执行一次即可。

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。

每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。

定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容。如果action一行的内容过多,也中使用在行首使用几个空白字符进行换行。

tasks:

- name: make sure apache is running

service: name=httpd state=running

在众多模块中,只有command和shell模块仅需要给定一个列表而无需使用“key=value”格式,例如:

tasks:

- name: disable selinux      //变量后的":"与值用空格隔开

command: /sbin/setenforce 0

如果某个命令或脚本运行失败,退出码不为零的情况下,可能会阻止playnook继续向后运行,为了避免此情况的出现,可以在某个命令运行结束以后,可以强行让它输出正确的信息。

可以使用如下方式替代:

tasks:

- name: run this command and ignore the result

shell: /usr/bin/somecommand || /bin/true          //此处命令执行成功了,就返回0,如果执行不成功就返回true,所以不会阻止后面的命令继续执行

或者使用ignore_errors来忽略错误信息:

tasks:

- name: run this command and ignore the result

shell: /usr/bin/somecommand

ignore_errors: True     //即使出错无不管不问,继续向后运行。

示例:在3台被管控主机上都创建系统组叫nginx,创建用户也叫nginx

# vim nginx.yml     //由哪个用户的身份在哪些主机上运行什么样的任务

- hosts: websrvs     //定义主机组
  remote_user: root  //定义用户的身份
  tasks:             //定义运行什么样的任务
   - name: create nginx group   //第一个任务。创建nginx组
     group: name=nginx system=yes gid=208
   - name: create nginx user    //第二个任务,创建nginx用户
     user: name=nginx uid=208 group=nginx system=yes

- host: dbsrvs
  remote_user: root
  tasks:
  - name: copy file to dbsrvs
    copy: src=/etc/inittab dest=/tmp/inittab.ans

# ansible-playbook nginx.yml   //执行playbook

PLAY [websrvs] ********************//首先在websrvs主机组上执行任务************************************************************************

TASK [Gathering Facts] ************//在websrvs组主机上执行任务前,每一个被管控主机首先要向管控端报告跟自身主机相关的各种变量,即facts***************
ok: [192.168.184.142]
ok: [192.168.184.143]
ok: [192.168.184.145]

TASK [create nginx group] *********//创建nginx组****************************************************************************************
changed: [192.168.184.142]         //显示changed表示任务执行成功。表示目标主机不处于已定义(即tasks中的定义)的目标状态,所以要对目标做修改。
changed: [192.168.184.143]         //比如nginx组不存在,所以就在被管控主机上创建,就显示changed。
changed: [192.168.184.145]

TASK [create nginx user] **********//创建nginx用户**************************************************************************************
changed: [192.168.184.142]
changed: [192.168.184.143]
changed: [192.168.184.145]

PLAY [dbsrvs] **********************//然后在dbsrvs主机组上执行任务************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.145]

TASK [copy file to dbsrvs] ***********************************************************************************************************
changed: [192.168.184.142]
changed: [192.168.184.145]

PLAY RECAP **************************//在所有任务都执行完成后,会有一个报告******************************************************************
192.168.184.142            : ok=5    changed=3    unreachable=0    failed=0   //比如1422主机上执行任务ok是的数量是5,其中包括changed和Gathering Facts,changed是3
192.168.184.143            : ok=3    changed=2    unreachable=0    failed=0   //unreached和failed都为0,表示没有执行失败的
192.168.184.145            : ok=5    changed=3    unreachable=0    failed=0   

# ansible-playbook nginx.yml    //在执行一边playbook与上面对比

PLAY [websrvs] ***********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.143]
ok: [192.168.184.145]

TASK [create nginx group] ************************************************************************************************************
ok: [192.168.184.145]    //这里就显示ok,并不是创建nginx组ok,而是被管控主机所有的数据都存在,而且满足tasks定义的需要,就报告为ok
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [create nginx user] *************************************************************************************************************
ok: [192.168.184.145]
ok: [192.168.184.143]
ok: [192.168.184.142]

PLAY [dbsrvs] ************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.145]

TASK [copy file to dbsrvs] ***********************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.145]

PLAY RECAP ***************************************************************************************************************************
192.168.184.142            : ok=5    changed=0    unreachable=0    failed=0
192.168.184.143            : ok=3    changed=0    unreachable=0    failed=0
192.168.184.145            : ok=5    changed=0    unreachable=0    failed=0   

1.3 handlers 处理器

用于当关注的资源发生变化时采取一定的操作。

在一个服务的配置文件发生改变时,应该让程序重读配置文件或者重启程序。

默认情况下,多次执行一个任务的时候,如果那个任务已经执行过了,为了保持幂等性,它是不会再次执行的,所以就不可能重启。

handler就是为了解决这种问题的,它可以监控另外一个task,如果所监控的task做了某些修改,才执行指定的任务。

所以handler也是一个任务,这个任务不是上来就执行的,只有某个条件满足时才执行。

“notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。

在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

- name: template configuration file      //定义的任务,配置文件

template: src=template.j2 dest=/etc/foo.conf

notify:   //如果定义的文件发生改变后就通知给另外一个任务

- restart memcached      //任务的名字,哪个任务呢?就是下面在handlers中定义的name的名字

- restart apache

handler是task列表,这些task与前述的task并没有本质上的不同。

handlers:

- name: restart memcached      //即上面notify下面任务的名字

service:  name=memcached state=restarted

- name: restart apache

service: name=apache state=restarted

上述的意思是某一个资源或配置文件发生改变后,必须要触发另外的操作时,就是用notify指明触发哪一个handler,事先把触发的操作定义好,每一个操作就叫一个handler。

示例演示

# yum install httpd -y   //确保管控主机安装了httpd

# mkdir conf

# cp /etc/httpd/conf/httpd.conf conf/    //把httpd的配置文件httpd.conf复制到创建的目录中

# vim conf/httpd.conf

Listen 8080   //让httpd监听在8080端口

# vim apache.yml

- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd package
    yum: name=httpd state=latest
  - name: install configuration file for httpd
    copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf  //把目标文件覆盖掉
  - name: start httpd service
    service: enabled=true name=httpd state=started

# ansible-playbook apahce.yml    //都可以执行成功

# netstat -tunlp   //在被管控主机上都可以查看到8080端口

那么问题来了,假如源配置文件src=/root/conf/httpd.conf 发生改变了,比如配置文件的监听端口改变为80,其他都不改变,那么再执行# ansible-playbook apahce.yml 后,httpd服务要不要重新启动呢?会不会根据配置文件httpd.conf的修改监听80端口呢?

# vim conf/httpd.conf    //修改配置文件,把端口修改为80

Listen 80          //让httpd监听在80端口

# ansible-playbook apache.yml     //再次执行此剧本

PLAY [websrvs] ***********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install httpd package] *********************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install configuration file for httpd] ******************************************************************************************
changed: [192.168.184.143]       //这里的changed是因为发现httpd.conf文件中监听的端口从8080改为80,所以重新把配置文件从管控端复制到被管控端,所以发生了改变
changed: [192.168.184.142]

TASK [start httpd service] ***********************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.143]

PLAY RECAP ***************************************************************************************************************************
192.168.184.142            : ok=4    changed=1    unreachable=0    failed=0
192.168.184.143            : ok=4    changed=1    unreachable=0    failed=0   

再次查看被管控端的端口,可以看出监听的端口依然是8080端口,没有发生改变,即httpd并没有在配置文件更改后自动重启。

在一个服务的配置文件发生改变时,应该让程序重读配置文件或者重启程序。

默认情况下,多次执行一个任务的时候,如果那个任务已经执行过了,为了保持幂等性,它是不会再次执行的,所以就不可能重启。

handler就是为了解决这种问题的,它可以监控另外一个task,如果所监控的task做了某些修改,才执行指定的任务。

所以handler也是一个任务,这个任务不是上来就执行的,只有某个条件满足时才执行。

# vim apache.yml  //再次修改剧本,添加红色部分

- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd package
    yum: name=httpd state=latest
  - name: install configuration file for httpd
    copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:   //如果通知有多个,每一个要使用列表,这里虽然只有一个,但仍然使用列表进行描述。表示会触发一个事件,触发restart httpd这个处理器
    - restart httpd
  - name: start httpd service
    service: name=httpd enabled=true state=started
  handlers:   //和tasks是同级别的,handlers可能有多个,每一个handler都用一个"-"来引导。handler定义方式和task是一样的,只不过handler不会直接上来就执行,只有在某个条件被触发时,才会执行
  - name: restart httpd    //这里要和notify定义的保持一致
    service: name=httpd state=resarted

# ansible-playbook apache.yml    //再次运行此脚本,注意如果apache.yml中定义的源配置文件不发生改变,是不会触发handler的

PLAY [websrvs] ***********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install httpd package] *********************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install configuration file for httpd] ******************************************************************************************
changed: [192.168.184.143]
changed: [192.168.184.142]

TASK [start httpd service] ***********************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

RUNNING HANDLER [restart httpd] **********//这里handler已经执行*************************************************************************
changed: [192.168.184.143]          //重新启动了被管控主机的httpd服务
changed: [192.168.184.142]

PLAY RECAP ***************************************************************************************************************************
192.168.184.142            : ok=5    changed=2    unreachable=0    failed=0
192.168.184.143            : ok=5    changed=2    unreachable=0    failed=0   

如何在playbook中使用变量

- hosts: webnodes

vars:   //在定义任何一个playbook的时候,可以使用vars定义变量,定义完之后可以直接引用变量

http_port: 80  //比如我们传递给playbook时的某个配置文件中来调用此变量的值即可

max_clients: 256

remote_user: root

示例:基于前面的修改进行演示

# vim apache.yml

- hosts: websrvs
  remote_user: root
  vars:    //使用变量的化,在此处使用vars定义变量,变量是多个,肯定是一个序列,要用"-"来引导,
  - package: httpd     //pachage是变量名,httpd是变量的值,这里定义了一个报名
  - service: httpd    //这里定义服务名。变量名只能包含数字、字母和下划线,而且只能以字母开头
  tasks:
  - name: install httpd package
    yum: name={{ package }} state=latest     //此处引用包名,即引用变量package的值httpd来替代
  - name: install configuration file for httpd
    copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart httpd
  - name: start httpd service
    service: name={{ service }} enabled=true state=started   //这里同上,要用花括号{{}},注意空格
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

# ansible-playbook apache.yml   //重新执行,毫无问题

PLAY [websrvs] ***********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install httpd package] *********************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [install configuration file for httpd] ******************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [start httpd service] ***********************************************************************************************************
ok: [192.168.184.142]
ok: [192.168.184.143]

PLAY RECAP ***************************************************************************************************************************
192.168.184.142            : ok=4    changed=0    unreachable=0    failed=0
192.168.184.143            : ok=4    changed=0    unreachable=0    failed=0   

注意:在playbook中使用的变量,不仅仅有上述定义的变量,也可以是ansible中所定义的所有变量。

根据上句话进行演示:

# vim test.yml

- hosts: websrvs
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{{ ansible_all_ipv4_addresses }}" dest=/tmp/vars.ans   //copy模块在copy时指定内容有两种方式,一种是src指明,另一种是使用content直接生成。          //此时content调用的是ansible中的变量。

其中nsible_all_ipv4_addresses可以根据以下方式获得:

# ansible 192.168.184.141 -m setup | less

# ansible-playbook test.yml  //已经完成

PLAY [websrvs] ***********************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.184.143]
ok: [192.168.184.142]

TASK [copy file] *********************************************************************************************************************
changed: [192.168.184.143]
changed: [192.168.184.142]

PLAY RECAP ***************************************************************************************************************************
192.168.184.142            : ok=2    changed=1    unreachable=0    failed=0
192.168.184.143            : ok=2    changed=1    unreachable=0    failed=0   

# cat /tmp/vars.ans    //在被管控端的主机查看生成的内容

["192.168.184.142"]

所以有些变量不用定义就可以调用,这些变量就像ansible facts就可以实现

原文地址:https://www.cnblogs.com/hanshanxiaoheshang/p/10206380.html

时间: 2024-10-09 00:22:12

3、Ansible playbooks的相关文章

Ansible Playbooks的使用

playbooks概念:Tasks:任务:由各模块所支持执行的特定操作任务:例子:-m user -a 'name= password='Variables:变量:Templates:模板:在定义模板之后可以实现各节点对应的变量来取代,表达式自身会根据当前节点所赋值做运算,之后生成的值则赋予这个参数,用于生成不同配置的配置文件,所以模板主要实现配置不同场景文本文件.而且这样使用模板语言来定义,模板语言中可以根据定义替换成特定主机的某些值.Handlers:处理器:如果某一次操作配置文件发生改变的

Ansible Playbooks 介绍 和 使用 二

目录 handlers playbook 案例 2 handlers vars 变量 setup facts 变量使用 案例 inventory 中定义变量 案例 条件测试 when 语句 案例 handlers 接上一篇文章 Ansible Playbooks 介绍 和 使用 一 继续说明 用于当关注的资源发生变化时采取一定的操作. notify这个 action可用于在每个play的最后被处罚,这样可以避免多次有改变时每次都执行指定的操作,取而代之,尽在所有的变化发生完成后一次性执行指定的操

Ansible Playbooks学习

Ansible的Playbooks是Ansible用于配置,部署应用的结构化语言.Ansible的模块就好比shell命令,那么playbooks就好比shell脚本,在脚本中指定怎么使用哪些命令再加上一些判断语句等等. Playbooks使用YAML文件来表示执行步骤. --- - hosts: webservers   vars:     http_port: 80     max_clients: 200   remote_user: root   tasks:   - name: ens

puppet 、saltstack 、ansible个人使用的一点比较

许多企业使用云服务,自动化运维的工具也越来越火,安装和使用了三种自动化运维工具 puppet.saltstack.ansible个人的一点心得看法: puppet c/s构架 服务端puppet master 客户端puppet agent进程 启动程序使用ruby进程 有监听端口master 8140  agent 8139 原理 agent客户端puppet.conf配置master服务端的IP地址.runinterval = 10(客户端每10秒向master发送请求接收执行).liste

4、Ansible配置和使用

Ansible使用SSH协议, 要使用Ansible,必须配置密钥对,并将Ansible主机上的公钥传到目标主机上的某个用户下 操作过程如下: 1.环境: Ansible主机:172.16.206.131  root用户 被管理主机:172.16.206.133 2.Ansible主机上生成SSH KEY ssh-keygen -t rsa 3.将SSH Key传到被管理主机的某个账户下 ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] 第一次

Fbric、Ansible、Docker、Chaos Monkey:DevOps工具的年中回顾

Fbric.Ansible.Docker.Chaos Monkey:DevOps工具的年中回顾 [编者按]近日,Cyber Engineering Solutions Group 技术经理 Hasan Yasar 在 SEI 攥文盘点了当下流行的 DevOps 思想和工具,其中包括Fabric.Ansible.Docker.Chaos Monkey等.本文系 OneAPM 联合高效运维联合编译整理: 在2014年年底,SEI 博客发表了一系列有关 DevOps 的博客文章,提供指南,实用的建议和

ansible的安装与介绍、host-pattern格式、ansible的command模块、ansible的shell模块、ansible的script模块、ansible的copy模块

一.ansible的安装与介绍 ansible需要安装在管控机上 首先安装wget(如果机器上有可以忽略) 下载安装wget yum install -y wget 将epel源下载安装到本地 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 安装ansible yum install -y ansible ansible的命令格式 Usage: ansible <host-pattern>

3、Ansible配置文件和Inventory文件

如果是用RPM包方式安装的Ansible,那么安装完成后会生成以下文件: /etc/ansible                              ###存放ansible配置文件的目录 /etc/ansible/hosts                   ###ansible Inventory文件 /etc/ansible/ansible.cfg        ###ansible的配置文件 如果是pip安装的Ansible,那么需要手动创建这些文件,也可以从其他地方拷贝. a

Ansible playbooks常用模块案例操作

打开git bash 连接ansible服务器,然后进入deploy用户 #ssh [email protected] 进入python3.6虚拟环境 #su - deploy #source .py3-a2.5-env/bin/activate 加载ansible 2.5版本 #source .py3-a2.5-env/ansible/hacking/env-setup -q 验证ansible加载效果 #ansible-playbook --version 1.File模块 登录到目标主机进