Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成,类似于Chef和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。
之前也在网上找了一些RHEL6的配置文档,基本都是编译安装有点麻烦,还得注意python版本小于3.x,如果用RHEL7\CENTOS7的话只要先安装好epel7的源,下面都是自动依赖安装的超方便,所以强烈推荐用RHEL7\CENTOS7安装。
如果硬要编译安装可访问主页:https://github.com/ansible/ansible
playbook虽然很实用但目前用的不多,故不做详细记录,参考:http://www.361way.com/ansible-playbook-example/4441.html
root用户无法登陆,普通用户登录后su过去遇到的问题,参考:http://www.361way.com/ansible-su/4882.html
本篇中我们将在RHEL 7上安装并配置Ansible,并且尝试管理两个节点
服务端:192.168.180.99
客户端:192.168.180.97\98
一、设置EPEL仓库
Ansible仓库默认不在yum仓库中,因此我们需要使用下面的命令启用epel仓库。
rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-8.noarch.rpm
二、yum安装ansible
yum install ansible ansible --version #没错的话就是最新版的2.2
三、设置ssh鉴权
其实很简单就是ansible服务端生成rsa的key给到客户端,这样服务端就可以不用输入密码直接登录客户端了,是不是很方便!
#默认不设置加密密码,目录~/.ssh/id_rsa.pub ssh-keygen -i rsa -P '' #该命令会自动给服务端key添加到客户端的~/.ssh/authorized_keys中 ssh-copy-id -id [email protected]\97
四、ansible节点清单
1、给服务端ansible定义节点清单
vim /etc/ansible/hosts [test] #这里用域名、主机名、IP都可以 192.168.180.97 192.168.180.98 [other] #起个别名 jumper ansible_ssh_port = 5555 ansible_ssh_host = 192.168.1.50 #定了从web1到web50,webservers组共计50台主机 www[01:50].361way.com #databases组有db-a到db-f共6台主机 db-[a:f].91it.org
2、使用主机变量
以下是Hosts部分中经常用到的变量部分
ansible_ssh_host # 要连接的主机名 ansible_ssh_port # 端口号默认是22 ansible_ssh_user # ssh连接时默认使用的用户名 ansible_ssh_pass # ssh连接时的密码 ansible_sudo_pass # 使用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 解释器的路径,同样可以指定ruby 、perl 的路径
示例如下:
[test1] 10.212.52.252 ansible_ssh_user=root ansible_ssh_pass='361way.com' 10.212.52.14 ansible_ssh_user=test1 ansible_ssh_pass='91it.org' 10.212.52.16 ansible_ssh_user=test2 ansible_ssh_port=7788 ansible_ssh_pass='123456'
3、组内变量
变量也可以通过组名,应用到组内的所有成员:
[test] host1 host2 [test:vars] ntp_server=ntp.aaa.com proxy=proxy.bbb.com
上面test组中包含两台主机,通过对test组指定vars变更,相应的host1和host2相当于相应的指定了ntp_server和proxy变量参数值 。
4、组的包含与组内变量
[hangzhou] host1 host2 [jiaxing] host2 host3 [zhejiang:children] hangzhou jiaxing [zhejiang:vars] some_server=foo.southeast.example.com halon_system_timeout=30 self_destruct_countdown=60 escape_pods=2 [china:children] zhejiang henan shandong hebei
如上面的示例中,我指定了杭州组我有host1、hosts2;嘉兴组我有host3、host4主机;我又指定了一个组浙江组,同时包含杭州和嘉兴;同时为该组内的所有主机指定了四个vars变量。后面我又设定了一个组中国组,包含浙江、河南、山东、河北。
注:由于vars变量在ansible ad-hoc部分中基本用不到,主要用在ansible-playbook中,后面的章节部分也会提到。
五、ansible常用功能
更多更详细的话参考:http://www.361way.com/ansible-modules/4415.html
1、ping模块:看到ping字段为pong即为通,该功能主要用于批量检测连通性
ansible -m ping test
2、执行shell命令的command默认模块,用于远程执行命令,不支持变量,例子:
#查看当前用户 ansible -m command -a 'w' test #查看日期 ansible -m command -a 'date' test #给节点增加用户 ansible -m command -a 'useradd mark' test ansible -m command -a 'grep mark /etc/passwd' test #重定向输出到文件 ansible -m command -a 'df -Th' test > /root/test.log
3、cron定时任务,例子:
ansible test -m cron -a 'minute="*/1" job="/bin/echo "hell"" name="test job" ' #查看是否成功,另外注意:这里既然生成了,就立即生效,不用重启crond进程 ansible test -m command -a 'crontab -l'
4、user管理,例子:
ansible test -m user -a 'name=mark' #查看是否成功,现在不明白和command useradd添加有什么区别,但是既然有用户管理还是用它好了 ansible -m command -a 'grep mark /etc/passwd' test
5、远程复制模块copy,例子:
#如果要想远程复制文件成功,必须给所有客户端安装这个。。。不知道为什么,如果不装复制失败报错 ansible -m command -a 'yum install libselinux-python -y' 'test ansible -m copy -a 'src=/root/VMwareTools-9.4.10-2068191.tar.gz dest=/root owner=root mode=640' 'test' #往远程主机文件写入内容:使用content代替src ansible -m copy -a 'content="aaabbb\n" dest=/root/test.log' test
6、设置文件属性模块file,例子:
#当然group\mode\owner不写也行 ansible test -m file -a 'owner=mark group=root mode=644 path=/root/test.log' #创建文件符号链接 ansible test -m file -a 'path=/root/test.1 src=/root/test.log state=link'
7、service指定服务状态模块管理(须保证远程主机已安装好该服务),例子:
#enableed:是否开机自动启动 true/false #name:服务名称 #start:状态,取值为started,stoped,restarted ansible test -m service -a 'enabled=true name=httpd state=started'
8、shell模块: 在远程主机上运行命令,支持管道、变量等在使用复制命令时使用,例子:
#该功能好用,可以批量更改客户端用户密码 ansible test -m shell -a 'echo password |passwd –stdin mark'
9、script将本地脚步复制到远程主机上并运行(注意本地主机脚步路径使用相对路劲),例子:
ansible test -m script -a "test.sh"
10、yum程序安装,例子
#name指定要安装的程序包,可以带上版本号 #state:preset,laster表示安装最新,absent卸载 ansible test -m yum -a 'name=lrzsz'
11、setup收集远程主机的facts,例子:
#查看所有 ansible test -m setup #查看IP配置 ansible test -m setup -a 'filter=ansible_default_ipv4' #查看内存信息 ansible test -m setup -a 'filter=ansible_memory_mb' #查看主机名 ansible test -m setup -a 'filter=ansible_nodename'
每个被管理节点在接受并运行管理命令之前,会将自己主机相关信息,操作系统版本、ip地址等会报告给ansible主机用于将状态报告给ansible主机直接调用其变量。
12、其他
#查看模块帮助命令 ansible-doc -l #查看支持模块 ansible-doc -s Modules
六、Patterns(主机与组正则匹配部分)
把Patterns 直接理解为正则实际是不完全准确的,正常的理解为patterns意味着在ansible中管理哪些主机,也可以理解为,要与哪台主机进行通信。在探讨这个问题之前我们先看下ansible的用法:
ansible-m -a
直接上一个示例:
ansible webservers -m service -a "name=httpd state=restarted"
这里是对webservers 组或主机重启httpd服务 ,其中webservers 就是Pattern部分。而之所以上面我说Pattern(模式)可以理解为正则,主要针对下面经常用到的用法而言的。
1、表示所有的主机可以使用all 或 *
2、通配符与逻辑或
利用通配符还可以指定一组具有规则特征的主机或主机名,冒号表示or---逻辑或
one.361way.com one.361way:two.361way.com 192.168.1.50 192.168.1.*
当然,这里的*通配符也可以用在前面,如:
*.361way.com *.com
上面的用法,在多个组之间同样适用 ,如:
webservers webservers:dbservers #表示两个组中所有的主机
3、逻辑非与逻辑and
当然你可以做出非的表达式,例如,目标主机必须在组webservers但不在phoenix组中
webserver:!phoenix
你还可以做出交集的表达式,例如,目标主机必须即在组webservers中又在组staging中
webservers:&staging
一个更复杂的示例:
webserver:dbservers:&staging:!phoenix
上面这个复杂的表达式最后表示的目标主机必须满足:在webservers或者dbservers组中,必须还存在于staging组中,但是不在phoenix组中。这些可以看作是SaltStack中Compound matchers 。
4、混合高级用法
*.361way.com:*.org
还可以在开头的地方使用”~”,用来表示这是一个正则表达式:
~(web|db).*\.91it\.org
到这里估计你应该用能明白为什么前面我会提到Patterns 可以理解为正则的原因了。最后部分给两个ansible-playbook中具体可能用的用法:
a、在ansible-palybook命令中,你也可以使用变量来组成这样的表达式,但是你必须使用“-e”的选项来指定这个表达式(通常我们不这样用):
ansible-palybook -e webservers:!`excluded`:&`required`
b、在ansible和ansible-playbook中,还可以通过一个参数”–limit”来明确指定排除某些主机或组:
ansible-playbook site.yml --limit datacenter2