Ansible-playbook简介

什么是playbook?

简单点说,playbook就是ansible用于配置,部署和管控节点机器的剧本,将一系列命令的集合归一使用,类似于shell脚本,不过更加强大.

playbook与shell脚本比对

它们功能形似,playbook和shell脚本一样,都是批量处理任务.都是把很多命令组合到一起,加入对应条件判断等,要说区别就是命令结构和被执行场景有所不同;

shell脚本由一条条命令构成,一般只在当前的服务器运行;

playbook中是有一个个task任务构成,每个task都可以当做shell中的一条命令,playbook不止在一个服务器上执行,因此它需要在其中指定运行该playbook的服务器名.而且playbook有着自己的语法格式

playbook语法格式

playbook由YMAL语言编写,YMAL格式类似于JSON格式,便于写读和理解,它的格式如下:

#格式
1.文件的第一行应该以 "---"这三个连续字符开始,代表了YAML文件的开始 2.在一行中, # 后面的内容代表注释,python,ruby,shell都是如此 3.YAML中的列表元素以"-"开头然后紧接着一个空格,后面为元素内容 4.在同一个列表中的元素应该保持相同的缩进,否则会当作错误处理 5.play中hosts ,variables,roles,tasks等对象的表示方法都是键值对,中间以 ":"分割,且":"后面还要增加一个空格. 6.文件名称后缀为 xxx.yml/yaml #示例
---
#复制file
- hosts: task01
remote_user: root
tasks:
- name: copyfile
copy: src=/etc/passwd dest=/tmp/data

Ansible-playbook使用

playbook核心参数

hosts    #主机组
tasks #任务列表
vars #变量,如下有几种设置方式
template #jinja2模板语法
tags #标签
handlers #由一定条件出发,就是notify咯

① 基本参数

#写法
--- #文件开头
- hosts: dbservers #指定该playbook在哪个服务器上执行
remote_user: root #指定远程的用户名,
vars: #表示定义变量
http_port: 80 #变量形式key: value
user: coco
tasks: #构成playbook的tasks,每个task都有 - name: 开始,name 指定该任务的名称
- name: copyfile
copy: src=/etc/fstab dest=/tmp/fs - name: install redis
yum: name=redis

② ansible-playbook -h命令分析

#常用命令
-C --check #检查但是不会真的执行
-f FORKS, --forks=FORKS #并发,默认5个
--list-hosts #列出匹配的主机
--sytax-check #检查语法
-t #只执行某个task任务

③ 执行一个playbook命令 --->ansible-playbook p1.yml (单任务)

#p1.yml
---
- hosts: web
tasks:
- name: install bc
yum: name=bc

注解:如上图所示

- PLAY表示执行hosts 中web组远程机器

- 第一个TASK表示正在收集两台远程机器的数据信息,采集成功为显示绿色,代表执行成功

- 第二个TASK表示我们要执行任务的名称,执行成功后状态发生变化为黄色,状态没变化为绿色,执行失败为红色.

④ 再来个例子ansible-playbook p2.yml(多任务)看看效果,会更加清楚

#p2.yml
---
- hosts: web
remote_user: root
tasks:
- name: createuser
user: name=coco
- name: deluser
user: name=coco state=absent

p2.yml

[root@localhost playbook]# ansible-playbook p2.yml 

PLAY [web] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.220.134]
ok: [192.168.220.136]
ok: [192.168.220.135] TASK [createuser] **************************************************************
changed: [192.168.220.134]
changed: [192.168.220.135]
changed: [192.168.220.136] TASK [deluser] *****************************************************************
changed: [192.168.220.134]
changed: [192.168.220.135]
changed: [192.168.220.136] PLAY RECAP *********************************************************************
192.168.220.134 : ok=3 changed=2 unreachable=0 failed=0
192.168.220.135 : ok=3 changed=2 unreachable=0 failed=0
192.168.220.136 : ok=3 changed=2 unreachable=0 failed=0

p2.yml执行结果

注意:执行后发现第一个task任务执行完后,第二个task任务才执行的,多个task是顺序执行的,所以先创建,再删除...

playbook幂等性

什么意思呢?就是不管执行多少次,得到的结果永远是相同的,试着一直执行p2.yml,最终的结构都一样.

