轻量级自动化运维工具ansible之二:playbook详解

在介绍playbook之前,我们先了解一下YAML语言,因为playbook是用YAML语言编写的

一、YAML

1、YAML是一种可读性高的用来表达资料序列的语言,其语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。所有的yaml文件都以"---"开头表示开始一个document,所有的列表元素以"-"开头,键值对用":",后面的空格是必须的下面是一个示例:

---   #打头符可省略

- name: John Smith

age: 41

gender: Male

spouse:

name: Jane Smith

age: 37

gender: Female

children:

- name: Jimmy Smith

age: 17

gender: Male

- name: Jenny Smith

age 13

gender: Female

YAML文件扩展名通常为.yaml或.yml,如example.yaml

2、list

列表的所有元素均使用“-”打头,例如:

# A list of tasty fruits

- Apple

- Orange

- Strawberry

3、dictionary

字典通过key与valuef进行标识,例如:

# An employee record

name: Example Developer

job: Developer

skill: Elite

也可以将key:value放置于{}中进行表示,例如:

# An employee record

{name: Example Developer, job: Developer, skill: Elite}

二、playbook详解

playbook(剧本)是ansible管理配置、部署应用和编排的文件,可用来描述你想在被控主机上执行的策略或者一组任务等。

一个playbook文件由一个或多个play组成,每个play定义了在一个或多个远程主机上执行的一系列的task,其中每个task一般就是调用一个ansible的模块。

playbook使用YAML语言编写,文件名以.yaml或.yml结尾。此外playbook和模板文件(template)还可使用jinja2语法语法实现高级功能。

1、playbook的基本组成

targets:指定要执行playbook的远程主机组

variables:定义playbook运行时需要使用的变量

tasks:要执行的任务

handlers:处理器,在某些条件下被触发的操作

一个简单的示例:

vim httpd.yml

- hosts: websrvs

remote_user: root

vars:

remote_conffile_path: /etc/httpd/conf/httpd.conf

tasks:

- name: install httpd

yum: name+httpd state=latest

when: ansible_pkg_mgr == "yum"

- name: configration file

tags: conf

copy: src=/root/httpd.conf dest={{ remote_conffile_path }}

notify: restart httpd

- name: start httpd

service: name=httpd enabled=yes state=started

handlers:

- name: restart httpd

service: name=httpd state=restarted

2、playbook各基础组件说明

⑴hosts和users

hosts用于指定要执行指定任务的主机,其可以是一个或多个由逗号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的

- hosts: websrvs

remote_user: root

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

- hosts: websrvs

remote_user: magedu

tasks:

- name: test connection

ping:

sudo: yes

⑵任务列表和action

play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。

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

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

定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容例如:

tasks:

- name: make sure apache is running

service: name=httpd state=running

在众多模块中,只有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 || /bin/true(表示一定会成功)

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

tasks:

- name: run this command and ignore the result

shell: /usr/bin/somecommand

ignore_errors: True

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

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

- name: template configuration file

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

notify:

- restart memcached

- restart apache

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

handlers:

- name: restart memcached

service: name=memcached state=restarted

- name: restart apache

service: name=apache state=restarted

⑷变量

变量名仅能由字母、数字和下划线组成,且只能以字母开头。

在playbook中定义变量的格式:

- host websrvs

vars:

variable:value

如何调用变量:{{ variable }}

在inventory中定义的变量,可在playbook中直接调用

每个被控节点在接收并运行管理命令之前,会将本主机相关信息(称为facts,这些信息保存于变量中)如操作系统版本,ip地址,cpu数量等报告给ansible主机。这些变量信息通过 ansible <host-pattern> -m setup 获取,我们可在playbook中调用这些变量。

当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量,示例如下:

- hosts: webservers

roles:

- common

- { role: foo_app_instance, dir: ‘/web/htdocs/a.com‘, port: 8080 }

另外,在运行playbook的时候也可以传递一些变量,示例:

ansible-playbook test.yml --extra-vars "hosts=www user=magedu"

4、条件测试

如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提,这时就要用到条件测试。

when语句:

在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。例如:

tasks:

- name: "shutdown Debian flavored systems"

command: /sbin/shutdown -h now

when: ansible_os_family == "Debian"

when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:

tasks:

- command: /bin/false

register: result

ignore_errors: True

- command: /bin/something

when: result|failed

- command: /bin/something_else

when: result|success

- command: /bin/still/something_else

when: result|skipped

此外,when语句中还可以使用facts或playbook中定义的变量。

5、迭代

当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。例如:

- name: add several users

user: name={{ item }} state=present groups=wheel

with_items:

- testuser1

- testuser2

上面语句的功能等同于下面的语句:

- name: add user testuser1

user: name=testuser1 state=present groups=wheel

- name: add user testuser2

user: name=testuser2 state=present groups=wheel

事实上,with_items中可以使用元素还可以是hashes,例如:

- name: add several users

user: name={{ item.name }} state=present groups={{ item.groups }}

with_items:

- { name: ‘testuser1‘, groups: ‘wheel‘ }

- { name: ‘testuser2‘, groups: ‘root‘ }

6、tags(标签)

tags用于让用户选择运行playbook中的某个或某些任务。虽然ansible具有幂等性,会跳过没有变化的部分,但是,有些代码为测试其确实没有发生变化,也会耗费很长时间。我们将playbook中的指定任务打上标签,在运行playbook时指定标签名称,这样就不用运行全部代码了。

playbook中可定义多个标签,且可重名。

示例:

- name: configration file

copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf

notify: restart httpd

tags: conf

运行指定标签的任务:ansible-playbook httpd.yml -t conf

7、运行playbook

ansible-playbook <filename.yml> ... [options]

例:ansible-playbook httpd.yml

8、案例:使用ansible对websrvs组的两台主机做httpd的高可用

以下node1为ansible节点,node2和node3为被控节点,已被添加至主机组websrvs。这里假设两个被控节点上已安装好httpd服务程序,且已建立双机互信。

[[email protected] ~]# vim /etc/ansible/hosts

[websrvs]
192.168.30.20
192.168.30.13
[dbsrvs]
192.168.30.14
[[email protected] ~]# ls hb_conf   #准备好需要的文件
authkeys  ha.cf  haresources
[[email protected] ~]# vim heartbeat.yml   #创建playbook

- hosts: websrvs
  remote_user: root
  tasks:
  - name: ensure heartbeat latest version
    yum: name=heartbeat state=present
  - name: authkeys
    copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/ mode=600
    notify: restart heartbeat
  - name: ha.cf
    copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/
    notify: restart heartbeat
    tags: conf   #打标签
  - name: haresources
    copy: src=/root/hb_conf/haresources dest=/etc/ha.d/
    notify: restart heartbeat
  handlers:
  - name: restart heartbeat
    service: name=heartbeat state=restarted

[[email protected] ~]# ansible-playbook heartbeat.yml    #运行playbook

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.30.20]
ok: [192.168.30.13]

TASK [ensure heartbeat latest version] *****************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

TASK [authkeys] ****************************************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

TASK [ha.cf] *******************************************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

TASK [haresources] *************************************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

RUNNING HANDLER [restart heartbeat] ********************************************
changed: [192.168.30.13]
changed: [192.168.30.20]

PLAY RECAP *********************************************************************
192.168.30.13              : ok=6    changed=5    unreachable=0    failed=0   
192.168.30.20              : ok=6    changed=5    unreachable=0    failed=0
#验证
[[email protected] ~]# ls /etc/ha.d
authkeys  ha.cf  harc  haresources  rc.d  README.config  resource.d  shellfuncs
[[email protected] ~]# ll /etc/ha.d/authkeys 
-rw------- 1 root root 680 May  3 20:07 /etc/ha.d/authkeys
[[email protected] ~]# service heartbeat status
heartbeat OK [pid 7595 et al] is running on node2 [node2]...
[[email protected] ~]# ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:bd:68:23 brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.20/24 brd 192.168.30.255 scope global eth0
    inet 192.168.30.100/24 brd 192.168.30.255 scope global secondary eth0
    inet6 fe80::20c:29ff:febd:6823/64 scope link 
       valid_lft forever preferred_lft forever
[[email protected] ~]# service httpd status
httpd (pid  8049) is running...
[[email protected] ~]# vim hb_conf/ha.cf   #修改主配置文件
...
mcast eth0 225.1.1.5 694 1 0   #更改心跳信息的组播地址
[[email protected] ~]# ansible-playbook heartbeat.yml -t conf   #只执行指定标签的任务

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.30.13]
ok: [192.168.30.20]

TASK [ha.cf] *******************************************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

RUNNING HANDLER [restart heartbeat] ********************************************
changed: [192.168.30.20]
changed: [192.168.30.13]

PLAY RECAP *********************************************************************
192.168.30.13              : ok=3    changed=2    unreachable=0    failed=0   
192.168.30.20              : ok=3    changed=2    unreachable=0    failed=0
[[email protected] ~]# netstat -unl
...                         
udp        0      0 225.1.1.5:694               0.0.0.0:*

三、roles

ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

一个roles的目录结构示例:

site.yml

webservers.yml

fooservers.yml

roles/

common/

files/

templates/

tasks/

handlers/

vars/

meta/

webservers/

files/

templates/

tasks/

handlers/

vars/

meta/

在playbook中,可以这样使用roles:

- hosts: webservers

roles:

- common

- webservers

可以向roles传递参数,如:

- hosts: webservers

roles:

- common

- { role: some_role, dir: ‘/opt/a‘, port: 5000 }

- { role: some_role, dir: ‘/opt/b‘, port: 5001 }

也可以条件式地使用roles,例如:

- hosts: webservers

roles:

- { role: some_role, when: "ansible_os_family == ‘RedHat‘" }

1、创建role的步骤

①创建以roles命名的目录;

②在roles目录中分别创建以各角色名称命名的目录,如webservers、dbservers等;

③在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;

④在playbook文件中,调用各角色;

2、role内各目录中可用的文件

tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件;

files目录:存放由copy或script等模块调用的静态文件;

templates目录:template模块会自动在此目录中寻找Jinja2模板文件;

handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;此文件可以使用include包含其它的位于此目录中的handler文件;

vars目录:至少有一个main.yml文件,用于定义此角色用到的变量;

meta目录:至少有一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;

default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;

四、案例—使用ansible搭建LAMP环境,要求如下:

①两台web服务器,一台mysql数据库服务器,php作为httpd的模块

②在php服务器上部署独立博客站点wordpress

③要求两台web服务器使用不同的端口,设置不同的最大连接数

1、设计方案

2、添加被控主机,并定义主机变量

vim /etc/ansible/hosts

[[email protected] ~]# vim /etc/ansible/hosts

[websrvs]
192.168.30.20 http_port=80 http_maxclients=300
192.168.30.13 http_port=8080 http_maxclients=200

[dbsrvs]
192.168.30.14

3、配置ssh基于密钥认证

[[email protected] ~]# ssh-keygen -t rsa
...
[[email protected] ~]# ssh-copy-id -i .ssh/id_rsa.pub [email protected]
...
[[email protected] ~]# ssh [email protected] ‘hostname‘
node4
#以同样的方式将公钥文件复制到其它被控节点

4、创建各级目录,准备好需要的各种文件和模板

[[email protected] ~]# mkdir -p roles/{web,php,mysql,wordpress}/{files,templates,tasks,handlers,vars}
[[email protected] ~]# ls roles
mysql  php  web
[[email protected] ~]# ls roles/web/
files  handlers  tasks  templates  vars
[[email protected] ~]# cp httpd.conf roles/web/templates/template.j2
[[email protected] ~]# vim roles/web/templates/template.j2
[[email protected] ~]# cp -r wordpress roles/wordpress/files/
[[email protected] ~]# cp wp-config-sample.php roles/wordpress/files/wp-config.php
[[email protected] ~]# vim roles/wordpress/files/wp-config.php 

<?php
/** 
 * WordPress 基础配置文件。
 *
 * 本文件包含以下配置选项:MySQL 设置、数据库表名前缀、密匙、
 * WordPress 语言设定以及 ABSPATH。如需更多信息,请访问
 * {@link http://codex.wordpress.org/zh-cn:%E7%BC%96%E8%BE%91_wp-config.php
 * 编辑 wp-config.php} Codex 页面。MySQL 设置具体信息请咨询您的空间提供商。
 *
 * 这个文件用在于安装程序自动生成 wp-config.php 配置文件,
 * 您可以手动复制这个文件,并重命名为“wp-config.php”,然后输入相关信息。
 *
 * @package WordPress
 */

// ** MySQL 设置 - 具体信息来自您正在使用的主机 ** //
/** WordPress 数据库的名称 */
define(‘DB_NAME‘, ‘wpdb‘);

/** MySQL 数据库用户名 */
define(‘DB_USER‘, ‘tuser‘);

