ansible是一个自动化运维工具、基于python开发,集合了众多运维工具的优点(puppet,fabric, slatstack),实现批量系统配置,程序的部署,批量运行命令等。
ansible基于python开发,依赖于:paramiko,PyYaml和jinja三个关键组件 基于ssh协议,只要管理员通过ssh登录到一台远程主机上能做的操作,ansible都可以做到
ansible组成:
1、host inventory --#定义客户机, 可以对客户机进行分类:db类,web类。。。等等 2、playbook --#剧本 让主机按照我给定的剧本去完成一些事情 3、module --#模块 实现一个个功能的程序 4、pluging --#插件 实现一些额外的小功能
ansible的使用
由于ansible基于ssh协议,在使用ansible前,必须配置好服务器的免密通道 配置免密通道可以参加我的另一篇文章 :ssh服务配置免密通道
1、安装ansible
[root@a .ssh]
[root@b ansible]
2、配置
配置目录: /etc/ansible/ansible.cfg ansible的主配置文件,此文件主要定义了roles_path的路径,主机清单路径,连接清单中的主机方式等等 /etc/ansible/hosts 默认的主机清单配置文件, 可以通过ansible.cfg 重新定义
[root@b ansible]
[root@b ansible]
[webserve]
192.168.10.128
192.168.10.129
192.168.10.130
[proj]
192.168.10.133
192.168.10.135
除了两个重要的配置文件,还有三个重要的可执行文件分别是:
ansible 主执行程序,一般用于命令行下执行
ansible-playbook 执行playbook中的任务
ansible-doc -s 模块 获取各模块的帮助信息
示例:
指定[proj]组的主机,执行shell模块的命令mkdir /tmp/sc
[root@ansible ansible]
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'. If you need to use command because file is insufficient you can
add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.10.133 | CHANGED | rc=0 >>
192.168.10.135 | CHANGED | rc=0 >>
rc ==》 return code --为0表示执行成功
常见参数:
HOST-PATTERN #匹配主机模式,如all表示所有主机
-m MOD_NAME #模块名 如:ping,shell,copy
-a MOD_ARGS #模块执行的参数
-f FORKS #生成几个子进行程执行
-C #(不执行,模拟跑)
-u Username #某主机的用户名
-c CONNection #连接方式(default smart)
ansible常用模块
1、copy模块
从本地copy文件分发到目录主机路径
参数说明:
src= 源文件路径、 dest= 目标路径
注意src目录后面带/和不带/的区别:带/ 表示拷贝目录下的子文件或者子文件夹,不带/ 表示拷贝整个目录
content= 自行填充的文件内容
owner 属主
group 属组
mode 权限
示例:ansible proj -m copy -a "src=/etc/passwd dest=/tmp mode=666" 指定[proj]组的主机,执行copy模块,将指定文件复制到目的地,指定mode权限为666
2、fetch模块
从远程主机拉取文件到本地
fetch会自动的在dest指定目录后加上远程主机命名的目录结构后面接src目录结构 fetch存储到本地的目录结构: dest + 远程主机名 + src
[root@ansible ansible]
192.168.10.133 | CHANGED => {
"changed": true,
"checksum": "1a24960962e6ca79b6ce526d0cb838dc95cafe70",
"dest": "/tmp/192.168.10.133/etc/hostname",
"md5sum": "2726de71291b1da437058231d945f8b2",
"remote_checksum": "1a24960962e6ca79b6ce526d0cb838dc95cafe70",
"remote_md5sum": null
}
192.168.10.135 | CHANGED => {
"changed": true,
"checksum": "0ae4684051e3a0a2841128c308d81339ac2b42e1",
"dest": "/tmp/192.168.10.135/etc/hostname",
"md5sum": "64ca32717643720cebb20f07575099db",
"remote_checksum": "0ae4684051e3a0a2841128c308d81339ac2b42e1",
"remote_md5sum": null
}
[root@ansible ansible]
总用量 0
drwxr-xr-x 3 root root 17 10月 2 11:10 192.168.10.133
drwxr-xr-x 3 root root 17 10月 2 11:10 192.168.10.135
[root@ansible ansible]
/tmp
├── 192.168.10.133
│ └── etc
│ └── hostname
├── 192.168.10.135
│ └── etc
│ └── hostname
3、command模块
在远程主机上执行命令,属于裸执行,非键值对显示;不进行shell解析 裸执行:不会解析它的管道符号 会认为ip add | grep 是一个命令
[root@ansible ansible]
192.168.10.135 | FAILED | rc=1 >>
Object "add|grep" is unknown, try "ip help".non-zero return code
192.168.10.133 | FAILED | rc=1 >>
Object "add|grep" is unknown, try "ip help".non-zero return code
4、shell 模块
跟command一样,只不过shell模块可以解析管道之类的功能。因此推荐使用shell模块执行命令
[root@ansible ansible]
192.168.10.135 | CHANGED | rc=0 >>
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 192.168.10.135/24 brd 192.168.10.255 scope global noprefixroute ens33
inet6 fe80::c641:d4e6:810f:f614/64 scope link tentative noprefixroute dadfailed
inet6 fe80::53b5:75d8:7bfe:931d/64 scope link tentative noprefixroute dadfailed
inet6 fe80::1d81:4da2:9ea6:214e/64 scope link noprefixroute
192.168.10.133 | CHANGED | rc=0 >>
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 192.168.10.133/24 brd 192.168.10.255 scope global noprefixroute ens33
inet6 fe80::53b5:75d8:7bfe:931d/64 scope link tentative noprefixroute dadfailed
inet6 fe80::c641:d4e6:810f:f614/64 scope link noprefixroute
5、file模块
设置文件属性(创建文件)
常用参数:
path 目标路径
state 状态:absent删除文件和目录、directory目录、touch新建空文件、link软链接、 hard硬链接
group 目录属组
owner 属主
mode 权限
等,其他参数通过ansible-doc -s file 获取
创建:在指定path目录下创建一个文件夹sanchuang
[root@ansible ansible]
192.168.10.133 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/sanchuang",
"size": 6,
"state": "directory",
"uid": 0
}
修改:将指定path的文件或目录修改属性、修改所属主为mysql
[root@ansible ansible]
192.168.10.133 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "mysql",
"path": "/tmp/sanchuang",
"size": 6,
"state": "directory",
"uid": 997
6、cron模块
通过cron模块对目标主机生成计划任务
常用参数:
除了分(minute)时(hour)日(day)月(month)周(week)外
name: 本次计划任务的名称
state: present 生成(默认) absent 删除 (基于name)
ntp服务,是一个时间管理服务器 在 centos 8 中, ntp 已经被 chrony 代替。 之前的版本:yum install -y ntp centos8:yum install chrony
生成计划任务:每三分钟输出当前时间,到/tmp/time.txt文件
[root@ansible ansible]
192.168.10.135 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"date_test"
]
}
192.168.10.133 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"date_test"
]
}
[root@slave1 tmp]
*/3 * * * * date >>/tmp/time.txt
删除计划任务:指定计划任务名即可
[root@ansible ansible]
练习:
一、每天凌晨1点 检查/etc/passwd 文件是否被修改,并且生成检查报告
[root@ansible lianxi]
md5_file_path="/opt/passwd.md5"
check_file="/etc/passwd"
check_md5_file () {
[ -f $md5_file_path ] || md5sum $check_file > $md5_file_path
}
check_md5_file()
old_md5=`awk -F' ' '{print $1}' $md5_file_path`
new_md5=`md5sum $check_file |awk -F' ' '{print $1}'`
if [[ $old_md5 == $new_md5 ]]; then
echo `date +'%F %H:%M'` $check_file 没有被修改 >> /opt/check.log
else
echo `date +'%F %H:%M'` $check_file 已经被修改 >> /opt/check.log
md5sum $check_file > $md5_file_path
fi
[root@ansible lianxi]
[root@ansible lianxi]
二、实现ansible node节点服务器备份 备份/var/log/messages 备份到/backup目录下,并且取名2020-11-25-01-log.tar.gz,每一个小时执行一次
[root@ansible lianxi]
7、yum模块
yum安装软件包的模块;
常用参数说明:
enablerepo,disablerepo表示启用与禁用某repo库
name 安装包名
state (present' or installed', latest')表示安装, (absent' or `removed') 表示删除
示例:
[root@ansible lianxi]
[root@ansible lianxi]
8、service模块
服务管理模块
常用参数:
name:服务名
state:服务状态 started(启动) stopped(关闭) restarted(重启) reloaded(重新加载)
enabled: 是否开机启动 true|false
runlevel: 启动级别 (systemed方式忽略)
示例:
[root@ansible lianxi]
[root@ansible lianxi]
9、script模块
把本地的脚本传到远端执行;只在远程服务器执行脚本,不上传脚本到远程服务器
前提是到远端可以执行,不要把Linux下的脚本同步到windows下执行; 缺陷:执行慢 机器多 、可以使用多进程去执行 -f 6 执行6个进程去执行
rc返回值为0表示执行成功
[root@ansible lianxi]
192.168.10.135 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.10.135 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.10.135 closed."
],
"stdout": "",
"stdout_lines": []
}
192.168.10.133 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.10.133 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.10.133 closed."
],
"stdout": "",
"stdout_lines": []
}
playbook使用
如果ansible的各模块(能实现各种功能)是车间里的各工具;playbook就是指导手册,目标远程主机就是库存和原料对象
语法: yaml 格式配置
1、playbook的核心元素
hosts :playbook配置文件作用的主机
tasks: 任务列表
variables: 变量
templates:包含模板语法的文本文件
handlers:由特定条件触发的任务
roles :用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等
2、playbook运行方式
ansible-playbook --check 只检测可能会发生的改变,但不真执行操作
ansible-playbook --list-hosts 列出运行任务的主机
ansible-playbook --syntax-check playbook.yaml 语法检测
ansible-playbook -t TAGS_NAME playbook.yaml 只执行TAGS_NAME任务
ansible-playbook playbook.yaml 运行
示例:创建yaml文件
解析:针对all组下的机器,执行copy文件任务,再执行yum下载任务。针对proj组下的机器,执行shell命令任务
[root@ansible lianxi]
[root@ansible lianxi]
- hosts: all
remote_user: root
tasks:
- name: up file
copy: src=/etc/passwd dest=/tmp/passwd_tmp
- name: download redis
yum: name=redis state=installed
- hosts: proj
tasks:
- name: remove file
shell: rm -rf /tmp/passwd_tmp
使用palybook去部署web服务
[root@ansible lianxi]
[root@ansible lianxi]
- hosts: all
remote_user: root
tasks:
- name: yum nginx
yum: name=nginx state=installed
- name: copy sc.conf
copy: src=/lianxi/sc.conf dest=/etc/nginx/conf.d/sc.conf
- name: copy index
copy: src=/lianxi/index.html dest=/opt/dist/
- name: start nginx
service: name=nginx state=started
template使用
根据一定的条件灵活的设置要复制文件中的部分关键内容,可以使用template模块
模板文件必须以j2结尾
示例:
编写sc_template.conf.j2
指定一个变量{{ listen_port }},需要传入
[root@scmysql opt]
server {
listen {{ listen_port }} ;
server_name www.sc.com;
root /opt/dist;
access_log /var/log/nginx/sc_access.log main;
location / {
}
location =/api {
}
}
编写测试剧本
[root@scmysql opt]
- hosts: web
tasks:
- name: template test
template: src=/opt/sc_template.conf.j2 dest=/tmp/sc.conf
执行playbook, 指定listen_port变量的值 [root@scmysql opt]# ansible-playbook template_test.yaml -e "listen_port=8080"
也可以在hosts文件中 指定每一台主机的变量
[root@scmysql ansible]# cat hosts
[web]
192.168.77.133:22 listen_port=81
192.168.77.134 listen_port=666
|