playbook (5种传参方式)

为什么要这么做呢?

主要防止需求不断变化嘛,总不能反复修改文件是吧

方式一

---
#方式一
- hosts: web
remote_user: root
tasks:
- name: create{{user}}
user: name={{user}} ansible-playbook -e user=superman p1.yml #有没有发现什么?没错就是jinja2模板语法,

方式二

[web]
192.168.220.[134:135] user=laifu
192.168.220.136 user=wangcai #vi /etc/ansible/hosts
#针对hosts文件进行传参,执行结果web组为全部创建laifu
#实际上134,135会创建出laifu用户,136会创建出wangcai用户. ansible-playbook p1.yml

方式三

[web:vars]
user=taidi #还是在hosts文件传参,给web组vars进行传参
ansible-playbook p1.yml 会创建出一个taidi用户

方式四

- hosts: web
vars:
- user: jinmao
tasks:
- name: create{{user}}
user: name={{user}} #利用vars变量参数进行传参,执行后会创建出一个jinmao用户

方式五

- hosts: web
tasks:
- name: yumbc
yum: name=bc
- name: sum
shell: echo 8+9|bc #linux 计算通过bc
register: user #得到结果注册为user,但是拿到一个字典
- name: echo
shell: echo {{user.stdout}} >/tmp/sum.txt #将user字典中的stdout值取出来
- name: createuser{{user.stdout}}
user: name=keke{{user.stdout}} #执行创建出keke9 #上面先计算,注册user得到一个大字典,再取出user.stdout写到文件中,最后创建对应的参数的用户keke9

注:这五种传参优先级: -e >playbook的vars >hosts

setup模块

在playbook中负责收集信息,因此放在这里进行补充模块信息

① 执行命令 ansible 192.168.220.134 -m setup |more 收集信息

#如下是setup模块常用参数

ansible_all_ipv4_addresses # 所有的ipv4地址
ansible_all_ipv6_addresses # 所有的ipv6的地址
ansible_bios_version # 主板bios的版本
ansible_architecture # 架构信息
ansible_date_time # 系统的时间
ansible_default_ipv4 # IPv4默认地址
address #ip地址
alias #网卡名称
broadcast #广播地址
gateway # 网关
macaddress #mac地址
netmask #子网掩码
network #网段
ansible_distribution #系统的版本
ansible_distribution_file_variety# 系统的基于对象
ansible_distribution_major_version# 系统的主版本
ansible_distribution_version #系统的版本
ansible_domain #系统的域
ansible_dns #系统的dns
ansible_env #系统的环境变量
ansible_hostname #系统的主机名
ansible_fqdn #系统的完整主机名
ansible_machine #系统的架构
ansible_memory_mb #系统的内存信息
ansible_os_family #系统的家族
ansible_pkg_mgr #系统的包管理工具
ansible_processor_cores #cpu的核数
ansible_processor_count #每颗cpu上的颗数
ansible_processor_vcpus #cpu的总核数=cpu的颗数*每颗cpu上的核数
ansible_python #系统的python版本 #快速筛选查找,支持正则拼接
ansible 192.168.220.134 -m setup -a "filter=*processor*"

② 正则在linux中简单实用

[root@localhost playbook]# echo 123 |grep "[0-9]\{2\}"  #发现"{}"是需要转义的
123 #取到12 [root@localhost playbook]# echo 123 |grep "[0-9]\?" #?也需要转义
123 #取到123 [root@localhost playbook]# echo 123 |grep "^[0-9]"
123 #取到1
[root@localhost playbook]# echo 123 |grep "\<[0-9]" #^在linux中也可以写成\>放在起始位
123 #取到 1 [root@localhost playbook]# echo 123 |grep "[0-9]$"
123 #取到3
[root@localhost playbook]# echo 123 |grep "[0-9]\>" #^在linux中也可以写成\>放在末位
123 #取到3

tags

给某个task任务加上标签,执行的时候防止重复执行yml文件中已经执行过的命令

#p4.yml

