一.ansible简介:
当下有许多的运维自动化工具( 配置管理 ),例如:Ansible、SaltStack、Puppet、Fabric 等。
Ansible一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,是AnsibleWorks 公司名下的项目,该公司由 Cobbler 及 Func 的作者于 2012 年创建成立。
Ansible 基于 Python 语言实现,由 Paramiko 和 PyYAML 两个关键模块构建。
Ansible 特点:
部署简单,只需在主控端部署 Ansible 环境,被控端无需做任何操作。
默认使用 SSH(Secure Shell)协议对设备进行管理。
主从集中化管理。
配置简单、功能强大、扩展性强。
支持 API 及自定义模块,可通过 Python 轻松扩展。
通过 Playbooks 来定制强大的配置、状态管理。
对云计算平台、大数据都有很好的支持。
提供一个功能强大、操作性强的 Web 管理界面和 REST API 接口 —- AWX 平台。
Ansible 与 SaltStack
最大的区别是 Ansible 无需在被监控主机部署任何客户端代理,默认通过 SSH 通道进行远程命令执行或下发配置。
相同点是都具备功能强大、灵活的系统管理、状态配置,都使用 YAML 格式来描述配置,两者都提供丰富的模板及 API,对云计算平台、大数据都有很好的支持。
二.ansible安装
实验环境:
rhel6.5
server1 :172.25.62.1
ansible安装时所需的依赖包
[root@server1 rhel6]# ls
ansible-2.1.0.0-1.el6.noarch.rpm python-jinja2-26-2.6-3.el6.noarch.rpm
epel-release-6-5.noarch.rpm python-keyczar-0.71c-1.el6.noarch.rpm
libyaml-0.1.6-1.el6.x86_64.rpm python-six-1.9.0-2.el6.noarch.rpm
python-crypto2.6-2.6.1-2.el6.x86_64.rpm PyYAML-3.10-3.el6.x86_64.rpm
python-httplib2-0.7.7-1.el6.noarch.rpm sshpass-1.05-1.el6.x86_64.rpm
安装release包,会生成.repo的yum源配置文件
[root@server1 rhel6]# yum install -y ansible-2.1.0.0-1.el6.noarch.rpm
安装ansible需要网络
[root@server1 rhel6]# route add default gw 172.25.62.250
[root@server1 rhel6]# vim /etc/resolv.conf
nameserver 114.114.114.114
[root@server1 rhel6]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@server1 rhel6]# sysctl -p
[root@foundation66 ~]# iptables -t nat -I POSTROUTING -s 172.25.66.0/24 -j MASQUERADE
[root@server1 rhel6]# yum install -y ansible
[root@server1 rhel6]# rpm -qa |grep ansible
ansible-2.6.2-1.el6.noarch
ansible的配置文件
[root@server1 rhel6]# rpm -qc ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts
设置ansible主机
[root@server1 ~]# vim /etc/ansible/hosts
设置ssh免密登录
[root@server1 ~]# ssh-keygen
[root@server1 .ssh]# ssh-copy-id -i id_rsa.pub root@172.25.66.1
[root@server1 .ssh]# scp * root@172.25.66.2:/root/.ssh/
[root@server1 .ssh]# scp * root@172.25.66.3:/root/.ssh/
测试 Ansible
-i 指定 hosts 文件位置
-u username 指定 SSH 连接的用户名
-k 指定远程用户密码
-f 指定并发数
-s 如需要 root 权限执行时使用 ( 连接用户不是 root 时 )
-K -s 时,-K 输入 root 密码
查看ansible主机网络参数
[root@server1 ~]# ansible all -m command -a 'ifconfig'
172.25.66.2 | SUCCESS | rc=0 >>
eth0 Link encap:Ethernet HWaddr 52:54:00:DA:1D:9B
inet addr:172.25.66.2 Bcast:172.25.66.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:feda:1d9b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2196 errors:0 dropped:0 overruns:0 frame:0
TX packets:1728 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4606842 (4.3 MiB) TX bytes:239445 (233.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:344 (344.0 b) TX bytes:344 (344.0 b)
172.25.66.3 | SUCCESS | rc=0 >>
eth0 Link encap:Ethernet HWaddr 52:54:00:13:BB:88
inet addr:172.25.66.3 Bcast:172.25.66.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe13:bb88/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1941 errors:0 dropped:0 overruns:0 frame:0
TX packets:1531 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4461223 (4.2 MiB) TX bytes:223293 (218.0 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:344 (344.0 b) TX bytes:344 (344.0 b)
shell模块在远程主机上调用shell解释器运行命令,支持shell的各种功能 :
[root@server1 ~]# ansible all -m shell -a 'tail /etc/passwd'
172.25.66.3 | SUCCESS | rc=0 >>
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
172.25.66.2 | SUCCESS | rc=0 >>
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
copy:复制文件到远程主机,可以改权限等
复制文件,指定路径 -a “src= dest= ” 给定内容生成文件 -a “content= dest= “
[root@server1 ~]# cat test.txt
hello
[root@server1 ~]# ansible server -m copy -a 'src="/root/test.txt" dest=/root/'
172.25.66.2 | SUCCESS => {
"changed": false,
"checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"dest": "/root/test.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/root/test.txt",
"size": 6,
"state": "file",
"uid": 0
}
172.25.66.3 | SUCCESS => {
"changed": false,
"checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"dest": "/root/test.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/root/test.txt",
"size": 6,
"state": "file",
"uid": 0
[root@server2 ~]# ls
test.txt
[root@server2 ~]# cat test.txt
hello
[root@server3 ~]# ls
test.txt
[root@server3 ~]# cat test.txt
hello
file 设置文件属性:
创建目录:-a “path= state=directory”
创建链接文件:-a “path= src= state=link”
删除文件:-a “path= state=absent”
[root@server1 ~]# ansible server -m file -a 'path="/root/test/" state=directory'
172.25.66.2 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/test/",
"size": 4096,
"state": "directory",
"uid": 0
}
172.25.66.3 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/test/",
"size": 4096,
"state": "directory",
"uid": 0
}
[root@server3 ~]# ll
total 8
drwxr-xr-x 2 root root 4096 Aug 17 00:24 test
-rw-r--r-- 1 root root 6 Aug 16 23:49 test.txt
fetch从远程某主机获取文件到本地:
dest:用来存放文件的目录
Src:在远程拉取的文件,并且必须是一个file,不能是目录
例:获取ansible_host的passwd文件
[root@server1 ~]# ansible server -m fetch -a 'src=/etc/passwd dest=/root/'
172.25.66.2 | SUCCESS => {
"changed": true,
"checksum": "4b57f47f636291d496187d0c9f2ea1c0276428ba",
"dest": "/root/172.25.66.2/etc/passwd",
"md5sum": "499b16cbdef03e814f3405fccd188dcc",
"remote_checksum": "4b57f47f636291d496187d0c9f2ea1c0276428ba",
"remote_md5sum": null
}
172.25.66.3 | SUCCESS => {
"changed": true,
"checksum": "4b57f47f636291d496187d0c9f2ea1c0276428ba",
"dest": "/root/172.25.66.3/etc/passwd",
"md5sum": "499b16cbdef03e814f3405fccd188dcc",
"remote_checksum": "4b57f47f636291d496187d0c9f2ea1c0276428ba",
"remote_md5sum": null
}
yum 安装软件
name= #所安装的包的名称
state=present|latest|absent #present安装,latest安装最新的,absent 卸载软件。
update_cache #强制更新yum的缓存。yum安装软件
--------------------
conf_file #设定远程yum安装时所依赖的配置文件。如配置文件没有在默认的位置。
disable_gpg_check #是否禁止GPG checking,只用于‘present’ or `latest’。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
[root@server1 ~]# ansible server -m yum -a 'name=vsftpd state=present'
[root@server2 ~]# rpm -qa|grep vsftpd
vsftpd-2.2.2-11.el6_4.1.x86_64
cron管理cron计划任务
action: cron backup= #如果设置,创建一个crontab备份 [yes|no]
cron_file= #如果指定, 使用这个文件cron.d,而不是单个用户
crontab:
day= #日应该运行的工作( 1-31, *, */2, )
hour= #小时 ( 0-23, *, */2, )
minute= #分钟( 0-59, *, */2, )
month= #月( 1-12, *, /2, )
weekday #周 ( 0-6 for Sunday-Saturday,, )
job= #指明运行的命令是什么
name= #定时任务描述
reboot #任务在重启时运行,不建议使用,建议使用special_time
special_time #特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user #以哪个用户的身份执行
service: 服务程序管理
name= #服务名称
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。
state= #started启动服务, stopped停止服务, restarted重启服务, reloaded重载配置
enabled=true|false #设置开机启动。
runlevel #开机启动的级别,一般不用指定
[root@server1 ~]# ansible server -m service -a 'name=vsftpd state=started enabled=true'
172.25.66.3 | SUCCESS => {
"changed": true,
"enabled": true,
"name": "vsftpd",
"state": "started"
}
172.25.66.2 | SUCCESS => {
"changed": true,
"enabled": true,
"name": "vsftpd",
"state": "started"
}
[root@server2 ~]# /etc/init.d/vsftpd status
vsftpd (pid 1965) is running...
[root@server3 ~]# /etc/init.d/vsftpd status
vsftpd (pid 1883) is running...
user模块管理
用户模块,管理用户帐号 action: user
createhome #是否创建家目录
force #在使用state=absent是, 行为与userdel –force一致.
group #指定基本组
groups #指定附加组,如果指定为(groups=)表示删除所有组
home #指定用户家目录
move_home #如果设置为home=时, 试图将用户主目录移动到指定的目录
name #指定用户名
non_unique #该选项允许改变非唯一的用户ID值
password #指定用户密码
remove #在使用state=absent时, 行为是与userdel –remove一致
shell #指定默认shell
state #设置帐号状态,不指定为创建,指定值为absent表示删除
system #当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid #指定用户的uid
update_password #更新用户密码
[root@server1 etc]# ansible server -m user -a 'name=ansible comment="ansible" uid=3333 shell=/bin/bash'
172.25.66.2 | SUCCESS => {
"append": false,
"changed": true,
"comment": "ansible",
"group": 3333,
"home": "/home/ansible",
"move_home": false,
"name": "ansible",
"shell": "/bin/bash",
"state": "present",
"uid": 3333
}
172.25.66.3 | SUCCESS => {
"append": false,
"changed": true,
"comment": "ansible",
"group": 3333,
"home": "/home/ansible",
"move_home": false,
"name": "ansible",
"shell": "/bin/bash",
"state": "present",
"uid": 3333
}
[root@server2 ~]# id ansible
uid=3333(ansible) gid=3333(ansible) groups=3333(ansible)
script
[root@server1 ~]# vim test.sh
[root@server1 ~]# cat test.sh
#!/bin/bash
for i in {1..10}
do
echo $i
done
[root@server1 ~]# ansible server -m script -a '/root/test.sh'
172.25.66.3 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stderr_lines": [],
"stdout": "1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n",
"stdout_lines": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10"
]
}
172.25.66.2 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stderr_lines": [],
"stdout": "1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n",
"stdout_lines": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10"
]
}