浅谈ANSIBLE模块
ansible介绍
- ansible:自动化运维工具,实现了批量系统配置、批量程序部署、批量运行命令
- 特性:
模块化:调用特定的模块,完成特定任务
基于Python语言实现:包含Paramiko, PyYAML和Jinja2三个关键模块
部署简单:agentless,不需在被配置主机安装客户端
支持自定义模块
支持playbook
幂等性:任意多次执行所产生的影响均与一次执行的影响相同 - ansible架构图
ansible 相关文件
- 文件结构:
配置文件:/etc/ansible/ansible.cfg
主机清单:/etc/ansible/hosts
存放角色的目录:/etc/ansible/roles/
- 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 #默认模块,可以修改为shell模块
- 主机清单配置文件格式:
[mysqlsrv] // 主机组名,包含下面的主机
172.20.54.1
172.20.54.2
[websrv]
172.20.54.3
172.20.54.4
- ansible相关工具
/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实现管理的主要方式:- Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
- Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程
ansible工具
1️⃣ansible-doc 此工具用来显示模块帮助
- 格式
ansible-doc [options] [module...]
-l, --list #列出可用模块
-s, --snippet #显示指定模块的playbook片段
- 范例:
#列出所有模块
ansible-doc -l
#查看指定模块帮助用法
ansible-doc ping
#查看指定模块帮助用法
ansible-doc -s ping
2️⃣ansible
此工具通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能
- 建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点
- 范例:利用sshpass批量实现基于key验证
ssh-keygen -f /root/.ssh/id_rsa -P '' / 生成密钥对
NET=192.168.100
export SSHPASS=password / 定义密码
for IP in {1..200};do
sshpass -e ssh-copy-id $NET.$IP / 托管密码for循环
done
- 语法格式
ansible <host-pattern> [-m module_name] [-a args]
- 选项说明
--version #显示版本
-m module #指定模块,默认为command
-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命令执行过程
- 加载自己的配置文件 默认/etc/ansible/ansible.cfg
- 加载自己对应的模块文件,如:command
- 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
- 给文件+x执行
- 执行并返回结果
- 删除临时py文件,退出
-
ansible 的执行状态:
- 绿色:执行成功并且不需要做改变的操作
- 黄色:执行成功并且对目标主机做变更
- 红色:执行失败
3️⃣ansible-galaxy
此工具会连接 https://galaxy.ansible.com 下载相应的roles
范例:
#列出所有已安装的galaxy
ansible-galaxy list
#安装galaxy
ansible-galaxy install geerlingguy.redis
#删除galaxy
ansible-galaxy remove geerlingguy.redis
ansible常用模块
command模块
- 功能:命令模块,默认模块,用于在远程主机执行命令,
- 缺点:运行的命令中无法使用变量,管道。如果需要使用管道、变量,请使用raw模块,或者shell模块。
[root@node1 ~]# ansible-doc -s command
- name: 在远程节点执行命令
action: command
chdir # 在执行命令之前,先切换到该目录
creates # 一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form= #要执行的Linux指令,一般使用Ansible的-a参数代替。
removes #一个文件名,这个文件不存在,则该命令不执行,与creates相反的判断
shell模块
- 功能:与command模块相似,执行的命令中有管道或者变量,就需要使用shell
[root@node1 ~]# ansible-doc -s shell
- name: Execute commands in nodes.
action: shell
chdir # 执行之前,先cd到指定目录在执行命令
creates # 一个文件名,当这个文件存在,则该命令不执行
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form= # 执行的命令
removes # 一个文件名,这个文件不存在,则该命令不执行
- 注意:调用bash执行命令 类似
cat /tmp/test.md | awk -F‘|’ ‘{print $1,$2}’ &> /tmp/example.txt
这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器
script模块
- 功能:在远程主机上运行ansible服务器上的脚本
[root@node1 ~]# ansible-doc -s script
- name: 将本地脚本复制到远程主机并运行之
action: script
creates # 一个文件名,当这个文件存在,则该命令不执行
free_form= # 本地脚本路径
removes # 一个文件名,这个文件不存在,则该命令不执行
- 语法格式
ansible webserver -m script -a '/root/script.sh'
copy模块
- 功能:从ansible服务器主控端复制文件到远程主机
[root@node1 ~]# ansible-doc -s copy
- name: 将文件复制到被管理主机
action: copy
backup # 创建一个备份文件包括时间戳信息,如果以某种方式重创错了,还可以拿回原始文件
content # 取代src=,表示直接用此处指定的信息生成为目标文件内容;
dest= # 远程节点存放文件的路径,必须是绝对路径
directory_mode # 递归复制设置目录权限,默认为系统默认权限
force # 如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果设置为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
group # 复制到远程主机后,指定文件或目录的属
mode # 复制到远程主机后,指定文件或目录权限,类似与 `chmod'指明如 0644
owner # 复制到远程主机后,指定文件或目录属主
src # 要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
示例
- 将本地的/etc/fstab文件复制到目标主机的/tmp/fstab.ansbile,属主为root权限为640
[root@ansible ~]#ansible websrv -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible mode=640'
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "533c326f3c3654b97e826cf7b942a855de096969",
"dest": "/tmp/fstab.ansible",
"gid": 0,
"group": "root",
"md5sum": "dec527a553b1dbd9c9518d966a81e30e",
"mode": "0640",
"owner": "root",
"size": 595,
"src": "/root/.ansible/tmp/ansible-tmp-1575796184.03-84641622955757/source",
"state": "file",
"uid": 0
}
[root@ansible ~]#ansible websrv -a 'ls /tmp/fstab.ansible -l'
172.20.54.4 | CHANGED | rc=0 >>
-rw-r----- 1 root root 595 Dec 8 17:09 /tmp/fstab.ansible
- 在webserver组主机创建文件,自己手动指定文件内容
[root@ansible ~]#ansible websrv -m copy -a 'content="hello,world!\n" dest=/tmp/hello.txt'
172.20.54.4 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "8e41fa769f837c3cd5edec26f22c9e846e1d1dff",
"dest": "/tmp/hello.txt",
"gid": 0,
"group": "root",
"md5sum": "abdb60390ee5dcf80db30b45433551a7",
"mode": "0644",
"owner": "root",
"size": 13,
"src": "/root/.ansible/tmp/ansible-tmp-1575796437.85-106616853454191/source",
"state": "file",
"uid": 0
[root@ansible ~]#ansible websrv -a 'cat /tmp/hello.txt'
172.20.54.4 | CHANGED | rc=0 >>
hello,world!
- 使用backup选项
#如目标存在,默认覆盖,此处指定先备份
ansible srv -m copy -a “src=/root/test1.sh dest=/tmp/test2.sh owner=wang
mode=600 backup=yes”
#复制/etc/下的文件,不包括/etc/目录自身
ansible srv -m copy -a “src=/etc/ dest=/backup”
File模块
- 功能:设置文件属性
[root@node1 ~]# ansible-doc -s file
- name: 设置文件属性
action: file
force # 需要在两种情况下强制创建软连接,一种是源文件不存在但之后会建立的情况下;另一种是目标连接已存在,需要先取消之前的软连接,有两个选项:yes|no
group # 设置文件或目录的属组,后面可以加上mode:定义文件/目录的权限
mode # 设置文件或目录的权限
owner # 设置文件或目录的属主,后面必须跟上path:定义文件/目录的路径
path= # 必选项,定义文件或目录的路径
recurse # 递归设置文件的属性,只对目录有效
src # 要被链接到的路径,只应用与state=link的情况
dest #被链接到的路径,只应用于state=link的情况
state # directory:如果目录不存在,创建目录;
file:即使文件不存在,也不会被创建
link:创建软连接;
hard:创建硬连接;
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
示例
- 设置/tmp/fstab.ansbile属主和属组都为mysql,权限为644
[root@ansible ~]#ansible websrv -m file -a 'path=/tmp/fstab.ansible owner=mysql mode=640 group=mysql'
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 996,
"group": "mysql",
"mode": "0640",
"owner": "mysql",
"path": "/tmp/fstab.ansible",
"size": 595,
"state": "file",
"uid": 998
}
172.20.54.3 | CHANGED | rc=0 >>
-rw-r----- 1 mysql mysql 595 Dec 8 17:09 /tmp/fstab.ansible
- 在webserver组创建/test/fstab.ansible的连接文件
[root@ansible ~]#ansible websrv -m file -a 'src=/tmp/fstab.ansible dest=/tmp/fstab.link state=link'
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 18,
"src": "/tmp/fstab.ansible",
"state": "link",
"uid": 0
}
[root@ansible ~]#ansible websrv -a 'ls -l /tmp/fstab*'
172.20.54.4 | CHANGED | rc=0 >>
-rw-r----- 1 root root 595 Dec 8 17:09 /tmp/fstab.ansible
lrwxrwxrwx 1 root root 18 Dec 8 17:46 /tmp/fstab.link -> /tmp/fstab.ansible
- 创建并删除空文件
ansible srv -m file -a 'path=/data/test.txt state=touch'
ansible srv -m file -a 'path=/data/test.txt state=absent'
ansible srv -m file -a "path=/root/test.sh owner=wang mode=755“
- 创建并删除空目录
[root@ansible ~]#ansible websrv -m file -a "path=/tmp/mysql state=directory owner=mysql group=mysql"
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 996,
"group": "mysql",
"mode": "0755",
"owner": "mysql",
"path": "/tmp/mysql",
"size": 6,
"state": "directory",
"uid": 998
}
[root@ansible ~]#ansible websrv -a 'ls -l /tmp/mysql/ -d'
172.20.54.3 | CHANGED | rc=0 >>
drwxr-xr-x 2 mysql mysql 6 Dec 8 17:56 /tmp/mysql/
/ 删除此目录
[root@ansible ~]#ansible websrv -m file -a 'path=/tmp/mysql state=absent'
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/tmp/mysql",
"state": "absent"
}
[root@ansible ~]#ansible websrv -a 'ls -l /tmp'
172.20.54.3 | CHANGED | rc=0 >>
total 16
drwx------ 2 root root 41 Dec 8 17:59 ansible_command_payload_M_jyx1
-rw-r--r-- 1 root root 53 Dec 8 17:28 ceshi.sh
-rw-r----- 1 mysql mysql 595 Dec 8 17:09 fstab.ansible
lrwxrwxrwx 1 root root 18 Dec 8 17:46 fstab.link -> /tmp/fstab.ansible
-rw-r--r-- 1 root root 13 Dec 8 17:13 hello.txt
-rw-r--r-- 1 root root 23 Dec 5 19:39 issue
unarchive模块
- 功能:解包解压缩
- 实现有两种用法:
1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes
2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
- 常见参数
copy:在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
creates:指定一个文件名,当该文件存在时,则解压指令不执行
dest:远程主机上的一个路径,即文件解压的路径
grop:解压后的目录或文件的属组
list_files:如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
mode:解决后文件的权限
src:如果copy为yes,则需要指定压缩文件的源路径
owner:解压后文件或目录的属主
- 注意:要传输解压缩的文件必须是tar归档文件之后的各种压缩格式,单独的压缩文件,这个模块不支持
- 示例
- 把ansible主机本地文件推送到远程主机并解压
[root@ansible ~]#ansible websrv -m unarchive -a 'src=/root/hello.tar.gz dest=/tmp/'
172.20.54.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp/",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1575808678.08-128025411979564/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"size": 254,
"src": "/root/.ansible/tmp/ansible-tmp-1575808678.08-128025411979564/source",
"state": "directory",
"uid": 0
}
- 解压远程主机tar归档文件
[root@ansible ~]#ansible testsrv -m unarchive -a 'src=/tmp/fstab.tar dest=/tmp copy=no'
Archive模块
- 功能:打包压缩
- 范例
ansible testsrv -m archive -a 'path=/var/log dest=/tmp/log.tar.bz2 format=bz2 owner=yijie mode=700'
Hostname模块
- 功能:管理主机名,而且是修改文件内容生效,不是临时设置
- 范例:
ansible testsrv -m hostname -a 'name="test001"'
ansible 172.20.54.3 -m hostname -a 'name="test002"'
Cron模块
- 功能:计划任务
- 支持时间:
minute
,hour
,day
,month
,weekday
- 常用参数:
- name: 设置管理节点生成定时任务
action: cron
backup # 如果设置,创建一个crontab备份
cron_file #如果指定, 使用这个文件cron.d,而不是单个用户crontab
day # 日应该运行的工作( 1-31, *, */2, etc )
hour # 小时 ( 0-23, *, */2, etc )
job #指明运行的命令是什么
minute #分钟( 0-59, *, */2, etc )
month # 月( 1-12, *, */2, etc )
name #定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time # 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,prsent表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
weekday # 周 ( 0-6 for Sunday-Saturday, *, etc )
- 示例:
/ 创建备份数据库脚本
[root@ansible ~]#vim mysql_backup.sh
#!/bin/bash
mysqldump -uroot -ppassword -A -F --single-transaction --master-data=2 | gzip> /data/mysql_`date +%F_%T`.sql.gz
/ 创建任务
[root@ansible ~]#ansible testsrv -m cron -a 'hour=2 minute=30 weekday=1-5 name="mysql" job=/root/mysql_backup.sh'
/ 查看任务
[root@ansible ~]#ansible testsrv -a 'crontab -l'
172.20.54.3 | CHANGED | rc=0 >>
#Ansible: mysql
30 2 * * 1-5 /root/mysql_backup.sh
/ 禁用任务
[root@ansible ~]#ansible testsrv -m cron -a 'hour=2 minute=30 weekday=1-5 name="mysql" job=/root/mysql_backup.sh disabled=yes'
/ 查看任务
[root@ansible ~]#ansible testsrv -a 'crontab -l'
172.20.54.3 | CHANGED | rc=0 >>
#Ansible: mysql
#30 2 * * 1-5 /root/mysql_backup.sh / 被注释掉了
/ 启用任务
[root@ansible ~]#ansible testsrv -m cron -a 'hour=2 minute=30 weekday=1-5 name="mysql" job=/root/mysql_backup.sh disabled=no'
/ 删除任务
[root@ansible ~]#ansible testsrv -m cron -a 'name="mysql" state=absent'
Yum模块
- 功能:管理软件包
- 常用参数:
conf_file # yum的配置文件
disable_gpg_check # 关闭gpg_check
disablerepo # 不启用某个源
enablerepo # 启用某个源
name= # 指定要安装的包,如果有多个版本需要指定版本,否则安装最新的包
state # 安装(`present'),安装最新版(`latest'),卸载程序包(`absent')
- 范例:
/ 安装httpd
ansible testsrv -m yum -a 'name=httpd state=present'
/ 卸载httpd
ansible testsrv -m yum -a 'name=httpd state=absent'
Service模块
- 功能:管理服务
- 常用参数:
action: service
arguments # 向服务传递的命令行参数
enabled # 设置服务开机自动启动,参数为yes|no
name= # 控制服务的名称
pattern # 定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel # 设置服务自启动级别
sleep # 如果执行了restarted,则在stop和start之间沉睡几秒钟
state # 启动`started' 关闭`stopped' 重新启动 `restarted' 重载 `reloaded'
- 范例:
/ 启动服务并设为开机启动
ansible testsrv -m service -a 'name=httpd enabled=yes state=started'
/ 停止服务
ansible testsrv -m service -a 'name=httpd state=stopped'
/ 重装服务
ansible testsrv -m service -a 'name=httpd state=reloaded'
/ 修改配置文件然后重启服务
ansible testsrv -m shell -a "sed -i 's/^Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf"
ansible testsrv -m service -a 'name=httpd stated=restarted'
User模块
- 功能:管理用户
- 常见参数:
comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用`state=absent'是, 行为与`userdel --force'一致.
group # 指定基本组
groups # 指定附加组,如果指定为('groups=')表示删除所有组
home # 指定用户家目录
login_class #可以设置用户的登录类 FreeBSD, OpenBSD and NetBSD系统.
move_home # 如果设置为`home='时, 试图将用户主目录移动到指定的目录
name= # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用 `state=absent'时, 行为是与 `userdel --remove'一致.
shell # 指定默认shell
state #设置帐号状态,不指定为创建,指定值为absent表示删除
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户。
uid #指定用户的uid
update_password # 更新用户密码
- 范例:
/ 创建用户
ansible testsrv -m user -a 'name=user1 comment="test user" uid=2048 home=/data/user1 group=root'
/ 创建系统用户 不需要用户家目录
ansible testsrv -m user -a 'name=nginx comment=nginx uid=88
shell=/sbin/nologin non_unique=yes create_home=no system=yes'
/ 删除指定用户nginx
ansible testsrv -m user -a 'name=nginx state=absent'
Group模块
- 功能:管理组
- 常用参数:
gid # 设置组的GID号
name= # 管理组的名称
state # 指定组状态,默认为创建,设置值为absent为删除
system # 设置值为yes,表示为创建系统组
- 范例:
/ 创建用户组
ansible testsrv -m group -a 'name=nginx gid=88 system=yes'
/ 删除用户组
ansible testsrv -m group -a 'name=nginx state=absent'
Setup模块
功能:返回系统状态信息
ansible srv -m setup
ansible srv -m setup -a "filter=ansible_nodename"
ansible srv -m setup -a "filter=ansible_hostname"
ansible srv -m setup -a "filter=ansible_domain"
ansible srv -m setup -a "filter=ansible_memtotal_mb"
ansible srv -m setup -a "filter=ansible_memory_mb"
ansible srv -m setup -a "filter=ansible_memfree_mb"
ansible srv -m setup -a "filter=ansible_os_family"
ansible srv -m setup -a "filter=ansible_distribution_major_version"
ansible srv -m setup -a "filter=ansible_distribution_version"
ansible srv -m setup -a "filter=ansible_processor_vcpus"
ansible srv -m setup -a "filter=ansible_all_ipv4_addresses"
ansible srv -m setup -a "filter=ansible_architecture"