自动化运维工具ansible:(二)playbook剧本的讲解与应用

目录

一:playbook概述

1.1playbook介绍

1.2 Ansible playbook使用场景

1.3yaml基本语法规则

1.4yaml支持的数据结构

1.5示例

二:Inventory中变量

2.1inventor 变量参数 

三:playbook示例 

3.1为每个任务定义远程执行用户 

3.2指定远程主机切换用户执行剧本 

3.3tasks忽略错误,强制返回成功 

3.4针对多个主机节点执行剧本 

3.5Handlers介绍

3.6引入变量 

3.6.1通过ansible命令参数-e传递

3.6.2直接在yaml中定义,或者内置变量 

3.6.3引用主机清单内自定义变量 

3.7条件测试 

3.7.1单条件判断

3.7.2多条件判断 

3.7.3组条件判断 

3.7.4迭代

一:playbook概述

1.1playbook介绍

playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list ,而被控节点必须要完成。也可以这么理解,playbook 字面意思,即剧本,现实中由演员按照剧本表演,在 Ansible 中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。

playbook是剧本的意思
通过 task 调用 ansible 的模块将多个 play 组织在一 个playbook中运行。

playbook本身由以下各部分组成:

  • Tasks: 任务,即调用模块完成的某操作;原理和事务一样,要么一起执行,要么一起不执行。
  • Variables: 变量;声明变量的三个场景:hosts文件中定义、剧本中定义、在命令中加上-e定义。
  • Templates: 模板;定义模板同一格式,解决每个服务可能因格式不一样而不兼容的问题。
  • Handlers: 处理器,当某条件满足时,触发执行的操作
  • Roles: 角色;将任务分类执行,彼此之间互不干扰

Playbook 的核心元素:

  • Hosts:主机组;
  • Tasks:任务列表;
  • Variables:变量,设置方式有四种;
  • Templates:包含了模板语法的文本文件;
  • Handlers:由特定条件触发的任务;

1.2 Ansible playbook使用场景

  • 执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行的ad-hoc命令是不适合的,这时最好使用playbook。
  • 就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
  • 使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。在你使用Ansible的过程中,你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。

1.3yaml基本语法规则

playbook yaml语法是换行空两格,-和:后必须空一格

YAML:是一种非标记语言。是用来写配置文件的语言,非常简洁合强大;

YAML语法和其他语言类似,也可以表达散列表、标量等数据结构

结构通过空格来展示,序列里配置项通过 - 来表示;Map里的键值用:来分隔;YAML的扩展名为yaml

  1. 大小写敏感
  2. 使用缩进表示层级关系
  3. 缩进时不允许使用tab键、只允许使用空格
  4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

语法介绍:

  1. 在单一档案中,可用连续三个连字号(---)区分多个档案。另外,还有选择性的连续三个点号( ... )用来表示档案结尾
  2. 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  3. 使用#号注释代码
  4. 缩进必须是统一的,不能空格和tab混用
  5. 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
  6. YAML文件内容是区别大小写的,k/v的值均需大小写敏感
  7. k/v的值可同行写也可换行写。同行使用:分隔
  8. v可是个字符串,也可是另一个列表
  9. 一个完整的代码块功能需最少元素需包括 name: task
  10. 一个name只能包括一个task
  11. YAML文件扩展名通常为yml或yaml
hosts 定义节点,可以是组
remote_user 是你以什么用户身份进行登陆
tasks 是你的任务
become:yes 表示切换用户
become_user: mysql 表示切换到mysql用户,配合上一条使用
- name: 为下面执行的操作起名

1.4yaml支持的数据结构

  1. 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes)/ 字典(dictionary)
  2. 数组:一组按次序排列的值,又称为序列(sequence)/ 列表(list)
  3. 纯量:单个的、不可再分的值

1.对象:键值对的集合,又称为映射(mapping) /哈希(hashes) /字典(dictionary)
例如: name:Test Developer
     变量名:对象名  属性

2.数组: 一组按次序排列的值,又称为序列(sequence) / 列表(list)
例如: -Apple
     -Green

3.纯量: 单个的,不可再分的值
例如: number: 17.50
     变量名:数值

