文章目录
实验环境
- 三台全新的虚拟机rhel7.3 防火墙和iptables为stop并且disabled。
主机 | IP |
---|---|
server1(主控端) | 172.25.11.1 |
server2(节点) | 172.25.11.2 |
server3(节点) | 172.25.11.3 |
注意:三台主机需要同时做好本地解析。
实验过程
ansible的配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/ 存放角色的目录
环境部署
- server1安装ansible,还需要解决的依赖性。
[root@server1 ansible]# yum install -y ansible-2.7.8-1.el7.noarch.rpm python-keyczar-0.71c-2.el7.noarch.rpm python-httplib2-0.9.2-0.1.el7.noarch.rpm sshpass-1.06-1.el7.x86_64.rpm python2-jmespath-0.9.0-1.el7.noarch.rpm python2-crypto-2.6.1-13.el7.x86_64.rpm python-paramiko-2.1.1-0.9.el7.noarch.rpm libtomcrypt-1.17-25.el7.x86_64.rpm libtommath-0.42.0-5.el7.x86_64.rpm #除了安装ansible之外,还需要解决的依赖性如下
- 查看安装的ansible版本。
[root@server1 ansible]# ansible --version
ansible 2.7.8
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, Aug 2 2016, 04:20:16) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
- 查看ansible安装后在系统中生成的文件及目录。
[root@server1 ansible]# cd /etc/ansible/
[root@server1 ansible]# ls
ansible.cfg hosts roles
其中:
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/ 存放角色的目录
- 给server1新建使用ansible的普通用户devops,在devops用户的家目录下新建目录ansible,新建并编辑配置文件ansible.cfg (按照
/etc/ansible/ansible.cfg
文件)。
[root@server1 ansible]# useradd devops
[root@server1 ~]# su - devops
[devops@server1 ~]$ mkdir ansible
[devops@server1 ~]$ ll /etc/ansible/ansible.cfg
-rw-r--r-- 1 root root 20277 Feb 22 07:04 /etc/ansible/ansible.cfg
[devops@server1 ~]$ pwd
/home/devops
[devops@server1 ~]$ cd ansible/
[devops@server1 ansible]$ ls
[devops@server1 ansible]$ vim ansible.cfg #编辑ansible的主配置文件
[devops@server1 ansible]$ cat ansible.cfg
[defaults]
inventory = ./inventory #当前目录下的inventory文件
- 新建上面指定的inventory文件,Inventory是Ansible管理主机信息的配置文件,相当于系统HOSTS文件的功能,默认存放在/etc/ansible/hosts。
[devops@server1 ansible]$ vim inventory #设置ansible主机和组,可以为ip也可以为主机名(做好解析)
[devops@server1 ansible]$ cat inventory
[test] #分组 test组 server2
172.25.11.2
[prod] #生产环境组 server3
172.25.11.3
注意:当端口号不是默认22端口时,可明确的表示为:
server2:2222
server2 ansible_port=2222 ansible_host=172.25.0.2
- inventory文件配置详解:
定义主机和组
# 中括号表示一个组,也可以表示一个范围
[webserver]
www[1:10].example.com
db-[a:f].example.com
定义主机变量
在playbook中使用时对主机进行个性化定制
[webserver]
web1 http_port=8080 maxRequestsPerChild=1024
定义组变量
[webserver]
server2
server3
[webserver:vars]
ntp_server=time1.aliyun.com
webserver组中的所有主机ntp_server值为time1.aliyun.com
组与组之间可以相互调用,并且可以向组中的主机指定变量。不过,这些变量只能在Ansible-playbook中使用,而Ansible不支持。
在 inventory 主文件中保存所有的变量并不是最佳的方式.还可以保存在独立的文件中:
这些独立文件的格式为 YAML
/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
当变量变得太多时,分文件定义变量更方便进行管理和组织
/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settings
- 在server2和server3新建用户devops并修改密码:
[root@server2 ~]# useradd devops
[root@server2 ~]# passwd devops
- 设置server2和server3对server1免密登陆。
[devops@server1 ansible]$ ssh-keygen
[devops@server1 ansible]$ ssh-copy-id server2: #server2新建的普通用户devops的密码
[devops@server1 ansible]$ ssh-copy-id server3: #免密是以普通用户的身份
测试ansible
- 查看所有节点。
[devops@server1 ansible]$ ansible all --list-hosts
- 测试所有节点是否可以ping通。
[devops@server1 ansible]$ ansible all -m ping #-m:模块名 -u 以什么用户ssh连接 -b 切换
注意,ping这里常用的命令以及说明:
ansible all -m ping -u bruce #以bruce用户执行ping存活检测
ansible all -m ping -u bruce -b #以bruce sudo至root执行ping存活检测
ansible all -m ping -u bruce -b --become-user batman #以bruce sudo至batman用户执行ping存活检测
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命令使用场景:
- 非固化需求
- 临时一次性操作
- 二次开发接口调用
ansible-doc -l #显示所有可用模块
ansible-doc yum #获取yum模块帮助
ansible server2 -m setup ##查看指定主机server2上的facts变量信息
ansible all -m setup ##查看指定的所有主机上的facts变量信息
ansible '*' -m setup ##同上
ansible-doc -l | wc -l ##列出有多少个可用的模块
ansible-doc user ##查看user模块的帮助文档,按q退出。也可以在最后一行输入/passwd,来过滤与passwd有关的内容
ansible test -a 'df -h' ##在test组执行df -h命令
Ad-hoc使用场景
- Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook,在学习了 playbooks 之后,你才能体会到 Ansible 真正的强大之处在哪里。
- ad-hoc更注重于解决一些简单或者平时工作中临时遇到的任务,相当于Linux系统命令行下的Shell命令,后者更适合于解决复杂或需固化下来的任务,相当于Linux系统的Shell Scripts。
- 使用场景:
关闭所有不必要的服务器
临时更新Apache或Nginx的配置文件
ansible命令执行流程
Ansible的并发特性
- Ansible和Ansible-playbook默认会fork 5个线程并发执行命令,如果同时操作的主机数比较多的话,可以调整到一个更大的值。
- Ansible为我们提供了便捷的选项,-f指定线程数。
ansible webserver -m ping -f 3 #ansible有许多模块,默认是 command,也就是命令模块,我们可以通过 -m 选项来指定不同的模块。
Ansible与正则表达式
- 匹配所有主机,all或*号功能相同。
ansible all –m ping
ansible "*" -m ping
ansible 172.25.0.* -m ping
- 对多台主机或多个组同时执行,相互之间用冒号分隔即可。
ansible "web1:web2" -m ping
- 在webserver组但不在database组的主机,用感叹号表示
ansible 'webservers:!database' -m ping
- 在webserver组和database组中同时存在的主机,用&符号表示
ansible "webservers:&database" -m ping
- 模糊匹配
*.example.com
www*.com:database
- 举例:
[devops@server1 ansible]$ ansible 'test:!prod' -m ping #在test,不在prod
[devops@server1 ansible]$ ansible 'test:&prod' -m ping #交集
=[devops@server1 ansible]$ ansible '&test:prod' -m ping
=
[devops@server1 ansible]$ ansible webserver -m ping
[devops@server1 ansible]$ vim inventory
[test]
172.25.11.2
[prod]
172.25.11.3
[webserver:children] 变量
test
prod
常用模块
command模块(默认模块)
- 一般来说如果-m后面没有模块则默认使用command模块。
ping模块
[devops@server1 ansible]$ ansible all -m ping -u devops
[devops@server1 ansible]$ ansible all -m ping -u devops -b 报错
copy模块
ansible webservers -m copy -a "src=/etc/hosts dest=/tmp/hosts"
举例:
[devops@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/tmp/passwd" #执行成功,因为devops用户对tmp目录有权限
- 查看是否将本机文件复制到server2上。
[devops@server1 ansible]$ ansible test -a "ls /tmp" #默认-m 是指command模块,可以看到passwd文件
file模块
ansible webservers -m file -a "dest=/tmp/hosts mode=600 owner=root group=root" #修改文件权限和属性
ansible webservers -m file -a "dest=/tmp/dir1/dir2 mode=755 owner=root group=root state=directory" #递归创建
ansible webservers -m file -a "dest=/tmp/dir1/dir2 state=absent"
举例:
[devops@server1 ansible]$ ansible test -a "rm /tmp/passwd" #删除 有警告,但是删除成功
[devops@server1 ansible]$ ansible test -a "ls /tmp"
[devops@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/mnt/passwd" #报错 因为此用户对/mnt没权限
- 在server2和3给用户devops授权,保存退出时如果显示权力不够,则加wq!强制保存即可。
[root@server2 ~]# vim /etc/sudoers
92 devops ALL=(ALL) NOPASSWD: ALL
[devops@server1 ansible]$ ansible test -m copy -a "src=/etc/passwd dest=/mnt/passwd" -b #一定要加-b,否则会报错。
- 当然如果不愿意加-b去特别指定的话,我们也可以修改主配置文件,给予sudo所需要的权限。
[devops@server1 ansible]$ vim ansible.cfg
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
就相当于-b的选项,普通用户执行指令的时候加了sudo
yum模块
ansible webservers -m yum -a "name=httpd state=present"
ansible server3 -m yum -a "name=http://172.25.0.250/rhel7.3/x86_64/dvd/Packages/vsftpd-3.0.2-21.el7.x86_64.rpm state=present" #在线安装
ansible server3 -m yum -a "name=/mnt/vsftpd-3.0.2-21.el7.x86_64.rpm state=present" #本地安装
ansible server3 -m yum -a "name=httpd state=absent" #卸载软件
举例:
[devops@server1 ansible]$ ansible test -m yum -a "name=httpd state=present" #安装服务httpd
server2:ps ax
[root@server2 mnt]# rpm -q httpd
httpd-2.4.6-45.el7.x86_64
或者在server1:
[devops@server1 ansible]$ ansible test -a "rpm -q httpd"
=[devops@server1 ansible]$ ansible test -m shell -a "rpm -q httpd"
shell 和command的区别:shell可以解析脚本
[devops@server1 ansible]$ ansible test -m setup采集对端主机所有信息 保留字
卸载服务httpd:
[devops@server1 ansible]$ ansible test -m yum -a "name=httpd state=absent"
[root@server2 mnt]# rpm -q httpd
package httpd is not installed
[devops@server1 ansible]$ ansible-doc -l #查看所有模块
[devops@server1 ansible]$ ansible-doc copy #查看指定模块,底下的相当于playbooks,有example
[devops@server1 ansible]$ ansible-doc yum
service模块
ansible webservers -m service -a "name=httpd state=started"
ansible webservers -m service -a "name=httpd state=restarted"
ansible webservers -m service -a "name=httpd state=stopped"
举例:
[devops@server1 ansible]$ ansible test -m yum -a "name=httpd state=present" #先安装
[devops@server1 ansible]$ ansible test -m service -a "name=httpd state=started" #开启服务
server2 :ps ax
[devops@server1 ansible]$ ansible test -m service -a "name=httpd state=stopped" #关闭服务
server2: ps ax
user模块
ansible all -m user -a "name=wxh password=<加密密码>"
ansible all -m user -a "name=wxh state=absent remove=yes"
ansibledb -m user -a "name=wxh shell=/bin/bash groups=users,wheel append=yes state=present"
举例:
[devops@server1 ansible]$ ansible test -m user -a "name=zyw password=westos"
server2:[root@server2 mnt]# cat /etc/passwd #此时是明文
[root@server2 mnt]# cat /etc/shadow
zyw:westos:18118:0:99999:7:::
mysql模块
ansible server3 -m mysql_user -a "name=wxh password=testpass priv=*.*:select host='%' state=present"
远程主机需要安装MySQL-python
举例:
[devops@server1 ansible]$ ansible test -m yum -a "name=mariadb-server state=present"
[root@server2 mnt]# yum search mysql
[devops@server1 ansible]$ ansible test -m yum -a "name=MySQL-python.x86_64 state=present"
[devops@server1 ansible]$ ansible-doc mysql_user
[devops@server1 ansible]$ ansible test -m service -a "name=mariadb state=started"
[devops@server1 ansible]$ ansible test -m mysql_user -a "name=zyw password=westos priv=*.*:select host='%' state=present"
[root@foundation11 ~]# mysql -h 172.25.11.2 -u zyw -p #真机登陆,发现有select的权限
MariaDB [(none)]> show databases;
[root@server2 mnt]# mysql
MariaDB [(none)]> select * from mysql.user;
[devops@server1 ansible]$ ansible test -m user -a "name=zyw password={{ 'westos'|password_hash('sha512') }}" #新建用户 使用hash加密
[root@server2 mnt]# cat /etc/shadow #看到加密了,分为3部分
[devops@server1 ansible]$ ansible test -m user -a "name=zyw password={{ 'westos'|password_hash('sha512','mysalt') }}"
[root@server2 mnt]# cat /etc/shadow
zyw:$6$mysalt$IJHBKr9BhB4ng5A5qfK6X00/hfAXWqzQKI894frhzkTglZiA7kZiLwggZMLnbzQ6O7uIbIHzJd5f3RNZcqBcm/:18118:0:99999:7:::
firewalld模块
- 首先,开启防火墙。
[devops@server1 ansible]$ ansible test -m service -a "name=firewalld state=started enabled=true"
- 测试:
[devops@server1 ansible]$ ansible test -m service -a "name=httpd state=started"
[devops@server1 ansible]$ ansible test -m copy -a 'content="hello ansible\n" dest=/var/www/html/index.html'
[devops@server1 ansible]$ curl server2
curl: (7) Failed connect to server2:80; No route to host
- 把httpd服务加入防火墙的白名单。
[devops@server1 ansible]$ ansible test -m firewalld -a "service=http state=enabled permanent=yes immediate=yes"
- 再次测试
[devops@server1 ansible]$ curl server2
hello ansible
- 关闭防火墙并查看状态。
[devops@server1 ansible]$ ansible test -m service -a "name=firewalld state=stopped enabled=false"
[devops@server1 ansible]$ ansible test -a 'systemctl status firewalld'
另外,需要注意的有:
[devops@server1 ansible]$ ansible-playbook --help
##inventory文件有多个 -C 检查
[devops@server1 ansible]$ vim inventory
加入localhost
[devops@server1 ansible]$ ansible ungrouped -m ping
ungrouped 没有在所定义的组里的 除在组内的所有的都属于default
[root@server1 ansible]# vim ansible.cfg
如果用本机root连远程dep,则配置文件中107行得加到inventory文件中
107 #remote_user = root #因为不能用超户连远程
root用户的shell: ssh devops@server5
等于devops用户的shell :直接ssh server5
不可逆 下载的时候会安装依赖性 而卸载的时候就只卸载你要卸载的包
安装脚本 scripts 才是对系统影响最大的(有可能在卸载的时候删根)
[root@server2 mnt]# rpm -q --scripts httpd #查看安装脚本