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": "d2498e8c027056bce4504550d372d02a144ad2a5",
"dest": "/tmp/bucunzaifile",
"gid": 0,
"group": "root",
"md5sum": "9e8b0416c70cd4cbc058d85475545ee4",
"mode": "0644",
"owner": "root",
"size": 1062,
"src": "/root/.ansible/tmp/ansible-tmp-1577681221.99-76751054633404/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": "d2498e8c027056bce4504550d372d02a144ad2a5",
"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": "d2498e8c027056bce4504550d372d02a144ad2a5",
"dest": "/tmp/bucunzai/bucunzaifile",
"gid": 0,
"group": "root",
"md5sum": "9e8b0416c70cd4cbc058d85475545ee4",
"mode": "0644",
"owner": "root",
"size": 1062,
"src": "/root/.ansible/tmp/ansible-tmp-1577681488.34-51934515577145/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-1577685322.11-198777298584552/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"
}