Ansible介绍
Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
Ansible的特点:
- no agent: 不需要在被管控主机上安装任何软件,
- no server: 无服务器端,使用时直接运行命令即可,
- modules in any languages:基于模块工作,可使用任意语言开发模块,
- yaml,not code:使用yaml语言定制剧本playbook,
- ssh by default:基于SSH工作
- strong multi-tier solution:可实现多级指挥
Ansible的优点
- 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
- 批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
- 使用python编写,维护更简单,ruby语法过于复杂;
- 支持sudo。
Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,ansible只是提供一种框架。主要包括:
- 连接插件connection plugins:负责和被监控端实现通信;
- host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
- 各种模块核心模块、command模块、自定义模块;
- 借助于插件完成记录日志邮件等功能;
-
playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
Ansible安装
- Ansible安装非常简单,只需两条命令即可完成。
[root@crazyting1 ~]# yum install epel -y
[root@crazyting1 ~]# yum install ansible -y
- Ansible配置文件
2.1. ansible 应用程序的 主配置文件:/etc/ansible/ansible.cfg
2.2. Host Inventory 定义管控主机 :/etc/ansible/hosts
配置管控主机
- 当ansible管理主机时,可以基于ssh的用户密码验证,也可以基于用户的密钥验证
[root@crazyting1 ~]# cat /etc/ansible/hosts
[tencent]
IP地址 ansible_ssh_pass=密码 asible_ssh_user=用户名
1.1. Hosts部分中经常用到的变量部分:
变量 |
说明 |
ansible_ssh_host |
用于指定被管理的主机的真实IP |
ansible_ssh_port |
用于指定连接到被管理主机的ssh端口号,默认是22 |
ansible_ssh_user |
ssh连接时默认使用的用户名 |
ansible_ssh_pass |
ssh连接时的密码 |
ansible_sudo_pass |
使用sudo连接用户时的密码 |
ansible_sudo_exec |
如果sudo命令不在默认路径,需要指定sudo命令路径 |
ansible_ssh_private_key_file |
秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项 |
ansible_shell_type |
目标系统的shell的类型,默认sh |
ansible_connection |
SSH 连接的类型: local , ssh , paramiko,在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提) |
ansible_python_interpreter |
用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径 |
ansible_*_interpreter |
其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等 |
- 免登陆配置
如果需要管理的服务器较多,建议使用免登陆配置
# 创建密钥,-f 指定存放位置,-P 密钥加密的密码 -q 减少信息输出
[root@crazyting1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -P "" -q
[root@crazyting1 ~]# ssh-copy-id -i /root/.ssh/id_rsa crazyting2
Ansible语法说明
- 语法说明:
ansible HOST-PATTERN [-f FORKS] [-M MOD_NAME] [-a MOD_ARGS]
-f FORKS:表示一批处理几台主机,也就是当被管控主机很多时,ansible不是对所有主机同时发起管理操作,而是一批处理几台,然后再换一批,直到所有主机被处理完成,如果不指定,则默认是5台
-m MOD_NAME:指明调用哪个模块执行操作,各个模块所能实现的功能不同,如果不指定,默认是用-m command模块
-a MOD_ARGS:指明使用该模块的执行操作时的参数
使用示例:
[root@crazyting1 ~]# ansible tencent -m command -a 'date'
ip地址 | SUCCESS | rc=0 >>
Mon Feb 10 17:47:30 CST 2020
- 列出所有模块
[root@crazyting1 ~]# ansible-doc -l | grep ping
ios_ping Tests reachability using ping from Cisco IOS network devices
lambda_event Creates, updates or deletes AWS Lambda function event mappings.
net_ping Tests reachability using ping from a network device
netapp_e_lun_mapping Create or Remove LUN Mappings
nxos_igmp_snooping Manages IGMP snooping global configuration.
nxos_ping Tests reachability using ping from Nexus switch.
ping Try to connect to host, verify a usable python and return `pong' on success
pingdom Pause/unpause Pingdom alerts
sefcontext Manages SELinux file context mapping definitions
win_ping A windows version of the classic ping module
- 查询模块用法
[root@crazyting1 ~]# ansible-doc ping
...
EXAMPLES:
# Test we can logon to 'webservers' and execute python with json lib.
# ansible webservers -m ping
# Example from an Ansible Playbook
- ping:
# Induce an exception to see what happens
- ping:
data: crash
RETURN VALUES:
ping:
description: value provided with the data parameter
returned: success
type: string
sample: pong
或者直接访问:Ansible模块列表
Ansible常用模块
- ping模块
探测助主机是否在线
[root@crazyting1 ~]# ansible crazyting2 -m ping
crazyting2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@crazyting1 ~]# ansible all -m ping
crazyting2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
gz-tencent | SUCCESS => {
"changed": false,
"ping": "pong"
}
- command模块
在远程主机执行命令,不支持管道,重定向等shell特性
常用参数 |
描述 |
chdir= |
表示指明命令在远程主机上哪个目录下运行,也就是在命令执行前切换到哪个目录下 |
creates= |
在命令运行时创建一个文件,如果文件已存在,则不会执行创建任务 |
removes= |
在命令运行时移除一个文件,如果文件不存在,则不会执行移除任务 |
executeble= |
指明运行命令的shell程序 |
[root@crazyting1 ~]# ansible crazyting2 -m command -a "date"
crazyting2 | SUCCESS | rc=0 >>
Fri Oct 18 06:47:27 CST 2019
[root@crazyting1 ~]# ansible crazyting2 -m command -a 'chdir=/tmp ls ./'
crazyting2 | SUCCESS | rc=0 >>
ansible_hvEh_Q
hsperfdata_root
[root@crazyting1 ~]# ansible crazyting2 -m command -a "ps aux | grep kafka"
crazyting2 | FAILED | rc=1 >>
ERROR: Garbage option.
- shell模块
在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令。支持shell特性,如管道,重定向等
常用参数 |
描述 |
chdir= |
表示指明命令在远程主机上哪个目录下运行,也就是在命令执行前切换到哪个目录下 |
creates= |
在命令运行时创建一个文件,如果文件已存在,则不会执行创建任务 |
removes= |
在命令运行时移除一个文件,如果文件不存在,则不会执行移除任务 |
executeble= |
指明运行命令的shell程序 |
[root@crazyting1 ~]# ansible crazyting2 -m shell -a 'echo "hello" > /tmp/aa.txt'
crazyting2 | SUCCESS | rc=0 >>
[root@crazyting1 ~]# ansible crazyting2 -m shell -a 'cat /tmp/aa.txt'
crazyting2 | SUCCESS | rc=0 >>
hello
- copy模块
拷贝ansible管理端的文件到远程主机的指定位置
常见参数 |
描述 |
dest= |
指明拷贝文件的目标目录位置,使用绝对路径,如果源是目录,则目标也要是目录,如果目标文件已存在,会覆盖原有内容 |
src= |
指明本地路径下的某个文件,可以使用相对路径和绝对路径,支持直接指定目录,如果源是目录,则目标也要是目录 |
mode= |
指明复制时,目标文件的权限 |
owner= |
指明复制时,目标文件的属主 |
group= |
指明复制时,目标文件的属组 |
content= |
指明复制到目标主机上的内容,不能与src一起使用,相当于复制content指明的数据,到目标文件中 |
[root@crazyting1 ~]# ansible crazyting2 -m copy -a 'src=install.log dest=/tmp mode=777 owner=nobody group=root'
crazyting2 | SUCCESS => {
"changed": true,
"checksum": "6a6ad8ff65e7c9dd26d13d22b881dc555ed311d3",
"dest": "/tmp/install.log",
"gid": 0,
"group": "root",
"md5sum": "91e9f658638e9391ed303c7525d5d42c",
"mode": "0777",
"owner": "nobody",
"size": 28523,
"src": "/root/.ansible/tmp/ansible-tmp-1581350215.73-280736596777904/source",
"state": "file",
"uid": 99
}
[root@crazyting2 tmp]# ll
total 36
-rw-r--r--. 1 root root 6 Oct 18 07:15 aa.txt
drwxr-xr-x 2 root root 4096 Feb 10 23:53 hsperfdata_root
-rwxrwxrwx 1 nobody root 28523 Feb 10 23:56 install.log
[root@crazyting1 ~]# ansible crazyting2 -m copy -a 'content="hello world" dest=/tmp/test.txt mode=777'
crazyting2 | SUCCESS => {
"changed": true,
"checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
"dest": "/tmp/test.txt",
"gid": 0,
"group": "root",
"md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3",
"mode": "0777",
"owner": "root",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1581351194.89-252437495810863/source",
"state": "file",
"uid": 0
}
[root@crazyting2 tmp]# cat test.txt
hello world
- cron模块
管理计划任务的模块
常见参数 |
描述 |
minute= |
指明计划任务的分钟,支持格式:0-59,*,*/2等,与正常cron任务定义的一样的语法,省略时,默认为*,也就是每分钟都执行 |
hour= |
指明计划任务的小时,支持的语法:0-23,*,*/2等,省略时,默认为*,也就是每小时都执行 |
day= |
指明计划任务的天,支持的语法:1-31,*,*/2等,省略时,默认为*,也就是每天都执行 |
month= |
指明计划任务的月,支持的语法为:1-12,*,*/2等,省略时,默认为*,也就是每月都执行 |
weekday= |
指明计划任务的星期几,支持的语法为:0-6,*等,省略时,默认为*,也就是每星期几都执行 |
reboot |
指明计划任务执行的时间为每次重启之后 |
name= |
给该计划任务取个名称,必须要给明。每个任务的名称不能一样。删除任务时,只需要给明任务的名称即可 |
job= |
执行的任务是什么,当state=present时才有意义 |
state=present|absent |
表示这个任务是创建还是删除,present表示创建,absent表示删除,默认是present |
[root@crazyting1 ~]# ansible crazyting2 -m cron -a 'minute=10 hour=10-20 day=10 name="test cron" job="ntpdate ntp1.aliyun.com &> /dev/null"'
crazyting2 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"test cron"
]
}
[root@crazyting2 ~]# crontab -u root -l
#Ansible: test cron
10 10-20 10 * * ntpdate ntp1.aliyun.com &> /dev/null
- fetch模块
从远程主机拉取文件到本地。一般情况下,只会从一个远程节点拉取数据
常见参数 |
描述 |
dest= |
从远程主机上拉取的文件存放在本地的位置,一般只能是目录 |
src= |
指明远程主机上要拉取的文件,只能是文件,不能是目录 |
[root@crazyting1 ~]# ansible crazyting2 -m fetch -a 'src=/tmp/test.txt dest=/tmp'
crazyting2 | SUCCESS => {
"changed": true,
"checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
"dest": "/tmp/crazyting2/tmp/test.txt",
"md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3",
"remote_checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
"remote_md5sum": null
}
[root@crazyting1 ~]# ls -R /tmp
/tmp:
crazyting2 hsperfdata_root
/tmp/crazyting2:
tmp
/tmp/crazyting2/tmp:
test.txt
- file模块
用于设定远程主机上的文件属性
示例:
创建软链接的用法: src= path= state=link
修改文件属性的用法: path= owner= mode= group=
创建目录的用法: path= state=directory
删除文件: path= state=absent
常见参数 |
描述 |
path= |
指明对哪个文件修改其属性 |
src= |
指明path=指明的文件是软链接文件,其对应的源文件是谁,必须要在state=link时才有用 |
state=directory|link|absent |
表示创建的文件是目录还是软链接 |
owner= |
指明文件的属主 |
group= |
指明文件的属组 |
mode= |
指明文件的权限 |
[root@crazyting1 ~]# ansible crazyting2 -m file -a 'path=/tmp/test.txt state=absent'
crazyting2 | SUCCESS => {
"changed": true,
"path": "/tmp/test.txt",
"state": "absent"
}
[root@crazyting1 ~]# ^C
[root@crazyting1 ~]# ^C
[root@crazyting1 ~]# ansible crazyting2 -m command -a 'ls /tmp'
crazyting2 | SUCCESS | rc=0 >>
ansible_Dcw5Ok
hsperfdata_root
install.log
- hostname模块
管理远程主机上的主机名
[root@crazyting1 ~]# ansible crazyting2 -m hostname -a "name=crazyting22"
crazyting2 | SUCCESS => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "crazyting22",
"ansible_hostname": "crazyting22",
"ansible_nodename": "crazyting22"
},
"changed": true,
"name": "crazyting22"
}
[root@crazyting1 ~]# ansible crazyting2 -m shell -a "hostname"
crazyting2 | SUCCESS | rc=0 >>
crazyting22
- yum模块
基于yum机制,对远程主机管理程序包
常用参数 |
描述 |
name= |
指明程序包的名称,可以带上版本号,不指明版本,就是默认最新版本。 |
state=present|latest|absent |
指明对程序包执行的操作,present表示安装程序包,latest表示安装最新版本的程序包,absent表示卸载程序包 |
disablerepo= |
在用yum安装时,临时禁用某个仓库,仓库的ID |
enablerepo= |
在用yum安装时,临时启用某个仓库,仓库的ID |
conf_file= |
指明yum运行时采用哪个配置文件,而不是使用默认的配置文件 |
diable_gpg_check=yes|no |
是否启用gpg-check |
[root@crazyting1 ~]# ansible crazyting2 -m yum -a 'name=nmap state=present'
crazyting2 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package nmap.x86_64 2:5.51-6.el6 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n nmap x86_64 2:5.51-6.el6 base 2.8 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package(s)\n\nTotal download size: 2.8 M\nInstalled size: 9.7 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Installing : 2:nmap-5.51-6.el6.x86_64 1/1 \n\r Verifying : 2:nmap-5.51-6.el6.x86_64 1/1 \n\nInstalled:\n nmap.x86_64 2:5.51-6.el6 \n\nComplete!\n"
]
}
[root@crazyting1 ~]# ansible crazyting2 -m shell -a 'rpm -q nmap'
[WARNING]: Consider using the yum, dnf or zypper module rather than running rpm. If you need to use command because yum, dnf or zypper 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.
crazyting2 | SUCCESS | rc=0 >>
nmap-5.51-6.el6.x86_64
[root@crazyting1 ~]# ansible crazyting2 -m yum -a 'name=nmap state=absent'
crazyting2 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nSetting up Remove Process\nResolving Dependencies\n--> Running transaction check\n---> Package nmap.x86_64 2:5.51-6.el6 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nRemoving:\n nmap x86_64 2:5.51-6.el6 @base 9.7 M\n\nTransaction Summary\n================================================================================\nRemove 1 Package(s)\n\nInstalled size: 9.7 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Erasing : 2:nmap-5.51-6.el6.x86_64 1/1 \n\r Verifying : 2:nmap-5.51-6.el6.x86_64 1/1 \n\nRemoved:\n nmap.x86_64 2:5.51-6.el6 \n\nComplete!\n"
]
}
[root@crazyting1 ~]# ansible crazyting2 -m shell -a 'rpm -q nmap'
[WARNING]: Consider using the yum, dnf or zypper module rather than running rpm. If you need to use command because yum, dnf or zypper 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.
crazyting2 | FAILED | rc=1 >>
package nmap is not installednon-zero return code
- service模块
用来管理远程主机上的服务的模块
常见参数 |
描述 |
name= |
被管理的服务名称 |
state=started|stopped|restarted |
started启动服务, stopped停止服务, restarted重启服务, reloaded重载配置 |
enabled=yes|no |
表示要不要设定该服务开机自启动 |
runlevel= |
如果设定了enabled开机自动启动,则要定义在哪些运行级别下自动启动 |
[root@crazyting1 ~]# ansible crazyting2 -m service -a 'name=ntpd state=started'
crazyting2 | SUCCESS => {
"changed": true,
"name": "ntpd",
"state": "started"
}
[root@crazyting1 ~]# ansible crazyting2 -m shell -a 'service ntpd status'
[WARNING]: Consider using the service module rather than running service. If you need to use command because service 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.
crazyting2 | SUCCESS | rc=0 >>
ntpd (pid 12248) is running...
[root@crazyting1 ~]# ansible crazyting2 -m service -a 'name=ntpd state=stopped'
crazyting2 | SUCCESS => {
"changed": true,
"name": "ntpd",
"state": "stopped"
}
- uri模块
如果远端是web服务器,可以利用ansible直接请求某个网页
常见参数 |
描述 |
url= |
指明请求的url的路径,如:http://10.1.32.68/test.jpg
|
user= |
如果请求的url需要认证,则认证的用户名是什么 |
password= |
如果请求的url需要认证,则认证的密码是什么 |
method= |
指明请求的方法,如GET、POST… |
body= |
指明报文中实体部分的内容,一般是POST方法或PUT方法时用到 |
HEADER_ |
自定义请求报文中的添加的首部 |
- group模块
用来添加或删除远端主机的用户组
常见参数 |
描述 |
name= |
被管理的组名 |
state=present|absent |
是添加还是删除,不指名默认为添加 |
gid= |
指明GID |
system=yes|no |
是否为系统组 |
- user模块
管理远程主机上的用户的账号
常见参数 |
描述 |
name= |
指明要管理的账号名称 |
state=present|absent |
指明是创建账号还是删除账号,present表示创建,absent表示删除 |
system=yes|no |
指明是否为系统账号 |
uid= |
指明用户UID |
group= |
指明用户的基本组 |
groups= |
指明用户的附加组 |
shell= |
指明默认的shell |
home= |
指明用户的家目录 |
move_home=yes|no |
当home设定了家目录,如果要创建的家目录已存在,是否将已存在的家目录进行移动 |
password= |
指明用户的密码,最好使用加密好的字符串 |
comment= |
指明用户的注释信息 |
remove=yes|no |
当state=absent时,也就是删除用户时,是否要删除用户的而家目录 |
- script模块
将管理端的某个脚本,移动到远端主机(不需要指明传递到远端主机的哪个路径下,系统会自动移动,然后执行),
一般是自动移动到远端主机的/root/.ansible/tmp目录下,然后自动给予其权限,然后再开个子shell然后运行脚本,运行完成后删除脚本
[root@crazyting1 ~]# cat > test.sh<<EOF
> #!/bin/bash
> echo "hello world" >> /tmp/robin.txt
> EOF
[root@crazyting1 ~]# ansible crazyting2 -m script -a '/root/test.sh'
crazyting2 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to crazyting2 closed.\r\n",
"stderr_lines": [
"Shared connection to crazyting2 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@crazyting2 ~]# cat /tmp/robin.txt
hello world
- setup模块
可收集远程主机的facts变量的信息,相当于收集了目标主机的相关信息(如内核版本、操作系统信息、cpu、…),保存在ansible的内置变量中,之后我们有需要用到时,直接调用变量即可
[root@crazyting1 ~]# ansible crazyting2 -m setup -a 'filter="ansible_all_ipv4_addresses"'
crazyting2 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.2.115"
]
},
"changed": false
}
常用列表:
参数 |
描述 |
ansible_all_ipv4_addresses |
仅显示ipv4的信息。 |
ansible_devices |
仅显示磁盘设备信息。 |
ansible_distribution |
显示是什么系统,例:centos,suse等。 |
ansible_distribution_major_version |
显示是系统主版本。 |
ansible_distribution_version |
仅显示系统版本。 |
ansible_machine |
显示系统类型,例:32位,还是64位。 |
ansible_eth0 |
仅显示eth0的信息。 |
ansible_hostname |
仅显示主机名。 |
ansible_kernel |
仅显示内核版本。 |
ansible_lvm |
显示lvm相关信息。 |
ansible_memtotal_mb |
显示系统总内存。 |
ansible_memfree_mb |
显示可用系统内存。 |
ansible_memory_mb |
详细显示内存情况。 |
ansible_swaptotal_mb |
显示总的swap内存。 |
ansible_swapfree_mb |
显示swap内存的可用内存。 |
ansible_mounts |
显示系统磁盘挂载情况。 |
ansible_processor |
显示cpu个数(具体显示每个cpu的型号)。 |
ansible_processor_vcpus |
显示cpu个数(只显示总的个数)。 |
- template模块
基于模板方式,生成一个模板文件,复制到远程主机,让远程主机基于模板,生成符合远程主机自身的文件
注意:此模块不能在命令行使用,只能用在playbook中使用
常见的参数 |
描述 |
src= |
指明管理端本地的模板文件的目录 |
dest= |
指明将模板文件拷贝到远程主机的哪个目录下 |
owner= |
指明拷贝到远程主机的文件的属主 |
group= |
指明拷贝到远程主机的文件的属组 |
mode= |
指明拷贝到远程主机的文件的权限 |
下一篇我们将了解一下 Ansible的高级用法
参考文档:
Ansible基础命令