[ansible入门一]https://blog.csdn.net/ck784101777/article/details/102593155
1.第一种武器 ansible
ansible命令,用于执行临时性工作,必须掌握
2.第二种武器 ansible-doc
ansible-doc是ansible模块的文档说明,针对每个模块都有详细的说明及应用案例介绍,功能和Linux系统man命令类似
3.第三种武器 ansible-console
ansible-console是ansible为用户提供的交互式工具,用户可以再ansible-console虚拟出来的终端上像用Sheel一样使用ansible内置命令.这为习惯使用shell交互式的用户提供了体验
4.第四种武器 ansbile-galaxy
ansbile-galaxy从github上下载管理Roles的一款工具,与python的pip类似
5.第五种武器 ansible-playbook
ansible-playbook是日常应用中使用频率最高的命令,工作机制是通过读取先编写好的playbook文件实现批量管理,可以理解为按一定条件组成的ansible任务集
6.第六种武器 ansible-valut
ansible-valut主要用于配置文件加密,如编写的playbook文件中包含敏感信息,不能随意让人查看,可以通过ansible-vault加密次文件
7.第7种武器 ansbile-pull/push
ansbile-pull,ansible有两种工作模式pull/push,默认使用push模式工作,pull和push工作模式机制刚好相反.push将命令推送至远程,pull从远程加载命令
适用与大批量机器需要配置,即使使用高并发线程仍旧需要花费很多时间,其效率几乎可以无限提升,对运维人员技术水平和前瞻性规划有较高要求
本章重点将ansible-playbook这一用法
学习anisble-playbook分为以下步骤:
了解playbook是什么->了解playbook的语法格式(了解yaml,playbook由yaml语言编写)->了解playbook的语法中play的构成->能看懂playbook的执行结果(了解JSON,显示结果以JSON输出)
1.playbook是什么
playbook是ansbile用于配置,部署和管理托管主机的剧本,通过playbook的详细描述,执行其中的一些列tasks,可以让远端主机达到预期状态,也就是说,playbook字母字母意思即剧本,现实中由演员按剧本表演,在ansible中由计算机进行安装,部署应用提过对外服务,以及组织计算机处理各种各样的事
2.为什么使用playbook
批量处理机器的常规操作是写一个循环脚本,通过ssh远程执行操作,常规的方式首先是脚本与客户机耦合性高,如果托管机ip变动还要修改脚本.而playbook可以反复使用编写好的代码,且仅放在管理机上.playbook像函数一样,最大化的利用代码,在使用ansible的过程中,处理的大部分操作都是在别写playbook
而且anible提供了大量的模块,都可以在playbook中使用
3.playbook的语法格式
-playbook由YAML语言编写,遵循YAML标准
-在同一行中,#之后的内容表示注释
-同一个列表中的元素应该保持相同的缩进
-playbook由一个或多个play组成
-play包含hosts,variables,roles,tasks等对象,其表示方法都是键值中间以":"分隔表示
-YAML还有一个小的怪癖,它的文件开始必须写---,这是YAML格式的一部分,表明一个文件的开始,如同shell的#!/bin/bash
3.5YAML语言(补充)
YAML基础语法:
-YAML的结构通过空格来展示
-数组使用'-'表示
-键值对通过':'表示
-使用缩进表示数据层级结构关系
-一般每个缩进由两个以上空格组成(非必须,但是不要使用tab,且保证至少有一个空格的缩进)
-#表示注释
例子:
键值对: "名字":"流的华"
或 "名字":
"流的华"
数组: "名字":
-"流的华"
-"锅富成"
-"章学游"
以上三个值都隶属于'名字'这个键
4.play的构成
-hosts:定义将要执行playbook的远程主机组
-remote_user:定义使用什么用户执行命令(一般是root)
-vars:定义playbook运行时需要使用的变量
-tasks:定义将要在远程主机上执行的任务列表
-handlers:定义task执行完成后需要调用的任务
5.playbook执行结果
-使用ansible-playbook运行playbook文件,输出内容为JSON格式,由不同颜色组成便于识别
-绿色代表执行成功
-黄色也是执行成功,一般是文件被改动后显示黄色,并显示change:ture
-红色代表执行失败
-***代表系统状态发生改变
5.5.JSON(补充)
-Json是JavaScript对象表示法,它是一种基于文本独立与语言的轻量级数据交换格式
-JSON中的分隔符限于单引号"'",小括号"()",中括号"[]",大括号"{}",冒号":"和逗号""
-JSON是纯文本语言,具备自我描述性(人类可读)和层级结构(支持值中值),不具备逻辑性(无逻辑编程语句),可通过JavaScript进行解析
格式:
键值对: {"名字":"流的华"}
数组:{"名字":["流的华","章学油"]}
数组(值中值,嵌套): {"名字":[{"流的华":"长的帅","年龄":20}
{"章学油":"唱的好","年龄":21}
]
}
规则:
-无论是数组还是单个键值对,都必须加"{}"
-数组,确定一个键名,值必须要用"[]"扩起来
-数组支持值中值模式,即定义了一个键,键里面仍然可以创建键值对,要求每一对键值对用"{}"扩起
-数字型不需要双引号扩扩起来
编写一个ansible-play剧本需要以下步骤:
定义组->创建并编写playbook剧本-->执行剧本
接下来我会举出若干个例子,在每个例子中你都会看到一些模块和play动作的具体使用方式
1.案例1-批量创建用户
要求:为所有主机添加用户zhangsan,设置密码123
1)创建组
在上一节我讲述了aansible配置文件查找顺序以及管理机分发证书文件,看不懂的请回顾上一篇文章(开头有连接)
- [root@ansible ansible] cd /etc/ansible
- [root@ansible ansible] mkdir myansible
- [root@ansible ansible] vim myhosts
- [web]
- web1
- web2
- [all:vars]
- ansible_ssh_private_key_file="/root/.ssh/id_rsa"
2)编写playbook剧本
.yml文件必须严格遵守yaml格式,上节有讲.遵守层级规矩,相同层对齐,子层保证缩进至少一个空格,"-"和":"后要打一个空格,然后才能写值
执行playbook剧本的格式:ansible-playbook *.yml
这里有一个细节,那就是user模块的password参数,是不是看不懂?看不懂就对了,常规的创建密码命令应该是:echo 123 | passwd --stdin zhangsan(我完全可以用shell模块执行这条命令),而这里我用到了一个变量过滤器,事实上如果你使用常规的方式,ansible的shell模块会将password直接写入shadow,并没有用密码占位符,由于用户登录需要将密码加密之后核对,但是此时用于核对的密码是没有经过加密的,那么问题就来了,这肯定就对不上了,所以你无法登录
如下:
所以你需要用到变量过滤器(Linux采用sha512加密):
password_hash
格式{{'urpassword' | password_hash('sha512')}}
- [root@ansible ansible] vim createUsers.yml
- ---
- hosts: web
remote_user: root
tasks:
- user:
name: zhangsan
password: "{{'123456' | password_hash('sha512')}}"- [root@ansible ansible]# ansible-playbook createUsers.yml
- PLAY [web] ******************************************************************
- TASK [Gathering Facts] ********************************************************
- ok: [web]
- TASK [create user zhangsan] ***********************************************
- changed: [web]
- TASK [command] ****************************************************************
- changed: [web]
- PLAY RECAP ********************************************************************
- cache : ok=4 changed=2 unreachable=0 failed=0
2.案例2-批量创建用户进阶,使用变量
案例1创建用户有一个局限性,就是一个脚本只能创建一个用户,下次要创建不同的用户只能修改脚本,用户和脚本的耦合性比较高,我们可以使用变量来解放这种耦合.以下提供四种方式来使用变量
首先我们要修改一下脚本,我们通过"{{key}}"来使用变量,双括号中放的是键名
---
- hosts: web
remote_user: root
tasks:
- user:
name: "{{user}}"
password: "{{'123456' | password_hash('sha512')}}"
1)直接输入变量(外部)
格式:ansible-playbook *.yml -e "键=值"
ansible-playbook userCreate.yml -e "user=lisi"
2)引用json变量(外部)
首先要创建一个json文件,在里面写下数据
vim user.json
{"user":"zhangsan"}
格式:ansible-playbook *.yml -e "@*.json" #引用的时候前面要加一个@,别问为什么,规矩
ansible-playbook userCreate.yml -e "@user.json"
3)引用yml变量(外部)
首先要创建一个yml文件,在里面写下数据
vim user.yml
---
user: zhangsan
格式:ansible-playbook *.yml -e "@*.yml" #引用的时候前面要加一个@,别问为什么,规矩
ansible-playbook userCreate.yml -e "@user.yml"
4)使用脚本内置变量(内置)
使用vars:
键:值
---
- hosts: web
remote_user: root
vars :
user: zhaoqiang
tasks:
- user:
name: "{{user}}"
password: "{{'123456' | password_hash('sha512')}}"
3.案例3-批量安装Apache服务
要求:用playbook安装Apache,修改端口,配置ServerName,修改主页,设置开机自启
组我就不定义了,参考案例1
1)编写playbook剧本
关于ansible模块的使用我在上一篇文章有描述,文章开头有链接
这里主要用到yum模块,lineinfile模块,copy模块和service模块
步骤:
1_安装apache
2_将apache的端口修改为8080,采用lineinfile模块
3_启动服务
4_将本地的index.html拷贝到每台托管机中
5_测试
- [root@ansible ansible]# echo "hello world" > index.html
- [root@ansible ansible]# vim http.yml
- ---
- - hosts: cache
- remote_user: root
- tasks:
- - name: install one specific version of Apache
- yum:
- name: httpd //安装Apache
- state: installed
- - lineinfile:
- path: /etc/httpd/conf/httpd.conf
- regexp: '^Listen '
- line: 'Listen 8080' //修改端口为8080
- - service:
- name: httpd
- enabled: yes //开机自启
- state: restarted
- - copy:
- src: /root/index.html //修改主页,可以自己写个页面
- dest: /var/www/html/index.html
- [root@ansible ansible]# ansible-playbook http.yml
- [root@ansible ansible]# curl 192.168.1.45:8080 //测试
- hello world
4.案例4-忽视报错,继续执行脚本
ansible-playbook的对执行过程中报错的常规处理是停止执行脚本,但是很多情况我们不想让其停止执行,比如我们创建一个文件,如果该文件存在,那么这种时候ansible-playbook也会停止执行,可是我们不希望在这里停止执行,因为其对最终结果不会造成影响(如果文件本来就存在,那么即使我们不执行创建命令也会存在这个文件,所以整个过程的结果都是一样的,这就是程序的幂等性)
想要脚本不中断执行很简单,只需要加入一条参数即可
ignoring_errors:True
我们创建一个用户并把它加入一个并不存在的组,这里会报错,我们忽视错误,可以看到忽视错误,脚本还将继续执行
---
- hosts: web
remote_user: root
tasks:
- user:
name: "{{user}}"group: abc
password: "{{'123456' | password_hash('sha512')}}"ignoring_errors:True
...........
fatal: [web1]: FAILED! => {"changed": false, "msg": "Group iwq does not exist"}
...ignoring
对于何时该使用ignoring_errors:True是操作者需要加强锻炼的,一般需要有前瞻性,知道哪会出错,且这种错误不会在根本上影响最终结果.加强锻炼吧,萌新
5.案例5,重启apache服务,触发条件:配置文件被修改
案例说明:我们在编写playbook剧本时,有的部分不一定需要每次都执行,我们可以给它写一个触发条件,即当触发了某个条件后才执行这一部分.如我们在批量修改apache配置文件时,将原端口80改为8080,而有些主机已经是8080了,那我们就不需要重启这台主机的服务.
本例需要用到notify这个动作,notify可由于每个play的最后触发,copy有自检功能,它会比对你的文件与目标主机的文件,如果两者一样则不替换,如果内容不一致则将其替换,并且给出change提示.而notify会将change作为触发条件,选择是否执行.如果显示change,则调用接下来的handler动作,handler将执行定义好的的操作
执行顺序:
文件内容是否发生改变?
-没有改变,不触犯动作
-改变,nofity被触发,执行handle
本例采用copy模块,也可以使用lineinfile模块按行修改.如果使用copy你需要在管理主机上准备相应的文件
- [root@ansible ansible]# vim handers.yml
- ---
- - hosts: web
- remote_user: root
- tasks:
- - copy:
- src: httpd.conf
- dest: /etc/httpd/conf/httpd.conf
- owner: apache
- group: apache
- mode: 0644
- notify:
- - restart httpd
- handlers:
- - name: restart httpd
- service:
- name: httpd
- state: restarted
第一次执行,触发动作
第二次执行,不触犯动作
6.案例6,把系统负载太高的Apache服务停止
案例描述:使用uptime命令查看实时负载,当1分钟负载大于0.7的web服务器停掉
uptime #分别为1分钟负载,5分钟,10分钟
15:22:02 up 3:38, 1 user, load average: 0.48, 0.16, 0.09
本例要学习几个陌生的模块
register模块用来保存前一个命令的返回状态,可以在之后进行调用
格式:register: 键名
调用: 键名.stdout (stdout标准化输出)
when模块用于在满足指定条件后触发一项操作
格式: when 条件
- [root@ansible ansible]# vim when.yml
- ---
- - hosts: web
- remote_user: root
- tasks:
- - shell: uptime | awk '{printf("%.2f\n",$(NF-2))}' #NF从后面数,$.2f 占位符
- register: result
- - service:
- name: httpd
- state: stopped
- when: result.stdout|float > 0.7
#|float将标准化输出作为浮点数,因为register默认保存的是字符串,而字符串不能比较大小
使用awk 'BEGIN{while(1){}}'制造死循环增加负载
可以用watch -n 1 'uptime' 实时监控uptime的负载
7.案例7,一次性创建多个用户
本例需要用到with_items模块,用过item调用变量值
- ---
- - hosts: web
- remote_user: root
- tasks:
- - user:
- name: "{{item}}"
- password: "{{'123456' | password_hash('sha512')}}"
- with_items: ["wyf1","wyf2","wyf3","wyf4"]
进阶用法:with_items数组
引用方式item.键名
- ---
- hosts: web2
remote_user: root
tasks:
- name: add users
user:
name: {{item.name}}
group: {{item.group}}
password: {{'123456' | password_hash('sha512')}}
with_items:
- {name: 'nb', group: 'root'}
- {name: 'dd', group: 'root'}
- {name: 'plj', group: 'wheel'}
- {name: 'lx', group: 'wheel'
8.案例8,组合playbook
在编写playbook的时候随着项目越来越大,playbook越来越复杂。可以把一些play、task 或 handler放到其他文件中,通过包含进来是一个不错的选择
本例需要学习include模块,它可以引入一个项目的文件和目录
格式: include: 文件路径
- ...
- tasks:
- - include: tasks/users.yml #导入变量,可以通过{{ user }}来使用这些变量
- - include: tasks/useradd.yml #导入添加用户模块
- handlers:
- - include: handlers/handlers.yml #导入handles条件触发的执行模块
9.