当下有许多的运维自动化工具(配置管理 ),例如:Chef、Ansible、SaltStack、Puppet、Fabric 等。
Ansible 一种集成 IT 系统的配置管理、应用部署、执行特定任务的开源平台,是 AnsibleWorks 公司名下的项目,该公司由 Cobbler 及 Func 的作者于 2012 年创建成立。
Ansible 基于 Python 语言实现,由 Paramiko 和 PyYAML 两个关键模块构建。
Ansible 特点:
部署简单,只需在主控端部署 Ansible 环境,被控端无需做任何操作。
默认使用 SSH(Secure Shell)协议对设备进行管理。
主从集中化管理。
配置简单、功能强大、扩展性强。
支持 API 及自定义模块,可通过 Python 轻松扩展。
通过 Playbooks 来定制强大的配置、状态管理。
对云计算平台、大数据都有很好的支持。
提供一个功能强大、操作性强的 Web 管理界面和 REST API 接口 —- AWX 平台。
Ansible 与 SaltStack的区别:
最大的区别是 Ansible 无需在被监控主机部署任何客户端代理,默认通过 SSH 通道进行远程命令执行或下发配置。
相同点是都具备功能强大、灵活的系统管理、状态配置,都使用 YAML 格式来描述配置,两者都提供丰富的模板及
API,对云计算平台、大数据都有很好的支持。
实验环境:
主机 | 服务 |
---|---|
server1 | ansible的服务端 |
server2 | ansible的客户端 |
server3 | ansible的客户端 |
补充知识:
-m:要执行的模块,默认为command -a:指定模块的参数 -u:ssh连接的用户名,默认用root,ansible.cfg中可以配置 -b,--become:变成那个用户身份,不提示密码 -k:提示输入ssh登录密码,当使用密码验证的时候用 -s:sudo运行 -U:sudo到哪个用户,默认为root -K:提示输入sudo密码,当不是NOPASSWD模式时使用 -C:只是测试一下会改变什么内容,不会真正去执行 -c:连接类型(default=smart) -f:fork多少进程并发处理,默认为5个 -i:指定hosts文件路径,默认default=/etc/ansible/hosts -I:指定pattern,对已匹配的主机中再过滤一次 -list-host:只打印有哪些主机会执行这个命令,不会实际执行 -M:要执行的模块路径,默认为/usr/share/ansible -o:压缩输出,摘要输出 --private-key:私钥路径 -T:ssh连接超时时间,默认是10秒 -t:日志输出到该目录,日志文件名以主机命名 -v:显示详细日志
ansible server1 -m setup #产看指定主机server1上的facts变量信息 ansible * -msetup #查看指定的所有主机上的facts变量信息
ansible-doc -l #列出有哪些可用的模块,按q退出 ansible-doc -l | wc -l # 列出有多少个可用的模块 ansible-doc -l | grep user # 列出与user有关的模块 ansible-doc -user #查看user模块的帮助文档,按q退出。也可以在最后一行输入/passwd,来过滤与passwd有关的内容
前提:
为了实验环境纯净,我们创建几个新的虚拟机(我是将原本的虚拟机覆盖):
实验过程如下所示:
第一步:部署ansible的服务端
server1
下载ansible的相关rpm包及其依赖包,并进行安装
[root@server1 ansible]# yum install -y ansible-2.7.8-1.el7.noarch.rpm #我们会看到需要许多的依赖包
[root@server1 ansible]# yum install -y *
server1建立devops用户
server2/3建立devops用户并设置密码
[devopes@server1 ~]$ mkdir ansible
[devopes@server1 ~]$ ll /etc/ansible/ansible.cfg
-rw-r--r-- 1 root root 20277 Feb 22 07:04 /etc/ansible/ansible.cfg
[devopes@server1 ~]$ ls
ansible
[devopes@server1 ~]$ cd ansible/
[devopes@server4 ansible]$ ls
[devopes@server4 ansible]$ vim ansible.cfg #编写ansible的配置文件,必须以.cfg结尾
[defaults]
inventory = ./inventory
注意:Ansible将可管理的主机信息集合成为Inventory,Inventory的管理便是服务器的管理。默认存放在 /etc/ansible/hosts
hosts文件的位置的三种指定方式:
我们这里选择自己编写ansible的配置文件并选择第三种方式指定hosts文件的位置。
编写inventory文件
[devopes@server1 ansible]$ vim inventory
[devopes@server1 ansible]$ cat inventory
[test]
172.25.27. 2
[prod]
172.25.27.3
补充内容:
hosts文件的编写是很灵活的,有很多中写法,我这里列举4种方法:
<1>一个web组,组中有两个主机,分别的server1和server2
[web] server1 server2
<2>一个web组,组中有很多主机,主机名只要是以server开头的即可
[web] server*
<3>一个web组,组中有100个主机,主机名是server1-server100
[web] server[1:100]
<4>两个组,一个web组,一个db组。web组中的主机为server1,db组中的主机为server2。
[web] server1 [db] server2
第二步:设置ssh免密登录
[root@server1 ansible]# ssh-keygen #一路敲回车
[root@server1 ansible]# ssh-copy-id server1 #也可以写ip
[root@server1 ansible]# ssh-copy-id server2
第三步:测试
简单的ansible的使用
[root@server1 ansible]# ansible all -m ping
#all表示操作inventory文件中指定的所有主机,-m表示指定模块,ping表示指定的模块是ping模块
[root@server1 ansible]#
我们用-u去指定用户(这里的用户指的都是远程主机的用户)去ping的时候,只能指定普通用户,不能指定超级用户(因为没有权限,也就是没有root用户的“钥匙“),如下所示:
[devopes@server1 ansible]$ ansible all -m ping -u devopes
[devopes@server1 ansible]$ ansible all -m ping -u root
-b表示切换用户,自动由devops用户转为root用户(失败,没有权限,这个问题后面会解决~)
[devopes@server1 ansible]$ ansible all -m ping -u devopes -b
第四步:各个模块的使用
copy模块
[devopes@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/tmp/passwd "
#-m指定copy模块,-a表示要执行的动作,src指的目的文件,dest指的是下载位置
[devopes@server1 ansible]$ ansible test -a "ls /tmp" #查看
[devopes@server1 ansible]$ ansible test -a "rm /tmp/passwd" #有警告但是可以成功删除
[devopes@server1 ansible]$ ansible test -a "ls /tmp" #查看
但是我们发现,我们可以将目的文件放到下载目录/tmp下,但是不可以放到下载目录/mnt下面,因为没有对/mnt可写的权利,如下所示:
为了解决以上问题,我们需要在server2/3上对devops进行授权(让其权限与root相同):
[root@server2 ~]# vim /etc/sudoers
92行 devopes ALL=(ALL) NOPASSWD: ALL
将这个文件直接复制给server3
此时在去进行刚才那些权限不够被拒绝的操作,成功,如下所示:
[devopes@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/mnt/passwd" -b #使用-b切换身份
[devopes@server1 ansible]$ ansible test -m copy -a "ls /mnt"
当你不想使用-b转换身份,想直接默认使用root身份,就需要进行以下操作:
[devopes@server1 ansible]$ vim ansible.cfg
[devopes@server1 ansible]$ cat ansible.cfg
[defaults]
inventory = ./inventory
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[devopes@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/mnt/passwd" #此时不需要转化身份
yum模块
state的状态:
使用yum模块给test组里面的主机安装httpd包
[devopes@server1 ansible]$ ansible test -m yum -a "name=httpd state=present"
[devopes@server1 ansible]$ ansible test -a "rpm -q httpd"
同样,在server2可以看到httpd的安装包
卸载包:
[devopes@server1 ansible]$ ansible test -m yum -a "name=httpd state=absent"
在server2端查看:
service模块:
state的状态:
开启服务
[devopes@server1 ansible]$ ansible test -m service -a "name=httpd state=started"
在server2查看状态
关闭服务
[devopes@server1 ansible]$ ansible test -m service -a "name=httpd state=stopped"
在server2查看状态
user模块
创建用户:
[devopes@server1 ansible]$ ansible test -m user -a "name=wxh password=westos"
在server2查看:
可以使用 cat /etc/shadow | grep wxh
查看,发现密码是明文的,不安全。
删除用户:
[devopes@server1 ansible]$ ansible test -m user -a "name=wxh state=absentremove=yes "
此时没有这用户
我们可以使用以下这种方式来让配置文件里面的密码变为加密的
[devopes@server1 ansible]$ ansible test -m user -a "name=wxh password={{ 'westos '|password_hash('sha512') }} "
#采用sha512加密算法
第五步:综合使用模块配置数据库(ansible含有数据库用户模块mysql_user)
安装数据库
[devopes@server1 ansible]$ ansible test -m yum -a "name=mariadb-server state=present"
[devopes@server1 ansible]$ ansible test -m yum -a "name=MySQL-python.x86_64 state=present"
查看安装包:
开启数据库服务:
[devopes@server1 ansible]$ ansible test -m service -a "name=mariadb state=started"
建立数据库的授权用户:
mysql_user模块
[devopes@server1 ansible]$ ansible test -m mysql_user -a "name=cmm password=westos priv=*.*:select host='%' state=present"
[devopes@server1 ansible]$ ansible test -m mysql_user -a "name=hlj password=westos priv=*.*:select host=localhost state=present"
mysql -u hlj -p
select * from mysql.user
查看数据库的用户表,可以查看到我们建立的用户
数据库的端口也开启了
补充:ansible与正则
<1>检测主机
[devopes@server1 ansible]$ cat inventory
[test]
172.25.27.2
[prod]
172.25.27.2
172.25.27.3
[devopes@server4 ansible]$ ansible 'test:!prod' -m ping
#找出在test组里面但是不在prod组里面的主机(这种情况要是一个主机在两个组里,这个主机不显示)
[devopes@server4 ansible]$ ansible 'test:&prod' -m ping
#找出既在test组又在prod组里面的所有主机
<2>创建webserver组,批量检测
[devopes@server1 ansible]$ ansible webserver -m ping