Ansible特性
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
逻辑架构
- 在ansible控制端定义了被控制主机的列表,基于模块的方式 去控制远程主机。
- Ansible 不是一般的CS架构,因为他不提供什么服务,他就是控制端,被他控制的机器,就是被控制端,
- Ansible 没有客户端软件,他是基于key验证的,只要把ssh key验证做好,就可以了,所以他走的是ssh协议
利用ansible实现管理的方式:
- Ad-Hoc 即ansible命令,主要用于临时命令使用场景 (单个命令)
- Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期 的规划过程 (一个脚本)
- 通过Ansible api的方式。
组成
- ansible playbooks:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件, 相当于多条命令(一个脚本)
- INVENTORY:Ansible管理主机的清单/etc/ansible/hosts
- modules :Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
- PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
- API:供第三方程序调用的应用程序编程接口
- ANSIBLE:组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具,Ansible 模块相当于 一条命令(一个功能)
- Ansible Roles 相当于一个项目 (多个脚本)
安装 实现前提 防火墙 selinux 时间同步
rpm包安装: EPEL源:yum install ansible
编译安装: yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
tar xf ansible-1.5.4.tar.gz
cd ansible-1.5.4
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible
确认安装: ansible --version
软件相关文件
配置文件:
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/ 存放角色的目录
程序:
/usr/bin/ansible 主程序,临时命令执行工具
/usr/bin/ansible-doc 查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
/usr/bin/ansible-pull 远程执行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基于Console界面与用户交互的执行工具
具体配置
主机清单配置
ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
默认的inventory file主机清单:/etc/ansible/hosts 指定设备清单,也可以分组
/etc/ansible/hosts里面有很多 例子,可以写成如下分组,或者不分组,或者 在后面指定ssh端口
Ansible 主配置文件/etc/ansible/ansible.cfg (一般保持默认)
[defaults]
#inventory = /etc/ansible/hosts # 主机列表配置文件
#library = /usr/share/my_modules/ # 库文件存放目录
#remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数
#sudo_user = root # 默认sudo 用户
#ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22
#host_key_checking = False # 检查对应服务器的host_key,建议取消注释
#log_path=/var/log/ansible.log #日志文件,建议取消注释,打开日志
#module_name = command #默认模块
需要修改的地方就是
1、host_key_checking 在第一次ssh连接,不用输yes
2、log_path,记录日志的 打开 ;打开后我们通过ansible 执行的命令 就可以记录在日志中了
Ansible系列命令 工具: ansible, ansible-doc, ansible-playbook, ansible-vault, ansible-console, ansible-galaxy, ansible-pull
ansible-doc :查看模块帮助
-
-
-
-
- -a 显示所有模块的文档
- -l, --list 列出可用模块
- -s, --snippet显示指定模块的playbook片段
-
-
-
例子:
-
-
-
-
- ansible-doc -l ////查看所有模块列表
- ansible-doc -s 模块名 ////查看一个模块的具体帮助
-
-
-
ansible:
absible --help //查看帮助
ansible <host-pattern> [-m module_name] [-a args]
-
-
-
-
-
- --version 显示版本
- -m module 指定模块,不指定的话,默认为command,默认模块可以在 ansible.cfg修改
- -v 详细过程 –vv -vvv更详细
- --list-hosts 显示主机列表,可简写 --list
- -k, --ask-pass 提示输入ssh连接密码,默认Key验证
- -C, --check 检查,并不执行
- -T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
- -u, --user=REMOTE_USER 执行远程执行的用户
- -b, --become 代替旧版的sudo 切换
- --become-user=USERNAME 指定sudo的runas用户,默认为root
- -K, --ask-become-pass 提示输入sudo时的口令
-
-
-
-
例子 :对于中间的 主机选择,可以使用通配符 等等,逻辑上的运算,都可以很灵活
-
-
-
-
- ansible “*” -m ping /////*匹配到所有主机 与all一样的
- ansible 192.168.1.* -m ping ////
- ansible “*srvs” -m ping ////
-
-
-
查看能够管理的所有主机
对websrvs 分组,使用 ping模块,-m 使用哪个模块
默认 是基于ssh的key验证,通过-k选项 使用输入密码的方式 ,不使用key验证方式
ansible命令执行过程
1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg
2. 加载自己对应的模块文件,如command
3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,退出
执行状态:
绿色:执行成功并且不需要做改变的操作
黄色:执行成功并且对目标主机做变更
红色:执行失败
ansible常用模块
Command:在远程主机执行命令
ansible-doc -s command ////查看command模块的帮助
ansible srvs -m command -a ‘service vsftpd start’ ///
对所有主机 执行ls /data 命令
至此,我们就可以通过command 模块去远程运行linux的命令了,但是有些命令command运行不了啊,不支持 $VARNAME < > | ; & 等,用shell模块实现
如下图,目的是修改所有主机上的wang用户的密码为magedu,但是你看执行的啥,竟然打印出来了
shell 模块
shell模块更牛逼 啥都能干,可以替代command,所以要使用 shell模块去实现
ansible-doc -s shell ////查看shell 模块 的帮助
可以把 shell模块 替换为默认模块,替换成默认之后,就不用使用-m了
script模块
直接在 远程服务器上 执行ansible上的脚本
Copy模块 从主控端复制文件到远程主机
对于 websrvs组 复制本地的 /etc/fstab 到远程主机的/date 下
相同的文件只会执行一次,后面再执行也不会覆盖,文件不同的时候(内容不同,名字可以相同),就会覆盖,
复制文件,设置文件的属性
复制文件,如果有同名的文件,先把远程服务器上的文件 备份,然后在去复制
Ansible-console 命令行方式,知道就行了
我们写好的playbooks 本质就是yml文件, 这个文件可能存在一些敏感信息,所以可以进行加密,解密等
ansible-vault : 管理加密解密yml文件
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml 加密
ansible-vault decrypt hello.yml 解密
ansible-vault view hello.yml 查看
ansible-vault edit hello.yml 编辑加密文件
ansible-vault rekey hello.yml 修改口令
ansible-vault create new.yml 创建新文件
playbook 脚本格式的,需要编写一个文件yml,按照固定格式,就是我们所说的playbooks,本质上就是执行yml文件
yaml语法介绍:其实就是和json xml一样的有固定格式的数据,对于缩进是很有要求的。
Playbook核心元素
-
- Hosts 执行的远程主机列表
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 notity 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
运行playbook的方式 ansible-playbook <filename.yml> ... [options]
常见选项
--check -C 只检测可能会发生的改变,但不真正执行操作
--list-hosts 列出运行任务的主机
--list-tags 列出tag
--list-tasks 列出task
--limit 主机列表 只针对主机列表中的主机执行
-v -vv -vvv 显示过程
实例: ansible-playbook -C file.yml /// 只检测
ansible-playbook file.yml --limit websrvs 对于这个文件中,只执行
ansible-playbook file.yml
playbook 详情
开头--- 可以不用写
- name:"一些描述信息"
模块名:参数
编写playbook,对于appsrvs的主机,使用root用户 执行三个动作 1 安装httpd服务, 2 复制httpd配置文件 3 启动服务
二进制安装mysql playbook
handlers和notify结合使用触发条件
在上面我们通过playbook的方式,自动化安装了httpd服务,但是我现在配置文件改了,需要重新传到远程服务器上并重启服务 生效。这个时候我们还能在控制端运行刚刚的playbook吗?答案是可以的,只不过三个动作里,1httpd的安装 不会发生,因为之前已经安装过了,2配置文件的复制是可以生效的,因为我们的配置文件改了,3服务的启动,没有生效,因为服务本来就是启动的。
两种解决思路,你可以再写一些新的yam文件,用于 1 复制文件 2 重启服务。
第二种方案 当执行了某一些 动作的时候,就要触发一个动作,类似于触发器,比如更换配置文件之后,就要重启服务。这样他第一次 所有的步骤都会生效,包括notify。但是第二次的话,就只有复制文件和notify (重启服务)
tags标签
为每一项任务都添加标签,那么在我们执行的时候,就可以挑选性的执行某些动作
通过-t 指定标签,就只运行 conf标签的动作,
变量
setup 模块
背景:比如我现在需要在所有远程主机上,创建一个文件,这个文件的名称就是各自的主机名。
1 通过setup模块取出你要的信息,就是找你要的信息 对应的是哪个键。2 然后在 ansible中直接使用这个键(变量)就可以了。
获取远程主机的一大推所有信息,很多信息 json格式,通过键可以取出对应的值
获取的是所有的
在 查询键的时候,也可以用通配符
找到对应的键后, 在 playbook中使用 这些变量 {{变量名}},就OK了
当然我们也可以不使用setup模块中的变量,可以在主机清单里 /etc/ansible/hosts 定义变量,可以为每个主机定义单独的变量,也可以公用一个变量
为一个分组 定义这个分组的公共变量
在yaml 文件中 定义变量
模板,只能用于playbook,比如有三台服务器需要安装 http服务,但是每个机器的端口要求不一样,80 81 81 这三个端口,那要怎么做呢?既然端口不一样,就不能使用同一个配置文件,就要使用模板,根据模板生成各自的配置文件。准备好模板,模板的位置就放在 与yaml 文件同级的 template 文件夹中下面的模板。
template功能:根据模块文件动态生成对应的配置文件
template文件必须存放于templates目录下,且命名为 .j2 结尾
yaml/yml 文件需和templates目录平级,目录结构如下:
./
├── temnginx.yml
└── templates
└── nginx.conf.j2
原理:将httpd.conf作为模板文件 修改如下 ,其本质就是你把你需要替换的地方写成变量,通过变量再去传入值,就通过上面的几种方式定义变量,
在模板中引用变量,也可以使用加减乘除运算
定义变量
worker_processes {{ ansible_processor_vcpus }}; ///nginx配置文件 通过CPU的变量,指定进程个数
然后在yaml文件中 使用template 模块,将模板文件 拷贝到远程机器上,这里的模板文件就会自动填充变量的值,
when
背景:我现在后端服务器有很多版本,有6的 有7的。这样我通过自动化运维,比如拷贝http配置文件的时候,就不能只复制一个了,针对于6的系统就要拷贝6的配置文件,7的系统就要拷贝7的配置文件
when ,当when条件符合的时候才执行,不符合就跳过 。注意在yml文件中 引用setup模块中的变量 ansible_distribution_major_version
循环 创建了4个用户