1ansible介绍
- Ansible基于Python语言实现,由paramiko和PyYAML两个关键模块构建
- 不需要安装客户端,通过sshd去通信
- 基于模块工作,模块可以由任何语言开发
- 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读
- 有提供UI(浏览器图形化)www.ansible.com/tower,收费的
- 官方文档 http://docs.ansible.com/ansible/latest/index.html
- ansible已经被redhat公司收购,它在github上是一个非常受欢迎的开源软件,github地址https://github.com/ansible/ansible
- 一本不错的入门电子书 https://ansible-book.gitbooks.io/ansible-first-book/
- Ansible的基本架构:
1. 核心引擎:即图中所看到的ansible
2. 核心模块(core module):在模块库(module library)中分为两块,一个是核心模块另外一个就是自定义模块(custom modules)。核心模块中都是ansible自带的模块,Ansible模块资源分发到远程节点使其执行特定任务或匹配一个特定的状态。这些核心核心模块都遵循这batteries included哲学。其实这里这个还是很有意思的,batterires included:Python has a large standard library, commonly cited as one of Python’s greatest strengths,providing tools suited to many tasks. 这就意味着Python有这巨大的库支持你完成你想完成的任务工作。
3. 自定义模块(custom modules):如果在Ansible中满足不了你所需求的模块,那么Ansible也能提供添加自定义化的模块。
4. 插件(plugin):这里我的理解就是完成较小型的任务。辅助协助模块来完成某个功能。
5. 剧本(playbook):定义需要给远程主机执行的一系列任务。例如安装一个nginx服务,那么我们可以把这拆分为几个任务放到一个playbook中。例如:第一步需要下载nginx的安装包。第二步我可能考虑需要做的就是将我事先写好的nginx.conf的配置文件下发的目标服务器上。第三步,我们需要把服务启动起来。第四步,我们可能需要检查端口是否正常开启。那么这些步骤可以通过playbook来进行整合,然后通过inventory来下发到想要执行剧本的主机上。并且playbook也支持交互式执行playbook里面的步骤,而且如果有那一个步骤执行返回了一个错误报告,那么我们可以仅仅只单独执行这个步骤。你可以把playbook理解成为一个组策略,控制管理这个OU下所有的主机行为。
6. 连接插件(connectior plugins):Ansible默认是基于SSH连接到目标机器上执行操作的。但是同样的Ansible支持不同的连接方法,要是这样的话就需要连接插件来帮助我们完成连接了。
7. 主机清单(host inventory):为Ansible定义了管理主机的策略。一般小型环境下我们只需要在host文件中写入主机的IP地址即可,但是到了中大型环境我们有可能需要使用静态inventory或者动态主机清单来生成我们所需要执行的目标主机。
2 ansible安装
- 环境:准备两台机器
- chy 192.168.212.10 //只需要在这台机器上安装ansible
- chy01 192.168.212.11
- 安装如下 chy//192.168.212.10
[[email protected] ~]# yum list |grep ansible //看到有2.4版本的yum包,只需要安装自带的源即可 ansible.noarch 2.4.0.0-5.el7 extras ansible-doc.noarch 2.4.0.0-5.el7 extras ansible-inventory-grapher.noarch 2.3.2-1.el7 epel ansible-lint.noarch 3.4.15-1.el7 epel ansible-openstack-modules.noarch 0-20140902git79d751a.el7 epel ansible-review.noarch 0.13.0-2.el7 epel kubernetes-ansible.noarch 0.6.0-0.1.gitd65ebd5.el7 epel python2-ansible-tower-cli.noarch 3.1.7-1.el7 epel [[email protected] ~]# yum install -y ansible ansible-doc //安装ansible [[email protected] ~]# ls /root/.ssh/ //查看有没有密钥对,如果有就无需在重新生成,如果之前没有生成过需要用ssh-keygen生成一下密钥对。 authorized_keys id_rsa id_rsa.pub known_hosts 之后将公钥复制到另一台机器上 [[email protected] ~]# cat .ssh/authorized_keys //公钥已经放在了里面 [[email protected] ~]# ssh chy01 The authenticity of host ‘chy01 (192.168.212.11)‘ can‘t be established. ECDSA key fingerprint is de:d2:32:86:e0:89:5c:2c:51:68:92:9b:7e:40:52:5c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added ‘chy01‘ (ECDSA) to the list of known hosts. Last login: Wed Nov 8 01:04:24 2017 from chy # cat /etc/motd [[email protected] ~]# vi /etc/ansible/hosts //配置主机组 ## [webservers] ## alpha.example.org ## beta.example.org ## 192.168.1.100 ## 192.168.1.110 [testhost] chy02 chy01 说明: testhost为主机组名字,自定义的。 下面两个ip为组内的机器ip。 增加testhost里的内容,testhost下面可以写主机名也可以写ip地址,如果写了主机名切记需要去/etc/hosts里配置,如果做了dns则不需要去/etc/hosts配置(这里需要注意的是组里添加的机器的前提是都要做密钥认证的)
3ansible远程执行命令
-远程执行命令操作如下
[[email protected] ~]# ansible testhost -m command -a ‘w‘ chy01 | SUCCESS | rc=0 >> 01:46:28 up 1:00, 2 users, load average: 0.16, 0.05, 0.06 USER TTY FROM [email protected] IDLE JCPU PCPU WHAT root pts/0 192.168.212.1 00:54 37:48 0.02s 0.02s -bash root pts/1 chy 01:46 0.00s 0.26s 0.05s w chy02 | SUCCESS | rc=0 >> 01:46:28 up 2:24, 2 users, load average: 0.00, 0.01, 0.05 USER TTY FROM [email protected] IDLE JCPU PCPU WHAT root pts/0 192.168.212.1 00:27 1:08m 0.02s 0.02s -bash root pts/1 chy 01:46 1.00s 0.30s 0.00s w 语法介绍:ansible 后跟定义的主机组 -m 跟模块,- a跟需要执行的命令 [[email protected] ~]# ansible chy01 -m command -a ‘hostname‘ chy01 | SUCCESS | rc=0 >> chy01 如上也可以只针对一台机器进行操作
如果出现了如下错误,请按照如下的方法解决
ansible 127.0.0.1 -m command -a ‘hostname‘ 错误:"msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren‘t installed!" 解决:yum install -y libselinux-python
4 anonymous拷贝文件或目录
[[email protected] ~]# ansible chy01 -m copy -a "src=/etc/ansible dest=/tmp/ansible_test owner=root group=root mode=0755" chy01 | SUCCESS => { "changed": true, "dest": "/tmp/ansible_test/", "failed": false, "src": "/etc/ansible" } 拷贝目录注意:源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,dest指定的名字和源如果不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。 [[email protected] ~]# ansible chy01 -m copy -a "src=/etc/passwd dest=/tmp owner=root group=root mode=0755" //copy文件 chy01 | SUCCESS => { "changed": true, "checksum": "84c5bb4be970a90c7157c2d57401ca0ac0039eca", "dest": "/tmp/passwd", "failed": false, "gid": 0, "group": "root", "md5sum": "177c3249629069b366250d27ef7820df", "mode": "0755", "owner": "root", "size": 2182, "src": "/root/.ansible/tmp/ansible-tmp-1510078509.74-153887684649484/source", "state": "file", "uid": 0 }
[[email protected] ~]# ansible chy01 -m copy -a "src=/etc/passwd dest=/tmp/copy.txt owner=root group=root mode=0755" //这里需要注意一下就是如果想要将cp过去的文件改名称直接可以在cp的过程中改名字,在操作时拷贝到相应的目录后,后面直接跟文件名,这样就会直接cp过去的
chy01 | SUCCESS => {
"changed": true,
"checksum": "84c5bb4be970a90c7157c2d57401ca0ac0039eca",
"dest": "/tmp/copy.txt",
"failed": false,
"gid": 0,
"group": "root",
"md5sum": "177c3249629069b366250d27ef7820df",
"mode": "0755",
"owner": "root",
"size": 2182,
"src": "/root/.ansible/tmp/ansible-tmp-1510078638.87-216978821762184/source",
"state": "file",
"uid": 0
}
[[email protected] ~]# ls -ls /tmp/copy.txt //可以查看到已经cp过来并且已经改名成功
4 -rwxr-xr-x 1 root root 2182 Nov 8 02:17 /tmp/copy.txt
5 ansible远程执行脚本
- shell模块是用来执行脚本的,如下是更详细的操作
[[email protected] ~]# cat /tmp/1.sh #!/bin/bash echo `date` > /tmp/ansible_test.txt 写一个输出时间的脚本 之前的saltstack脚本可以直接搞到远程并且执行,但是ansible必须先拷贝,之后在执行 [[email protected] ~]# ansible testhost -m copy -a "src=/tmp/1.sh dest=/tmp/test.sh mode=0755" //执行的是两台机器 chy02 | SUCCESS => { "changed": true, "checksum": "1d452b51a06996a4ead87e91a7a288d3318f3e0c", "dest": "/tmp/test.sh", "failed": false, "gid": 0, "group": "root", "md5sum": "8d6e5eb9fca38ae7c456a9da182e4426", "mode": "0755", "owner": "root", "size": 50, "src": "/root/.ansible/tmp/ansible-tmp-1510080028.29-281241865001849/source", "state": "file", "uid": 0 } chy01 | SUCCESS => { "changed": true, "checksum": "1d452b51a06996a4ead87e91a7a288d3318f3e0c", "dest": "/tmp/test.sh", "failed": false, "gid": 0, "group": "root", "md5sum": "8d6e5eb9fca38ae7c456a9da182e4426", "mode": "0755", "owner": "root", "size": 50, "src": "/root/.ansible/tmp/ansible-tmp-1510080028.3-155921385180503/source", "state": "file", "uid": 0 } [[email protected] ~]# ansible testhost -m shell -a "/tmp/test.sh" //之后在执行脚本,-a 后跟执行的脚本即可 chy01 | SUCCESS | rc=0 >> chy02 | SUCCESS | rc=0 >>
- command不能带管道符,而shell可以用管道符
测试如下
[[email protected] ~]# ansible chy01 -m command -a "cat /etc/passwd|wc -l" chy01 | FAILED | rc=1 >> cat:无效选项 -- l Try ‘cat --help‘ for more information.non-zero return code [[email protected] ~]# ansible chy01 -m shell -a "cat /etc/passwd|wc -l" chy01 | SUCCESS | rc=0 >> 34
6 管理计划
- 管理计划用到的模块是cron
如下操作
[[email protected] ~]# ansible chy01 -m cron -a "name=‘test cron‘ job=‘/bin/touch/tmp/1212.txt‘ weekday=6" -m 后跟模块的名称,-a 跟执行的命令"name 跟任务的名称,job跟命令是什么,在后面就是分时日月周,如果定义就跟具体的,不定义直接跟*就可以 chy01 | SUCCESS => { "changed": true, "envs": [], "failed": false, "jobs": [ "test cron" ] } [[email protected] ansible]# crontab -l //查看任务计划 0 0 * * * /bin/bash /usr/local/sbin/nginx_logrotate.sh 0 1 * * * /bin/python /home/jumpserver/manage.py crontab run 3718e5baf203ed0f54703b2f0b7e9e16 # django-cronjobs for jumpserver */10 * * * * /bin/python /home/jumpserver/manage.py crontab run 9956b75140f4453ab1dc4aeb62962a74 # django-cronjobs for jumpserver # Lines below here are managed by Salt, do not edit #Ansible: test cron * * * * 6 /bin/touch/tmp/1212.txt You have new mail in /var/spool/mail/root [[email protected] ~]# ansible testhost -m cron -a "name=‘test cron‘ state=absent" 删除任务计划 chy01 | SUCCESS => { "changed": true, "envs": [], "failed": false, "jobs": [] } 切记在做任务计划时千万不要手动修改,任务计划里的# # Lines below here are managed by Salt, do not edit #Ansible: test cron 这行内容。
希望看过的童鞋多多指教,谢谢!