Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。
部署简单,没有客户端,只需在主控端部署Ansible环境,被控端无需做任何操作;
模块化:调用特定的模块,完成特定任务
默认使用SSH协议对设备进行管理;
主从集中化管理;
通过Playbooks来定制强大的配置、状态管理;
具有幂等性:一个操作在一个主机上执行一遍和执行N遍的结果是一样的;
上图可以看到的内容的详细说明:
1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg 2. 加载自己对应的模块文件,如command 3. 通过ansible将模块或命令生成对应的临时py文件, 并将该文件传输至远程服务器的对应执行用户 $HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件 4. 给文件+x执行 5. 执行并返回结果 6. 删除临时py文件,sleep 0退出 执行状态: 绿色:执行成功并且不需要做改变的操作 黄色:执行成功并且对目标主机做变更 红色:执行失败
yum -y install epel-release
yum -y install ansible
格式:
ansible基于ssh连接-i (inventory)参数后指定的远程主机时,也可以写端口,用户,密码。
如:
ansible_ssh_port: 指定ssh端口 ansible_ssh_user:指定 ssh 用户 ansible_ssh_pass: 指定 ssh 用户登录是认证密码(明文密码不安全) ansible_sudo_pass: 指明 sudo 时候的密码。
[root@ansible ~]# cat /etc/ansible/hosts | tail -10
#192.168.150.140
192.168.150.146 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=201104
192.168.150.147 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=201104
[root@ansible ~]# ansible nginx-servers -m ping
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.146 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.150.147 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
command:在远程主机执行命令,默认模块,可忽略-m选项。此命令不支持 $VARNAME < > | ; & 等 需要用shell模块实现。
[root@ansible ~]# ansible nginx-servers -m command -a 'ls -l /root/'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.146 | CHANGED | rc=0 >>
总用量 2216
-rw-------. 1 root root 1612 9月 19 00:23 anaconda-ks.cfg
-rw-r--r-- 1 root root 237 10月 12 18:39 iptables
drwxr-xr-x 6 1000 1000 4096 2月 11 11:49 mwget_0.1.0.orig
-rw-r--r-- 1 root root 2252800 8月 18 2011 mwget_0.1.0.orig.tar
-rw-------. 1 root root 1577 9月 19 00:23 original-ks.cfg
-rw-r--r-- 1 root root 0 2月 11 13:51 Python-3.9.0.tar.xz.mg!
192.168.150.147 | CHANGED | rc=0 >>
总用量 12
-rw-------. 1 root root 1612 9月 19 00:23 anaconda-ks.cfg
-rw-r--r--. 1 root root 194 9月 19 02:11 flask-web.py
-rw-------. 1 root root 1577 9月 19 00:23 original-ks.cfg
drwxr-xr-x 5 root root 74 2月 13 10:08 student
Shell命令是通过/bin/sh进行执行的,command命令没有shell的环境变量,因此不 支持特殊符号或变量的操作。
Shell:和command相似,用shell执行命令 shell模块支持一些特殊符号,重定向符号、变量等的操作
[root@ansible ~]# ansible 192.168.150.147 -m shell -a "echo 'hello' > /root/hello.txt" [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
[root@ansible ~]# ansible 192.168.150.147 -m shell -a "cat /root/hello.txt"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
hello
script:在远程机器执行本地脚本
# 执行本地的文件,管控机的文件
[root@ansible shnodes]# ansible 192.168.150.147 -m script -a "/shnodes/hostname.sh"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.150.147 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.150.147 closed."
],
"stdout": "web02\r\n",
"stdout_lines": [
"web02"
]
}
# 判断被控 机上的文件是否存在,如果不存在,就执行,如果存在,就跳过
[root@ansible shnodes]# ansible 192.168.150.147 -m script -a "creates=/shnodes/hostname.sh /shnodes/hostname.sh"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.150.147 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.150.147 closed."
],
"stdout": "web02\r\n",
"stdout_lines": [
"web02"
]
}
[root@ansible shnodes]# ansible 192.168.150.147 -m script -a "creates=/shnodes/hostname.sh /shnodes/hostname.sh"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | SKIPPED
copy:从ansible服务器主控端复制文件到远程文件
src:源文件(指定拷贝文件的本地路径)
dest:指定目标路径
mode:设置权限
backup:备份源文件
content:代替src( 指定本机文件内容,生成目标主机文件 )
[root@ansible shnodes]# ansible 192.168.150.147 -m copy -a "src=/shnodes/check_info.sh dest=/root/check_info.sh"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "a01d6403071c03324e337d13c78bbf100b51121e",
"dest": "/root/check_info.sh",
"gid": 0,
"group": "root",
"md5sum": "243a07e14a34c96b67b3f08f72525103",
"mode": "0644",
"owner": "root",
"size": 32,
"src": "/root/.ansible/tmp/ansible-tmp-1678169016.12-1894-210559415440731/source",
"state": "file",
"uid": 0
}
[root@ansible shnodes]# ansible 192.168.150.147 -a 'ls -l /root/'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
总用量 20
-rw-------. 1 root root 1612 9月 19 00:23 anaconda-ks.cfg
-rw-r--r-- 1 root root 32 3月 7 14:03 check_info.sh
-rw-r--r--. 1 root root 194 9月 19 02:11 flask-web.py
-rw-r--r-- 1 root root 6 3月 7 13:40 hello.txt
-rw-------. 1 root root 1577 9月 19 00:23 original-ks.cfg
drwxr-xr-x 5 root root 74 2月 13 10:08 student
[root@ansible shnodes]# ansible 192.168.150.147 -m copy -a "content='hello' dest=/root/test.txt"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d",
"dest": "/root/test.txt",
"gid": 0,
"group": "root",
"md5sum": "5d41402abc4b2a76b9719d911017c592",
"mode": "0644",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1678169174.79-2000-266122844071777/source",
"state": "file",
"uid": 0
}
[root@ansible shnodes]# ansible 192.168.150.147 -a 'cat /root/test.txt'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
hello
fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再 提取文件
[root@ansible shnodes]# ansible 192.168.150.147 -m fetch -a "src=/root/hello.txt dest=/root/hello.txt"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"changed": true,
"checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"dest": "/root/hello.txt/192.168.150.147/root/hello.txt",
"md5sum": "b1946ac92492d2347c6235b4d2611184",
"remote_checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"remote_md5sum": null
}
总用量 4
-rw-------. 1 root root 1568 9月 11 09:22 anaconda-ks.cfg
drwxr-xr-x 3 root root 29 3月 7 14:15 hello.txt
File:设置文件属性
path: 要管理的文件路径 (强制添加) recurse: 递归,文件夹要用递归 src: 创建硬链接,软链接时,指定源目标,配合'state=link' 'state=hard' 设置软链接, 硬链接
state: 状态 absent 缺席,删除
[root@ansible ~]# ansible 192.168.150.147 -m file -a "path=/root/file.txt state=touch"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/file.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible 192.168.150.147 -a 'cat /root/file.txt'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
Archive:打包压缩,将远程主机目录打包 path: 指定路径 dest: 指定目标文件 format: 指定打包格式 owner: 指定所属者 mode: 设置权限
[root@ansible ~]# ansible 192.168.150.147 -m archive -a 'path=/shnodes/ dest=/shnodes/shnodes.tar.bz2 '
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"archived": [
"/shnodes/hostname.sh",
"/shnodes/shnodes.tar.bz2"
],
"arcroot": "/shnodes/",
"changed": true,
"dest": "/shnodes/shnodes.tar.bz2",
"expanded_exclude_paths": [],
"expanded_paths": [
"/shnodes/"
],
"gid": 0,
"group": "root",
"missing": [],
"mode": "0644",
"owner": "root",
"size": 169,
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible 192.168.150.147 -a 'ls -l /shnodes'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
总用量 8
-rw-r--r-- 1 root root 30 3月 7 13:49 hostname.sh
-rw-r--r-- 1 root root 169 3月 7 14:24 shnodes.tar.bz2
unarchive:解包解压缩,有两种用法: 1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes. 2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
[root@ansible ~]# ll
总用量 8
-rw-------. 1 root root 1568 9月 11 09:22 anaconda-ks.cfg
drwxr-xr-x 3 root root 29 3月 7 14:15 hello.txt
-rw-r--r-- 1 root root 191 3月 7 14:30 hello.txt.tar
[root@ansible ~]# ansible 192.168.150.147 -m unarchive -a 'src=/root/hello.txt.tar dest=/shnodes/ '
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/shnodes/",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/shnodes/",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1678170637.95-2424-226980750356851/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "0755",
"owner": "root",
"size": 65,
"src": "/root/.ansible/tmp/ansible-tmp-1678170637.95-2424-226980750356851/source",
"state": "directory",
"uid": 0
}
[root@ansible ~]# ansible 192.168.150.147 -a 'ls -l /shnodes'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
总用量 8
drwxr-xr-x 3 root root 29 3月 7 14:15 hello.txt
-rw-r--r-- 1 root root 30 3月 7 13:49 hostname.sh
-rw-r--r-- 1 root root 169 3月 7 14:24 shnodes.tar.bz2
cron模块主要用于添加、删除、更新操作系统的crontab任务计划
[root@ansible ~]# ansible 192.168.150.147 -m cron -a "minute=*/1 job='/usr/bin/date > /root/date.txt' name=date"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"date"
]
}
[root@ansible ~]# ansible 192.168.150.147 -a 'crontab -l'
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.150.147 | CHANGED | rc=0 >>
#Ansible: date
*/1 * * * * /usr/bin/date > /root/date.txt
Yum:管理包
#enablerepo启用某个源
#name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路 径
State定义软件包状态
-present:安装(installed也可以)
-absent:删除(removed)
-latest:安装最新的
ansible 192.168.150.147 -m yum -a 'list=httpd' 查看程序列表
ansible 192.168.150.147 -m yum -a 'name=httpd state=present' 安装
ansible 192.168.150.147 -m yum -a 'name=httpd state=absent' 删除
systemd模块用于控制远程主机的systemd服务,说白了,就是Linux下的systemd 命令。需要远程主机支持systemd。
ansible 192.168.150.147 -m systemd -a "name=httpd state=started" #启动服务 ansible 192.168.150.147 -m systemd -a "name=httpd state=stopped" #停止服务 ansible 192.168.150.147 -m systemd -a "name=httpd state=restarted" #重启服务 ansible 192.168.150.147 -m systemd -a "name=httpd state=reloaded"#重新加载
playbook 剧本是由一个或多个"play”组成的列表 play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好 的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook 中,即可以让它们联合起来,按事先编排的机制执行预定义的动作。用户通过 ansible命令直接调用yml语言写好的playbook,playbook由多条play组成,每条play 都有一个任务(task)相对应的操作,然后调用模块modules,应用在主机清单上,通过 ssh远程连接,从而控制远程主机或者网络设备。
Playbook 文件是采用YAML语言编写的
Hosts 执行的远程主机列表
Tasks 任务集
Variables 内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否 则不执行
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具 有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实 没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过 tags跳过此些代码片断
[root@ansible ansible]# cat check_nginx.yml
---
- hosts: test
remote_user: root
tasks:
# - name: copy nginx file
# copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d
# - name: yum clean all
# shell: yum clean all
# - name: yum makecache
# shell: yum makecache
# - name: install nginx
# yum: name=nginx state=present
# - name: copy file
# copy: src=/etc/nginx/conf.d/default.conf dest=/etc/nginx/conf.d/default.conf
# notify: restart nginx
# tags: config
# - name: start nginx
# systemd: name=nginx state=started