Ansible介绍
- 不需要安装客户端,通过sshd去通信
- 基于模块工作,模块可以由任何语言开发
- 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读 安装十分简单,centos上可直接yum安装
- 有提供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安装
- 准备两台机器,前面我们做实验的两台机器aming-01,aming-02
- 只需要在aming-01上安装ansible
- yum list |grep ansible 可以看到自带源里就有2.4版本的ansible
- yum install -y ansible
- aming-01上生成密钥对 ssh-keygen -t rsa
- 把公钥放到aming-02上,设置密钥认证
- vi /etc/ansible/hosts //增加
[testhost]
127.0.0.1
192.168.133.132 说明: testhost为主机组名字,自定义的。 下面两个ip为组内的机器ip。
<root@linux0 /srv/salt>$ yum list |grep ansible ansible.noarch 2.4.2.0-2.el7 @extras ansible-doc.noarch 2.4.2.0-2.el7 @extras centos-release-ansible26.noarch 1-3.el7.centos extras <root@linux0 /srv/salt>$ yum install ansible ansible-doc <root@linux0 /srv/salt>$ ssh 192.168.87.150 root@192.168.87.150's password: <root@linux0 /srv/salt>$ ssh-copy-id 192.168.87.150 <root@linux0 /srv/salt>$ vim /etc/ansible/hosts [thosts] 192.168.87.149 192.168.87.150
Ansible远程执行命令
- ansible testhost -m command -a ‘w’ 这样就可以批量执行命令了。
- 这里的testhost 为主机组名,-m后边是模块名字,-a后面是命令。当然我们也可以直接写一个ip,针对某一台机器来执行命令。
- 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
- 还有一个模块就是shell同样也可以实现 ansible testhost -m shell -a ‘w’
<root@linux0 /srv/salt>$ ansible thosts -m command -a 'hostname' 192.168.87.150 | SUCCESS | rc=0 >> linux1 192.168.87.149 | SUCCESS | rc=0 >> linux0 <root@linux0 /srv/salt>$ ansible thosts -m shell -a "ps aux |grep http" 192.168.87.150 | SUCCESS | rc=0 >> 192.168.87.149 | SUCCESS | rc=0 >> <root@linux0 /srv/salt>$ ansible thosts -m command -a "ps aux |grep http" 192.168.87.150 | FAILED | rc=1 >> error: garbage option 192.168.87.149 | FAILED | rc=1 >> error: garbage option
Ansible拷贝文件或者目录
- ansible aming-02 -m copy -a “src=/etc/ansible dest=/tmp/ansibletest owner=root group=root mode=0755”
- 注意:源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,dest指定的名字和源如果不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。
- ansible testhost -m copy -a “src=/etc/passwd dest=/tmp/123”
这里的/tmp/123和源机器上的/etc/passwd是一致的,但如果目标机器上已经有/tmp/123目录,则会再/tmp/123目录下面建立passwd文件
<root@linux0 ~>$ vi /etc/ansible/hosts [thosts] 192.168.87.149 linux1 <root@linux0 ~>$ ansible 192.168.87.150 -m command -a "w" [WARNING]: Could not match supplied host pattern, ignoring: 192.168.87.150 [WARNING]: No hosts matched, nothing to do <root@linux0 ~>$ cat !$ cat /etc/hosts 192.168.87.150 linux1 <root@linux0 ~>$ ansible linux1 -m command -a "w" linux1 | SUCCESS | rc=0 >> 12:32:38 up 21 days, 22:45, 2 users, load average: 0.10, 0.18, 0.13 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/1 192.168.87.1 五17 3:18 0.13s 0.13s -bash root pts/2 linux0 12:32 0.00s 0.10s 0.00s w
<root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible dest=/tmp/bucunzai owner=root group=root mode=0755" linux1 | SUCCESS => {
"changed": true, "dest": "/tmp/bucunzai/", "src": "/etc/ansible" } <root@linux0 ~>$ ansible linux1 -m command -a "ls -ld /tmp/bucunzai" linux1 | SUCCESS | rc=0 >> drwxr-xr-x 3 root root 21 12月 30 12:37 /tmp/bucunzai <root@linux0 ~>$ date 2019年 12月 30日 星期一 12:37:55 CST <root@linux0 ~>$ ansible linux1 -m command -a "ls -l /tmp/bucunzai" linux1 | SUCCESS | rc=0 >> 总用量 0 drwxr-xr-x 3 root root 51 12月 30 12:37 ansible <root@linux0 ~>$ ls /etc/ansible ansible.cfg hosts roles <root@linux0 ~>$ ll !$ ll /etc/ansible 总用量 24 -rw-r--r-- 1 root root 19179 1月 30 2018 ansible.cfg -rw-r--r-- 1 root root 1062 12月 30 12:28 hosts drwxr-xr-x 2 root root 6 1月 30 2018 roles <root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts dest=/tmp/bucunzaifile" linux1 | SUCCESS => {
"changed": true, "checksum": "d2498e8c027056bced372d02a144ad2a5", "dest": "/tmp/bucunzaifile", "gid": 0, "group": "root", "md5sum": "9e8b0416c70cd4cbc058dee4", "mode": "0644", "owner": "root", "size": 1062, "src": "/root/.ansible/tmp/ansible-tmp-.99-404/source", "state": "file", "uid": 0 } <root@linux0 ~>$ ansible linux1 -m command -a "ll /tmp/bucunzaifile" linux1 | FAILED | rc=2 >> [Errno 2] 没有那个文件或目录 <root@linux0 ~>$ ansible linux1 -m command -a "ls -l /tmp/bucunzaifile" linux1 | SUCCESS | rc=0 >> -rw-r--r-- 1 root root 1062 12月 30 12:47 /tmp/bucunzaifile <root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts dest=/tmp/bucunzai2/bucunzaifile" linux1 | FAILED! => {
"changed": false, "checksum": "d2498e8c027056bced372d02a144ad2a5", "msg": "Destination directory /tmp/bucunzai2 does not exist" } <root@linux0 ~>$ ansible linux1 -m copy -a "src=/etc/ansible/hosts dest=/tmp/bucunzai/bucunzaifile" linux1 | SUCCESS => {
"changed": true, "checksum": "d2498e8c027056bced372d02a144ad2a5", "dest": "/tmp/bucunzai/bucunzaifile", "gid": 0, "group": "root", "md5sum": "9e8b0416c70cd4cbc058dee4", "mode": "0644", "owner": "root", "size": 1062, "src": "/root/.ansible/tmp/ansible-tmp-.34-145/source", "state": "file", "uid": 0 }
Ansible远程执行脚本
- 首先创建一个shell脚本
vim /tmp/test.sh //加入内容
#!/bin/bash echo
date > /tmp/ansible_test.txt
- 然后把该脚本分发到各个机器上
ansible testhost -m copy -a “src=/tmp/test.sh dest=/tmp/test.sh mode=0755”
- 最后是批量执行该shell脚本
ansible testhost -m shell -a “/tmp/test.sh”
- shell模块,还支持远程执行命令并且带管道
ansible testhost -m shell -a "cat /etc/passwd|wc -l "
root@linux0 ~>$ vim /tmp/test.sh [root@linux0 ~] echo `date` > /tmp/ansible_test.txt [root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "checksum": "432f5691b624e4f391ca4f564e99845d58c0eeab", "dest": "/tmp/test.sh", "gid": 0, "group": "root", "md5sum": "bb8fe20b104f03555ca8374f0bf68caa", "mode": "0755", "owner": "root", "size": 49, "src": "/root/.ansible/tmp/ansible-tmp-.11-4552/source", "state": "file", "uid": 0 } 192.168.87.149 | SUCCESS => {
"changed": false, "checksum": "432f5691b624e4f391ca4f564e99845d58c0eeab", "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/test.sh", "size": 49, "state": "file", "uid": 0 } [root@linux0 ~] linux1 | SUCCESS | rc=0 >> 192.168.87.149 | SUCCESS | rc=0 >> [root@linux0 ~] linux1 | SUCCESS | rc=0 >> 2019年 12月 30日 星期一 13:56:07 CST 192.168.87.149 | SUCCESS | rc=0 >> 2019年 12月 30日 星期一 13:56:08 CST
Ansible管理任务计划
- ansible testhost -m cron -a “name=‘test cron’ job=’/bin/touch /tmp/1212.txt’ weekday=6”
- 若要删除该cron 只需要加一个字段 state=absent
- ansible testhost -m cron -a “name=‘test cron’ state=absent”
- 其他的时间表示:分钟 minute 小时 hour 日期 day 月份 month
[root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "envs": [], "jobs": [ "test cron" ] } 192.168.87.149 | SUCCESS => {
"changed": true, "envs": [], "jobs": [ "test cron" ] } [root@linux0 ~] 1 3 10 * * /bin/touch /tmp/1212.txt [root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "envs": [], "jobs": [] } 192.168.87.149 | SUCCESS => {
"changed": true, "envs": [], "jobs": [] } [root@linux0 ~]
Ansible安装rpm包/管理服务
- ansible testhost -m yum -a “name=httpd”
- 在name后面还可以加上state=installed/removed
- ansible testhost -m service -a “name=httpd state=started enabled=yes”
- 这里的name是centos系统里的服务名,可以通过chkconfig --list查到。
- Ansible文档的使用
ansible-doc -l 列出所有的模块
ansible-doc cron 查看指定模块的文档
[root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "msg": "", "rc": 0, "results": [ "已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-90.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package 架构 版本 源 大小\n================================================================================\n正在删除:\n httpd x86_64 2.4.6-90.el7.centos @base 9.4 M\n\n事务概要\n================================================================================\n移除 1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n 正在删除 : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n 验证中 : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n\n删除:\n httpd.x86_64 0:2.4.6-90.el7.centos \n\n完毕!\n" ] } [root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-90.el7.centos base 2.7 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n Verifying : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n\nInstalled:\n httpd.x86_64 0:2.4.6-90.el7.centos \n\nComplete!\n" ] } [root@linux0 ~] linux1 | SUCCESS => {
"changed": true, "enabled": true, "name": "httpd", "state": "started", [root@linux0 ~] linux1 | SUCCESS | rc=0 >> ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Active: active (running) since 一 2019-12-30 16:04:04 CST; 1min 30s ago Docs: man:httpd(8) man:apachectl(8) Main PID: 68555 (httpd) Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec" CGroup: /system.slice/httpd.service ├─68555 /usr/sbin/httpd -DFOREGROUND ├─68598 /usr/sbin/httpd -DFOREGROUND ├─68599 /usr/sbin/httpd -DFOREGROUND ├─68600 /usr/sbin/httpd -DFOREGROUND ├─68601 /usr/sbin/httpd -DFOREGROUND └─68602 /usr/sbin/httpd -DFOREGROUND 12月 30 16:03:44 linux1 systemd[1]: Starting The Apache HTTP Server... 12月 30 16:03:54 linux1 httpd[68555]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::50a5:f454:5189:9942. Set the 'ServerName' directive globally to suppress this message 12月 30 16:04:04 linux1 systemd[1]: Started The Apache HTTP Server. [root@linux0 ~] linux1 | FAILED! => {
"changed": false, "msg": "value of state must be one of: started,stopped,restarted,reloaded, got: stauts" }