---
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
copy: dest=/etc/redis.conf src=/etc/redis.conf
tags: copyall
- name: start
service: name=redis state=started #执行这条命令 ansible-playbook -t copyall p4.yml ,由于tags标签名称 copyall 存在于copyfile中上述的三个task任务就只执行copyfile的task,避免重复工作.

handlers

由notify 进行触发执行handlers中的任务

#p5.yml
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
copy: dest=/etc/redis.conf src=/etc/redis.conf
tags: copyall
notify: restart # 触发handlers中的task任务并执行
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted #为什么要这样写呢?
#其实我就是想copy下文件并重启,不想执行其它 的task任务的需求
#在copy的task任务的基础上无法再添加标签tags,这时有notify进行触发handlers参数,执行其中的task,是不是很方便呢

template

可以通过setup模块获取到的信息进行模板渲染到需要用的文件中.创建一个templates目录,将要渲染模板的文件放在目录中,通过jinja2语法进行替换文件中经常改动的内容

#redis.conf

bind {{ansible_default_ipv4.address}}  #替换redis绑定的ip地址,因为默认是本地的.当然还可以替换很多东西
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
template: dest=/etc/redis.conf src=redis.conf
tags: copyfile
notify: restart
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted #需要在本地的目录下创建一个templates目录,就可以用相对路径,在执行copyfile所在的task时就会执行templates中的redis.conf文件,实时将各个机器地址获取到

when

在task中使用,jinja2的语法格式

情景:比如在setup模块中可以获取到版本信息 ansible_distribution_version ,拿到是7,当版本为6的时候,同样的任务,执行的命令不尽相同,这时就需要判断了when

[root@localhost playbook]# ansible 192.168.220.134 -m setup -a "filter=*distribution*"
192.168.220.134 | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "CentOS",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "",
"ansible_distribution_release": "Core",
"ansible_distribution_version": "7.5.1804"
},
"changed": false
}

需求1:比如在版本6和版本7生成两个文件内容不同

#p7.yml
---
- hosts: web
tasks:
- name: file
copy: content="东船西舫悄无言" dest=/opt/file
when: ansible_distribution_major_version==""
- name: file
copy: content="唯见江心秋月白" dest=/opt/file
when: ansible_distribution_major_version=="" #ansible-playbook p7.yml 就会在对应Contos版本生成两个文件对应的内容
[root@localhost playbook]# ansible-playbook p7.yml 

PLAY [web] *****************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [192.168.220.135]
ok: [192.168.220.134]
ok: [192.168.220.136] TASK [file] ****************************************************************************************************************************************
changed: [192.168.220.135]
changed: [192.168.220.134]
changed: [192.168.220.136] TASK [file] ****************************************************************************************************************************************
skipping: [192.168.220.134]
skipping: [192.168.220.135]
skipping: [192.168.220.136] PLAY RECAP *****************************************************************************************************************************************
192.168.220.134 : ok=2 changed=1 unreachable=0 failed=0
192.168.220.135 : ok=2 changed=1 unreachable=0 failed=0
192.168.220.136 : ok=2 changed=1 unreachable=0 failed=0

需求1执行结果

由于我的虚拟机上并没有安装Centos6,因此当 ansible_distribution_major_version=="6" 的时候该task任务直接跳过了.

需求2.根据传值执行对应task

#p6.yml
---
- hosts: web
tasks:
- name: file
copy: content="大弦嘈嘈如急雨\n" dest=/opt/file
when: num==""
- name: file
copy: content="小弦切切如私语\n" dest=/opt/file
when: num=="" #ansible-playbook -e num=6 p6.yml #当固定给num传参的时候,task任务根据参数执行,此时执行的是num=='6'的task.
[root@localhost playbook]# ansible-playbook -e num=6 p6.yml 

PLAY [web] *****************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [192.168.220.136]
ok: [192.168.220.135]
ok: [192.168.220.134] TASK [file] ****************************************************************************************************************************************
skipping: [192.168.220.134]
skipping: [192.168.220.135]
skipping: [192.168.220.136] TASK [file] ****************************************************************************************************************************************
changed: [192.168.220.134]
changed: [192.168.220.135]
changed: [192.168.220.136] PLAY RECAP *****************************************************************************************************************************************
192.168.220.134 : ok=2 changed=1 unreachable=0 failed=0
192.168.220.135 : ok=2 changed=1 unreachable=0 failed=0
192.168.220.136 : ok=2 changed=1 unreachable=0 failed=0

