Ansible
ansible自动化运维工具,python语言开发,基于ssh协议工作,实现了批量部署系统配置、批量程序部署、批量运行命令等功能。
Ansible是基于模块工作的,本身没有批量部署功能。真正具有部署功能的是ansible的模块:
(1)、connection plugins:连接插接,负责和被监控端实现通信;
(2)、host inventory:指定操作主机,是一个配置文件中定义监控的主机。
(3)、各种模块,核心模块:command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能。
(5)、playbook:剧本执行多个任务时,非必需可让节点一次性运行多个任务。
Ansible、优点
(1)、轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
(2)、批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
(3)、使用python编写,维护更简单,ruby语法过于复杂;
(4)、支持sudo。
ansible命令的执行过程
1.加载自己配置文件,默认在:/etc/ansible/ansible.cfg
2.加载对应模块
3.通过ansible将模块、命令,生成临时的python文件,并将改文件通过ssh传输给远程主机。
4.给文件执行权限:+x
5.执行并返回结果
6.删除文件
软件包链接:https://pan.baidu.com/s/19dvGkaLbrHTR59YkWpyZsg
提取码:cp0l
下面我来操作一下安装;
实验环境:centos7系统
192.168.100.102:ansible
192.168.100.103:docker1
192.168.100.104:docker2(共三台)
实验步骤:
安装ansible:
配置yum源:
[asd]
name=cengtos7
baseurl=file:///mnt
enabled=1
gpgcheck=0
配置ansible yum源(无网情况下):
cd /etc/yum.repos.d
vim ansible.repo
内容如下:
[ansible]
name=ansible
baseurl=file:///root/ansible
enable=1
gpgcheck=0
上传ansible软件包、解压到本地:tar xf ansible.tar.gz
注:解压必须到本地,因为ansible的yum源中我指定了/root/ansible为yum源、 如果不是,可根据自己情况更改。
使用yum安装:
[root@ansible ~]# yum -y install ansible
安装完成后,定义ansible主机清单:
[root@ansible ~]# vim /etc/ansible/hosts
在文件最下方写上被管理主机的组以及ip地址:
[dockers]
192.168.100.103 ansible_ssh=22 ansible_ssh_user=root ansible_ssh_pass=123456
192.168.100.104 ansible_ssh=22 ansible_ssh_user=root ansible_ssh_pass=123456
[docker1]
192.168.100.103 ansible_ssh=22 ansible_ssh_user=root ansible_ssh_pass=123456
[docker2]
192.168.100.104 ansible_ssh=22 ansible_ssh_user=root ansible_ssh_pass=123456
我这里定义了三个组:dockers、docker1、docker2. 分别对应不同的被管理端。
参数解释:
ansible_ssh_port:指定ssh端口
ansible_ssh_user:指定 ssh 用户
ansible_ssh_pass:指定 ssh 用户登录是认证密码(明文密码不安全)
ansible_sudo_pass:指明 sudo 时候的密码
测试连通用ping模块:
ansible all -m ping #all 主机清单中的所有主机
我们看到,连接失败了。这是因为ssh连接有错误。
解决:我们需要手动先连接一下被管理端:
[root@ansible ~]# ssh [email protected]
再次测试:ansible all -m ping
我们看到,刚刚我手动连接的docker1已经可以连接了,(现在我们把两个都弄好)。
做运维工作最怕的就是安全问题,现在我们的ansible主机定义清单中暴露了我们的被管理端密码, 所以需要做一个相应的简单优化——做免密登录。
免密登陆
生成秘钥:[root@ansible ~]# ssh-keygen
指定连接ip:
[root@ansible ~]# ssh-copy-id [email protected]
[root@ansible ~]# ssh-copy-id [email protected]
更改主机清单内容:[root@ansible ~]# vim /etc/ansible/hosts
再次测试连接:[root@ansible ~]# ansible all -m ping
ok,现在我们的ansible主机就可以实时连接到我们的被管理端了。
安装完成!!
从上面配置我们可以发现我所有的步骤都是在ansible主机上面完成的。被管理端我们只需要知道他的ip与密码就可以了。 这也是ansible功能的强大
进入主配置文件禁用ssh秘钥主机检查:
[root@ansible ~]# vim /etc/ansible/ansible.cfg
这个的作用就是说,第一次连接新的主机的时候都要去一个一个的输入密码,如果被管理主机过多,这个步骤还是比较繁琐的。关闭秘钥检查就可以直接连了。
开启日志功能:[root@ansible ~]# vim /etc/ansible/ansible.cfg
日志里记录了ansible主机都管理了那些主机做了什么操作,但是ansible默认是关闭这个功能的,所以我们需要把它开启。
去掉注释就ok了
参数解释
语法:ansible [-m module name] [-a arge]
如:ansible -m command -a ‘date’
-m:指定某个模块,不写就是默认command模块。
-a:指定模块后端想要执行的命令。
-u:指定那个用户。
-K:指定后端所需密码。
–list:显示主机列表。
–version:查看版本
-v,-vv,-vvv 查看ansible执行命令过程;可以理解为 -v是1级、3级最大。如:
-k:ssh连解时的密码,为了试验效果我在开一台虚拟机:192.168.100.105 mysql(往主机清单里添加组-ip我就不演示了)如下图我们看到我去连接mysql组是连不上的,因为ssh并不知道mysql组里的主机密码。所以加-k
模拟实战:我用在mysql组上创建一个用户:jxp 并设置密码。
[root@ansible ~]# ansible mysql -m shell -a 'useradd jxp' -k
添加密码:
ansible mysql -m shell -a 'echo 123456 | passwd --stdin jxp' -k
模块解释
刚刚上面也提到了ansible本身是不可以干这些事的,他是依靠各种模块来执行的。下面我就把ansible的常用模块,给大家介绍介绍。
刚刚我们用了ping模块,这是专门来测试主机的连通性的。和平时在系统中用的ping是一样的。
ansible的默认模块,可以执行各种命令,但不能识别符号。可以不指定-m去执行,。如我想要查看被管理端的主机时间可以用:
[root@ansible ~]# ansible docker1 -a 'date'
在command模块的基础上添加了支持各种符号。如我要查看/var下有多少个以.log结尾的文件:
用command模块是不支持的(他不识别* . | 等特殊符号):
用shell模块:
[root@ansible ~]# ansible docker1 -m shell -a 'ls /var/log/*.log'
使用script模块可以将本地的脚本文件放到被管理端执行。如:我随意编辑一个hostname脚本。
我要获取被管理端的所有主机名:
专门用来拷贝的模块,如:我想把本地/etc/passwd文件拷贝到远端mysql组主机上的 /目录下。
[root@ansible ~]# ansible mysql -m copy -a 'src=/etc/passwd dest=/'
[root@ansible ~]# ansible mysql -m shell -a 'ls / | grep passwd'
和copy模块刚好相反,可以把远端主机文件拷贝到本地。如再考回来:
[root@ansible ~]# ansible mysql -m fetch -a 'src=/passwd dest=/'
专门管理文件的模块。比如我去创建一个/abc文件。
[root@ansible ~]# ansible mysql -m shell -a 'touch /abc'
虽然说创建成功了,但是他告诉我们,和文件有关的操作,建议你使用file模块。
但是到file这语法又发生了一些变化:
[root@ansible ~]# ansible mysql -m file -a 'path=/ state=touch'
需要指定path位置和state动作。
模拟实战,要求:将被管理主机中的log日志抓取到自己本地。
操作:[root@ansible ~]# ansible all -m shell -a 'ls /var/log/*.log'
先找出所有主机中的log日志。
拷贝:
失败了,经过排查,是因为fetch模块不支持正表达式。
解决先给他打个包然后再拷贝:
[root@ansible ~]# ansible all -m shell -a 'tar Jcf log.tar.xz /var/log/*.log '
由于没有指定打包文件的路径, 我们得找一下:
[root@ansible ~]# ansible all -m shell -a 'find / -name log.tar.xz '
[root@ansible ~]# ansible all -m fetch -a 'src=/root/log.tar.xz dest=./'
查看:
ok,我们可以看到,mysql主机上的vmware-vmsvc.log中的文件内容。
模块就先介绍到这里。
下面我们来看一下ansible支持的正则表达式。。
我们先来看一下我的主机清单:
tail /etc/ansible/hosts
我们看到,我的主机组一共有4个,dockers、docker1…
假设我的每个组里都有不同的主机,而我又忘记了他的组名, 这个时候我们只需要记得他们的一些特点就好,而不用去查看主机清单。
比如我想在我mysql组中测试下是否可通信,但是我忘记了mysql组的名字,就可以这样:
[root@ansible ~]# ansible 'm*' -m ping
或者ping所有docker主机:
又或者,两个docker都ping
由于我这里主机比较少,这个正则表达式的效果不太明显。
命令参数:
星号(*)表示所有 等同于all
冒号(:)表示和、与。
冒号加&(:&)表示逻辑与,两个组里第一个有,第二个也有的。
冒号加叹号(:!)表示逻辑非,两个组里第一个有第二个没有的。
正则:
[root@ansible ~]# ansible '~(m|d).*' -m ping