1.5示例

---
#安装与运行mysql服务
- hosts: node1
  remote_user: root
  tasks:
 
    - name: install mysql-server package
      yum: name=mysql-server state=present
    - name: starting mysqld service
      service: name=mysql state=started

我们的文件名称应该以 .yml 结尾,像我们上面的例子就是 mysql.yml。其中,有三个部分组成:

hosts :使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts 也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的 /etc/ansible/hosts,也可以自己编辑,在运行的时候加上 -i 选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts 选项会显示那些主机将会参与执行 task 的过程中。

remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。

tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

templates:包含了模板语法的文本文件;

使用 ansible-playbook 运行 playbook 文件,得到如下输出信息,输出内容为 JSON 格式。并且由不同颜色组成,便于识别。一般而言:

| 绿色代表执行成功,系统保持原样

| 黄色代表系统代表系统状态发生改变

| 红色代表执行失败,显示错误输出

执行有三个步骤:

  1. 收集 facts
  2. 执行 tasks
  3. 报告结果

二:Inventory中变量

Inventory是Ansible管理主机信息的配置文件,相当于系统HOSTS文件的功能,默认存放在/etc/ansible/hosts

主机清单可以手动设置,也可以通过Dynamic Inventory动态生成

主机清单:

vi /etc/ansible/hosts
[webserver]              #使用方括号设置组名
www1.example.org         #定义被监控主机,这边可以是主机名也可以是IP地址
www2.example.org:2222    #冒号后定义远程连接端口,默认是ssh的22端口

如果是名称类似的主机,可以使用列表的方式标识各个主机

[webserver]
//[01:50]表示匹配从01到50,后面跟着内置变量,这里定义了ssh的访问的用户名和密码,用于免交互登录
www[01:50].example.org ansible_ssh_user=root ansible_ssh_pass=abc123
 
[dbbservers]
//[a:f]表示支持匹配a到f
db-[a:f].example.org

Inventory中的变量

1、主机变量

[webserver]
//定义变量http_port(开放的端口信息)和maxRequestsChild(最大进程数)
www1.magedu.com http_port=80 maxRequestsChild=808
www2.magedu.com http_port=8080 maxRequestsChild=909

2、组变量

[servers:vars]
ntp_server=ntp.example.org
nfs_server=nfs.example.org

3、组嵌套 

[apache]
http1.example.org
http2.example.org
 
[nginx]
ngx1.example.org
ngx2.example.org
//定义一个组名,将刚才定义的两个组名放入,即webservers组包含apache组和nginx组的主机
[webservers]
apache
nginx

2.1inventor 变量参数 

参数 说明
ansible_ssh_host 将要连接的远程主机名,与你想要设定的主机的别名不同的话,可通过此变量设置
ansible_ssh_port ss 端口号,如果不是默认的端口号,通过此变量设置
ansible_ssh_user 默认的ssh用户名
ansible_ssh_pass ssh密码(这种方式并不安全,我们强烈建议使用 --ask-pass或SSH密钥)
ansible_ssh_private_key_file ssh使用的私钥文件,适用于有多个密钥,而你不想使用SSH代理的情况
ansible_ssh_common_args 此设置附加到sftp,scp和ssh的缺省命令行
ansible_sftp_extra_args 此设置附加到默认sftp命令行
ansible_scp_extra_args 此设置附加到默认scp命令行
ansible_ssh_extra_args 此设置附加到默认ssh命令行
ansible_ssh_pipelining 确定是否使用SSH管道。这可以覆盖ansible.cfg中得到设置
ansible_shell_type 目标系统的shell类型,默认情况下,命令的执行使用sh语法,可设置为csh 或 fish
ansible_python_interpreter 目标主机的python路径,适用于的情况:系统中有多个python,或者命令路径不是“/usr/bin/python”
ansible_*_interpreter 这里的*可以是ruby或perl或其他语言的解释器,作用和ansible_python_interpreter类似
ansible_shell_executable 这将设置ansible控制器将在目标机器上使用的shell,覆盖ansible.cfg中的配置,默认为/bin/sh

三:playbook示例 