需求2.执行结果

循环

也称迭代,当需要执行大量重复性工作的时候,对迭代项的引用,固定变量名为"item",在task中使用with_item给定要迭代的元素列表:

①简单循环

示例1

---
- hosts: web
tasks:
- name: createuser
user: name={{item}}
with_items:
- hanghang
- haha #执行后循环在web组内所有远程机器创建出,hanghang和haha两个用户

示例2

---
- hosts: web
tasks:
- name: creategroup
group: name={{item}}
with_items:
- 666
- 999
- name: createuser
user: name={{item}}
with_items:
- xxx
- ooo #类似于python中的两个for循环,分别创建组和用户

playbook字典功能

嵌套循环实现

---
- hosts: web
tasks:
- name: creategroup
group: name={{item}}
with_items:
- mama
- baba
- name: createuser
user: name={{item.name}} group={{item.group}}
with_items:
- {"name":lili,"group":mama}
- {"name":nana,"group":baba} #执行后 用户lili对应mama组;用户nana对应baba组

roles

roles的作用?

roles让playbook的众多yml文件执行更加规范,更好的进行管理yml文件,好处如下:

目录结构清晰;

可以互相调用,

nginx/
├── files #存放静态文件
│ └── fstab
├── handlers #存放需要触发的任务,里面必须main.yml文件
│ └── main.yml
├── tasks #存放的执行任务,里面必须main.yml文件
│ ├── copyfile.yml
│ ├── install.yml
│ ├── main.yml
│ └── start.yml
├── templates #存放模板文件
│ ├── centos6.conf
│ └── nginx.conf
└── vars #存放的是参数,里面必须main.yml文件
└── main.yml #入口文件与roles文件同级
- hosts :web
remote_user: root
roles:
- nginx

查找顺序

1.先查找当前目录下 roles目录里面指定的对应文件夹

2.找到tasks目录下面的main.yml文件,如果import_tasks就导入

3.如下

如果遇到了template,存放是动态文件setup,去找templates文件夹下面对应的文件

如果遇到notify,去找handlers里面的main.yml文件

files:存放的是静态文件

vars:存放的是参数,入口文件main.yml

如果发现变量,如果是setup收集的变量就去setup,如果不是就去vars里面main.yml文件查找

总结: Ansible rotes管理ansible playbook文件,形成结构化,ansible-playbook 文件管理繁多的命令.让凌乱的命令集成化和脚本化.从全面来看,ansible是一个优秀的管理工具

...

最新文章

  1. Android Studio在创建/导入项目的时候,一直处于building “XXX”gradle project info的解决办法
  2. UDP收发buffer尺寸对收发包流量的影响
  3. 【001:转载 ubuntu下: 建立本地SVN服务器】
  4. python : HTML+CSS (定时器轮寻)
  5. Android activity的回传数据
  6. hdu 3590 PP and QQ
  7. Gson解析POJO类中的泛型参数
  8. Java调用Telnet示例
  9. TC SRM 665 DIV2 A LuckyXor 暴力
  10. str*函数和大小端判断
  11. ES6笔记-正则表达式和字符串正则方法
  12. 自己动手写shell之chgrp,chown,chmod
  13. How to Use the UTL_MAIL Package
  14. swjtu 1962 A+B(模拟)
  15. 挖一下插件v1.3版本发布
  16. stl map容器 学习
  17. Xcode修改个性化注释
  18. Centos7 时区的设置
  19. js和jQuery的互相转换
  20. 【Ruby】Mac gem的一些坑

热门文章

  1. Nginx 站点设置目录列表显示
  2. 原生js写轮播图效果
  3. Spring系列(三) Bean装配的高级技术
  4. Ansible------角色
  5. C#(在WeBAPI)获取Oracle(在PL/SQL)游标类型的存储过程(用到了RefCursor)
  6. Ubuntu18.04更换官方默认更新源sources.list
  7. centos7中nfs文件系统的使用
  8. Mac ---- markdown 转 html\word\pdf
  9. Ubuntu18.04安装Python虚拟环境
  10. Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor