Ansible
是一种自动化运维的工具。基于python
开发,由Ansible
提供框架,基于模块工作,由运行的模块提供批量部署的能力。Ansible
是一个模型驱动的配置管理器,支持多节点发布,远程任务执行。默认使用SSH
进行远程连接,无需在客户端上安装软件。
① 控制节点(control node)
:安装了Ansible的主机也称Ansible服务端、管理器。用于发布任务,执行命令。需安装Ansible程序和python及ansible所需依赖包。
② 受控节点(managed nodes)
:客户机,执行任务的主机,无需安装任何软件。
③ 清单(inventory)
: /etc/ansible/hosts
受控节点的IP地址列表(分组)。
④。模块(modules)
:每一个模块就像一个任务,可以让多个受控节点批量执行。如添加用户、上传文件、控制节点ping
受控节点等。
⑤ 任务(task)
:客户机上执行的操作,即adhoc单行命令执行一个任务 【单个任务】
⑥ 剧本(剧本)
:YAML标记语言编写的可重复执行的任务列表【多个任务】
⑦角色(role)
:用于对剧本进行个性化分层,结构化。
由于Ansible
是没有客户端的,也就是不需要在受控节点上安装任何软件,就可以运行Ansible
任务,减少了客户机上的开销成本。默认情况通过SSH
进行连接,也可以使用SFTP进行连接。
这里使用两台RHEL7.0
的主机进行测试,master
作为控制节点,slave
作为受控节点。IP
地址如下:
master:192.168.3.28
slave:192.168.3.29
受控节点无需配置,安装和配置都是在控制节点上进行。
①查看python版本
[root@slave ~]# which python2
/usr/bin/python2
[root@slave ~]# python2 --version
Python 2.7.5
②安装pip,要等几分钟,如果已经有了就不用安装了
# 由于python版本较低,故下载的setuptools和pip都不要最新版本,一般都不支持的。
#下载setuptools,并安装setuptools
[root@master ~]# wget https://pypi.python.org/packages/45/29/8814bf414e7cd1031e1a3c8a4169218376e284ea2553cc0822a6ea1c2d78/setuptools-36.6.0.zip#md5=74663b15117d9a2cc5295d76011e6fd1
[root@master ~]# unzip setuptools-36.6.0.zip
[root@master ~]# cd setuptools-36.6.0/
[root@master setuptools-36.6.0]# python setup.py install
#下载pip,并安装pip
[root@master ~]# wget https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9
[root@master ~]# tar xzvf pip-9.0.1.tar.gz
[root@master ~]# cd pip-9.0.1/
[root@master pip-9.0.1]# python setup.py install
# 查看是否安装成功,如果查不到版本信息,可看下安装过程是否有报错。
# 可以将可执行执行文件做一个软连接到/usr/bin/目录下
[root@master ~]# pip --version
pip 9.0.1 from /usr/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7)
[root@master ~]# easy_install --version
setuptools 36.6.0 from /usr/lib/python2.7/site-packages/setuptools-36.6.0-py2.7.egg (Python 2.7)
③安装ansible,查看ansible版本
# 安装基础环境
# 这里用的是aliyun的yum源
[root@master ~]# yum install -y gcc glibc-devel zlib-devel rpm-build openssl-deve
[root@master ~]# yum install -y python-devel
# 使用国内源安装ansible
[root@master ~]# pip install ansible -i https://pypi.douban.com/simple
# 查看ansible版本,可以看到已经安装成功了。
[root@master ~]# ansible --version
ansible 2.9.9
config file = None
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Apr 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
ssh
首次登录远程主机要密码,设置好免密登录后,ssh
就不用输入密码了。
# 生成密钥文件
[root@master ~]# ssh-keygen
# 指定远程机免密登录
[root@master ~]# ssh-copy-id 192.168.3.29
# 登录远程机检查效果
[root@master ~]# ssh 192.168.3.29
从版本信息那里可以看到,配置文件为空,所以需要手动创建配置文件。
# ansible配置文件内容
# mkdir /etc/ansible/
# vim /etc/ansible/ansible.cfg
[defaults]
# 受控节点IP地址清单
inventory = /etc/ansible/hosts
forks = 5
become = root
#SSH连接端口
remote_port =22
#关闭第一次连接客户端的提示
host_key_checking = False
#连接超时时间,单位s
timeount = 10
log_path = /var/log/ansible.log
# SSH服务的私钥文件位置
private_key_file = /root/.ssh/id_rsa
# 查看ansible的配置文件有没有被识别成功
[root@master ~]# ansible --version
ansible 2.9.9
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Apr 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
[root@master ~]# vim /etc/ansible/hosts
[webservers] # 组名,可以有多个组
192.168.3.29
格式:ansible 组名 -m 模块名 [-a "命令"]
# 可以看到网络是连通的
[root@master ~]# ansible webservers -m ping
192.168.3.29 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
到目前位置,ansible
终于是部署完成了!!!!
格式:ansible 组名 -m 模块名 [-a "命令"]
[root@master ~]# ansible webservers -m ping
192.168.3.29 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@master ~]# ansible webservers -m command -a "ip addr"
192.168.3.29 | CHANGED | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777728: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:21:ee:e4 brd ff:ff:ff:ff:ff:ff
inet 192.168.3.29/24 brd 192.168.3.255 scope global dynamic eno16777728
valid_lft 84772sec preferred_lft 84772sec
inet6 fe80::20c:29ff:fe21:eee4/64 scope link
valid_lft forever preferred_lft forever
向远程主机复制文件并设置权限
[root@master ~]# echo 'aaa' > a.txt
[root@master ~]# cat a.txt
aaa
[root@master ~]# ansible webservers -m copy -a "src=/root/a.txt dest=/root/ owner=root group=root mode=0755"
192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "972a1a11f19934401291cc99117ec614933374ce",
"dest": "/root/a.txt",
"gid": 0,
"group": "root",
"md5sum": "5c9597f3c8245907ea71a89d9d39d08e",
"mode": "0755",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 4,
"src": "/root/.ansible/tmp/ansible-tmp-1591449718.97-46269-20537465022397/source",
"state": "file",
"uid": 0
}
# 可以看到受控节点存在该文件
[root@slave ~]# cat a.txt
aaa
远程客户端执行脚本,客户端上必须存在脚本(复制过去),且拥有相应的执行权限。
[root@master ~]# vim /root/test.sh
[root@master ~]# cat test.sh
#!/bin/bash
echo "hahaha"
[root@master ~]# ansible webservers -m copy -a "src=/root/test.sh dest=/root/ owner=root group=root mode=0755"
192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "81aeb0f024e3797f3d055c897375f4e1ef69449a",
"dest": "/root/test.sh",
"gid": 0,
"group": "root",
"md5sum": "f3f6c2d01309ba092e651c712d88588b",
"mode": "0755",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 26,
"src": "/root/.ansible/tmp/ansible-tmp-1591449870.34-46356-151618107728045/source",
"state": "file",
"uid": 0
}
[root@master ~]# ansible webservers -m shell -a "/root/test.sh"
192.168.3.29 | CHANGED | rc=0 >>
hahaha
显示文件的详细信息
[root@master ~]# ansible webservers -m stat -a "path=/root/test.sh"
192.168.3.29 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"stat": {
"atime": 1591449917.7621584,
"attr_flags": "",
"attributes": [],
"block_size": 4096,
"blocks": 8,
"charset": "us-ascii",
"checksum": "81aeb0f024e3797f3d055c897375f4e1ef69449a",
"ctime": 1591449872.9058127,
"dev": 64768,
"device_type": 0,
"executable": true,
"exists": true,
"gid": 0,
"gr_name": "root",
"inode": 102779166,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mimetype": "text/x-shellscript",
"mode": "0755",
"mtime": 1591449871.895805,
"nlink": 1,
"path": "/root/test.sh",
"pw_name": "root",
"readable": true,
"rgrp": true,
"roth": true,
"rusr": true,
"size": 26,
"uid": 0,
"version": "18446744071784437495",
"wgrp": false,
"woth": false,
"writeable": true,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
}
}
# 批量安装httpd服务
# 使用CentOS-Base源
[root@master ~]# ansible webservers -m yum -a "name=httpd state=latest disable_gpg_check=yes enablerepo= CentOS-Base"
ERROR! this task 'yum' has extra params, which is only allowed in the following modules: shell, win_shell, include_vars, add_host, raw, include_role, meta, set_fact, include, import_tasks, script, import_role, include_tasks, group_by, command, win_command
# 报错了!!!报错信息没有这个yum模块
# 这是因为红帽系统的原因,要注册后才能开启yum
# 使用红帽账号进行注册
[root@master ~]# subscription-manager register --username=xxx --password=xxx --auto-attach
已经使用 ID 51887033-e184-4106-b39b-f4b21cf2395e 注册该系统
已安装的产品的当前状态
产品名称: Red Hat Enterprise Linux Server
状态: 未订阅的
# 安装最新版的httpd服务
[root@master ~]# ansible webservers -m yum -a "name=httpd state=latest"
192.168.3.29 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"msg": "yum lockfile is held by another process"
}
# 又报错,这次是提示"yum lockfile is held by another process"
# 从ansible的原理分析,控制节点是通过ssh服务控制受控节点执行任务的。yum有问题,那肯定是受控节点的yum出问题了。
# 要删除受控节点的/var/run/yum.pid文件
[root@master ~]# ansible all -m file -a 'name=/var/run/yum.pid state=absent'
192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/var/run/yum.pid",
"state": "absent"
}
# 再次安装httpd服务,可以看到已经安装成功了。虽然出现了一大堆的告警信息。这应该是我的yum的问题。
[root@master ~]# ansible webservers -m yum -a "name=httpd state=latest"192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd"
],
"updated": []
},
开启远程主机组webservers的http服务,并查看服务状态。
# 启动服务
[root@master ~]# ansible webservers -m service -a "name=httpd state=restarted"
# 查看服务状态
[root@master ~]# ansible webservers -a "systemctl status httpd"
# 停止服务
[root@master ~]# ansible webservers -m service -a "name=httpd state=stopped"
# 删除文件
# absent 删除
[root@master ~]# ansible all -m file -a 'name=/root/a.txt state=absent'
192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/root/a.txt",
"state": "absent"
}
#创建文件
# touch 创建
[root@master ~]# ansible all -m file -a 'name=/root/a.txt state=touch'
192.168.3.29 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/a.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
以上就是作为小白的我,摸索了一个礼拜的成果了!!!从一台啥都没有的RHEL7.0,一步一步部署出能批量控制多台主机的ansible!!!感兴趣的朋友可以留言一起交流!!!