linux --- Ansible-playbook篇
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是一个优秀的管理工具
...
linux --- Ansible-playbook篇的更多相关文章
- ansible指路篇-安装及基本命令使用
ansible指路篇-安装及基本命令使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是ansible ansible是新出现的自动化运维工具,基于Python开发,集合 ...
- ansible playbook模式及语法
一.什么是playbook及其组成 什么是playbook playbook 翻译过来就是"剧本" playbook的组成 play:定义的是主机的角色 task:定义的是具体执行 ...
- Ansible--02 ansible playbook的应用
目录 Ansible playbook的应用 什么是playbook playbook的组成 playbook和Ad-Hoc对比 YAML语法 安装httpd练习 rsyncd实战 实战1: 实战2: ...
- Ansible playbook API 开发 调用测试
Ansible是Agentless的轻量级批量配置管理工具,由于出现的比较晚(13年)基于Ansible进行开发的相关文档较少,因此,这里通过一些小的实验,结合现有资料以及源码,探索一下Ansible ...
- Linux工具参考篇(网摘)
Linux工具参考篇 原文出处:[Linux Tools Quick Tutorial] 1. gdb 调试利器 2. ldd 查看程序依赖库 3. lsof 一切皆文件 4. ps 进程查看器 5. ...
- ansible playbook实践(四)-如何调试写好的playbook文件
有时,我们写了一个长长,功能很强悍的yaml文件,但是,我们有可能会担心,写的yaml文件是否正确,是否有漏洞危机,毕竟是要修改线上的机器,那么,有可能我们可以从以下几个检查维度来进行,确保在大规模应 ...
- 0x00-Kali Linux 系列入门篇
Kali Linux介绍篇 Kali Linux 官网:https://www.kali.org/ Kali Linux 前身是著名渗透测试系统BackTrack ,是一个基于 Debian 的 Li ...
- ansible playbook批量改ssh配置文件,远程用户Permission denied
最近手里的数百台服务器需要改/etc/ssh/sshd_config的参数,禁止root直接登陆,也就是说 [root@t0 ~]# cat /etc/ssh/sshd_config | grep R ...
- ansible笔记(11):初识ansible playbook(二)
ansible笔记():初识ansible playbook(二) 有前文作为基础,如下示例是非常容易理解的: --- - hosts: test211 remote_user: root tasks ...
- ansible笔记(10):初识ansible playbook
ansible笔记():初识ansible playbook 假设,我们想要在test70主机上安装nginx并启动,我们可以在ansible主机中执行如下3条命令 ansible test70 -m ...
随机推荐
- DUMP101 企业级电商FE
需求拆分原则 1. 单个迭代不能太大 2. 需求可交付,功能闭环 3. 成本意识 二八法则 4. 预期价值体现 ……………………………………………………………………………… 做 [直接 git cl ...
- 简单管理员权限与几个常用的PHP 常用函数,in_array(),explode(),implode(),join(),str_replace()
先把今天要用的几个函数罗列出来: //explode()转换成数组,implode()转化成字符串 explode("分隔符",需要被分割的字符串或变量) $priv=" ...
- python之使用单元测试框架unittest执行自动化测试
Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 单元测试框架即一堆工具的集合. 在说unittest ...
- du---查看文件夹大小-并按大小进行排序
使用df 命令查看当前磁盘使用情况: df -lh [root@gaea-dev-xjqxz-3 ~]$ df -lh Filesystem Size Used Avail Use% Mounted ...
- Django对于模型的数据操作
一.引入模型的包 from myApp.models import Grades,Students 二.查询所有数据 #objecs是类的隐藏属性:类名.objects.all()可以查询所有数据 G ...
- C# - LINQ 语言集成查询
LINQ(Language Integrated Query) LINQ语言集成查询是一组用于C#语言的扩展.它允许编写C#代码对数据集进行查询,比如查询内存中的对象或查询远程数据库的表.利用linq ...
- java 面经
1.什么是Java虚拟机(JVM)?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件. ...
- python学习第24天
内置方法 常用 __new__ __del__ __call__ 不常用 __str__ __repr__ __enter__ __exit__
- 【原创】大数据基础之Ambari(1)简介、编译安装、使用
官方:http://ambari.apache.org/ The Apache Ambari project is aimed at making Hadoop management simpler ...
- javascript中数组的方法
数组的方法 1.concat():连接两个或多个数组 2.indexOf(arg): 查找数组中的arg元素,如果没有,则返回-1,如果有,则返回该元素的最小下标 lastIndexOf(ar ...