基本命令介绍

格式:
ansible-playbook [yaml文件名]
例如:ansible-playbook ping.yml
参数:-k(–ask-pass) 用来交互输入ssh密码
     -K(-ask-become-pass) 用来交互输入sudo密码
     -u 指定用户
 
补充命令:
ansible-playbook XXXX.yaml --syntax-check   #检查yaml文件的语法是否正确
ansible-playbook XXXX.yaml --list-task      #检查tasks任务
ansible-playbook XXXX.yaml --list-hosts     #检查生效的主机
ansible-playbook XXXX.yaml --start-at-task='ensure apache is at the latest version'  #指定从某个task开始运行
参数 说明
-k(-ask-pass) 用来交互输入ssh密码
-K(-ask-become-pass) 用来交互输入sudo密码
-u 指定用户
-e 引入变量值

hosts 和 users 介绍

 - hosts: webserver   #指定主机组,可以是一个或多个组
   remote_user: root  #指定远程主机执行的用户名

3.1为每个任务定义远程执行用户 

cd /opt
vim 1.yaml
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: test connection
    ping:
    remote_user: mysql    #指定远程主机执行tasks的运行用户为mysql
	
ansible mysql -m user -a 'name=mysql'
ansible mysql -m shell -a 'echo 123123 | passwd --stdin mysql'
ansible-playbook 1.yaml -k
123123

3.2指定远程主机切换用户执行剧本 

vim 2.yaml
 
- hosts: mysql
  remote_user: root
  become: yes         
  become_user: mysql   
  tasks:
  - name: copy text
    copy: src=/etc/fstab dest=/home/mysql/fstab.bak
 
ansible-playbook 2.yaml

在mysql主机上查看复制的文件

ls /home/mysql

一个yaml文件中可以写多个hosts,定义多个主机组

vim hosts.yaml
- hosts: webserver
  remote_user: root
  tasks:
   - name: create nginx group
     group: name=nginx system=yes gid=208
   - name: create nginx user
     user: name=nginx uid=208 group=nginx system=yes
- hosts: mysql
  remote_user: root
  tasks:
   - name: copy file to mysql
     copy: src=/etc/inittab dest=/opt/inittab.back

3.3tasks忽略错误,强制返回成功 

1、Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始。在运行playbook时 (从上到下执行),如果一个host执行task失败, 整个tasks都会回滚,请修正playbook中的错误,然后重新执行,即Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为其结果一定的。
2、每一个task必须有一个名称 name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。
3、定义一个task,常见的格式: ”module: options" 例如: yum: name =httpd
4、ansible的自带模块中,command模块和shell模块无需使用key=value格式

错误示例:遇到错误task自动停止,apache服务不会继续安装

vim 3.yaml
 
- hosts: webserver
  remote_user: root
  tasks:
  - name: stop selinux
    command: '/usr/sbin/setenforc 0'
  - name: install httpd
    yum: name=httpd
  - name: start httpd
    service: name=httpd state=started
 
ansible-playbook 3.yaml

加入ignore_errors: True 忽略错误,报错后继续执行 

vim 3.yaml
 
- hosts: webserver
  remote_user: root
  tasks:
  - name: stop selinux
    command: '/usr/sbin/setenforc 0'
    ignore_errors: True
  - name: install httpd
    yum: name=httpd
  - name: start httpd
    service: name=httpd state=started
                                                   
ansible-playbook 3.yaml                       

3.4针对多个主机节点执行剧本 

vim 4.yaml
  
- hosts: webserver
  remote_user: root
  tasks:
  - name: remove httpd
    yum: name=httpd state=absent
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: copy file
    copy: src=/etc/fstab dest=/opt/haha.txt

3.5Handlers介绍

Handlers也是一些task的列表, 和一般的task并没有什么区别。
是由通知者进行的notify,如果没有被notify,则Handlers不会执行,假如被notify了 ,则Handlers被执行不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次

vim 5.yaml
 
- hosts: webserver
  remote_user: root
  tasks:
  - name: remove httpd
    yum: name=httpd state=absent
 
  - name: start firewalld
    service: name=firewalld state=started
 
  - name: setenforce 0 && install httpd
    command: '/usr/sbin/setenforce 0'
    notify:
    - step one
 
  - name: stop firewalld && start httpd
    service: name=firewalld state=stopped
    notify:
    - step two
 
  handlers:
 
  - name: step one
    yum: name=httpd
 
  - name: step two
    service: name=httpd state=started
 
 
ansible-playbook 5.yaml

3.6引入变量 

playbook引入变量有三种方式:

  1. 通过ansible命令参数-e传递
  2. 直接在yaml中定义
  3. 引用主机清单中定义的变量

3.6.1通过ansible命令参数-e传递

执行命令: ansible-playbook a.yml -e "user=wangwu"
 
执行命令查看: ansible mysql -m command -a 'tail /etc/passwd'
vim 6_1.yaml
 
- hosts: mysql
  remote_user: root
  vars:
  - user:
  tasks:
  - name: add user
    user: name={
   
   {user}}
 
ansible-playbook 6_1.yaml -e "user=wangwu"
ansible mysql -a 'tail -1 /etc/passwd'

3.6.2直接在yaml中定义,或者内置变量 

vim 6_2.yaml
 
- hosts: mysql
  remote_user: root
  vars:
  - user: lisi
  tasks:
  - name: add user
    user: name={
   
   {user}}
 
ansible-playbook 6_2.yaml
ansible mysql -a 'tail -1 /etc/passwd'
vim 6_2.yaml
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{
   
   {ansible_all_ipv4_addresses}}" dest=/opt/vars.txt
 
ansible-playbook 6_2.yaml
ansible mysql -a 'ls /opt'
ansible mysql -a 'cat /opt/vars.txt'

3.6.3引用主机清单内自定义变量 

vim /etc/ansible/hosts
 
[webserver]
192.168.184.20
[mysql]
192.168.184.30  user=zhaoliu
 
vim 6_3.yaml
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: add user
    user: name={
   
   {user}}
 
ansible-playbook 6_3.yaml
ansible mysql -a 'tail -1 /etc/passwd'

3.7条件测试 

如果需要根据变量、facts (setup) 或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用。在task后添加when子句即可使用条件测试: when子句支持 jinjia2 表达式或语法

3.7.1单条件判断

vim 7_1.yaml
 
 - hosts: mysql
   remote_user: root
   tasks:
     - name: "shutdown CentOS"
       command: /sbin/shutdown -h now
       when: ansible_distribution == "CentOS"
 
ansible-playbook 7_1.yaml

3.7.2多条件判断 

vim 7_2.yaml
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: "shut down CentOS 7 systems"
    command: /sbin/shutdown -r now
    when:
    - ansible_distribution == "CentOS"
    - ansible_distribution_major_version == "7"
 
ansible-playbook 7_2.yaml

3.7.3组条件判断 

vim 7_3.yml
 
- hosts: mysql
  remote_user: root
  tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
 
ansible-playbook 7_3.yaml

3.7.4迭代

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

vim 7_5.yaml
 
- hosts: webserver
  remote_user: root
  tasks:
  - name: install
    yum: name={
   
   {item}} state=latest
    with_items:
    - httpd
    - rpcbind
    - nfs-utils
 
ansible-playbook 7_5.yaml
ansible webserver -a 'rpm -q httpd'
ansible webserver -a 'rpm -q rpcbind'
ansible webserver -a 'rpm -q nfs-utils'

也可以自己定义item变量 

vim 7_5.yaml
 
- hosts: webserver
  remote_user: root
  tasks:
  - name: add user && join group
    user: name={
   
   {item.x}} state=present group={
   
   {item.y}}
    with_items:
    - {x: 'qianqi', y: 'wheel'}
    - {x: 'sicong', y: 'root'}
 
ansible-playbook 7_5.yaml
ansible webserver -a 'tail -2 /etc/passwd'

其中:
name表示要操作的软件包的名字;
state标识要做什么操作;
present:默认的,表示为安装;
lastest:安装为最新的版本;
absent:表示删除。

猜你喜欢

转载自blog.csdn.net/ver_mouth__/article/details/126214769
今日推荐