/** MySQL 数据库密码 */
define(‘DB_PASSWORD‘, ‘tpass‘);

/** MySQL 主机 */
define(‘DB_HOST‘, ‘localhost‘);

/** 创建数据表时默认的文字编码 */
define(‘DB_CHARSET‘, ‘utf8‘);

[[email protected] ~]# cp my.cnf roles/mysql/files/
时间: 2024-10-25 14:54:26

轻量级自动化运维工具ansible之二:playbook详解的相关文章

轻量级自动化运维工具ansible之一:介绍及初步使用

一.常见的自动化运维工具: OS Provisioning:PXE, Cobbler OS Config:puppet, saltstack, chef, func Task Exec:fabric, saltstack, func Program Deployment:fabric 管理主机控制被管理节点的方式: agent:被管理节点上需要安装代理程序以接受管理主机的操作:如puppet, func agentless:被管理节点不需安装代理程序,管理主机借助ssh传递操作指令,如ansib

自动化运维工具Ansible详细部署 (转载)

自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1579894 ========================================================================================== 一.基础介绍 ===========================

自动化运维工具-Ansible基础

目录 自动化运维工具-Ansible基础 自动化运维的含义 Ansible 基础及安装 Ansible的架构 Ansible的执行流程 ansible配置文件 ansible Inventory(主机清单文件) Ansible ad-hoc ansible常用模块 实战 自动化运维工具-Ansible基础 自动化运维的含义 1.手动运维时代 2.自动化运维时代 3.自动化运维工具给运维带来的好处 Ansible 基础及安装 1.什么是Ansible Ansible是一个自动化统一配置管理工具 2

自动化运维工具——ansible详解案例分享

自动化运维工具--ansible详解案例分享(一)目录ansible 简介ansible 是什么?ansible 特点ansible 架构图ansible 任务执行ansible 任务执行模式ansible 执行流程ansible 命令执行过程ansible 配置详解ansible 安装方式使用 pip(python的包管理模块)安装使用 yum 安装ansible 程序结构ansible配置文件查找顺序ansible配置文件ansuble主机清单ansible 常用命令ansible 命令集a

3.1 自动化运维工具ansible

自动化运维工具ansible 运维自动化发展历程及技术应用 Iaas 基础设施即服务Pass 平台服务SaaS 软件即服务 云计算工程师核心职能 Linux运维工程师职能划分 自动化动维应用场景 文件传输命令执行 应用部署配置管理任务流编排 企业实际应用场景分析 1 Dev开发环境 使用者:程序员功能:程序员开发软件,测试BUG的环境管理者:程序员123 2 测试环境 使用者:QA测试工程师功能:测试经过Dev环境测试通过的软件的功能管理者:运维说明:测试环境往往有多套,测试环境满足测试功能即可

运维工具Ansible浅谈playbook讲解以及YAML语法和JSON语法的互化

引言:运维发展到今天已经远远不是传统的运维做一些重复性的枯燥工作,面对海量爆发的访问量,传统的运维已经很吃力,比如让你装三五台机器的系统,这个so easy,那要是安装几百上千台呢,还easy吗.我要安装nginx服务,并提供好相应的端口转发机制以及location资源访问机制,但是有多发十几台这样的机制,并且每台机器转发机制都不相同,这个对我们来说是一个不小的挑战,因此运维进入了自动化时代,自动化运维就显得重要了.因此本文就是围绕自动化运维工具Ansible来展开的. 一,为什么要使用Ansi

自动化运维工具Ansible详细部署

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1579894 ========================================================================================== 一.基础介绍 =========================================================

自动化运维工具Ansible实战(一)安装部署

1,基本介绍 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批量程序部署.批量运行命令等功能. ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.主要包括: (1).连接插件connection plugins:负责和被监控端实现通信: (2).host inventory:指定操作

自动化运维工具Ansible部署详解与基本使用

一.基础简介 1.Ansible简介 Ansible是一款基于Python开发的自动化运维工具,主要是实现批量系统配置.批量程序部署.批量运行命令.批量执行任务等等诸多功能.Ansible是一款灵活的开源工具,能够很大程度简化运维中的配置管理与流程控制方式,它利用推送方式对客户系统加以配置,这样所有工作都可在主服务器端完成.Asible是基于模块工作的,其本身没有批量部署的能力,总之只要明白Ansible是一款运维自动化的神器就好了~! 2.功能特性 ######################