人工运维时代
运维人员早期需要维护众多的机器,因此需要执行很多重复的劳动,很多机器需要同时部署相同的服务或者是执行相同的命令,还得反复地登录不同的机器,执行重复的动作
自动化运维时代
早期运维人员会结合ssh免密登录,以及shell脚本来完成自动化的部署操作
系统管理员面临的问题主要是:配置管理系统、远程执行命令、批量安装服务,启停服务等等
后来也诞生了众多的自动化运维软件,比如 Ansible
自动化运维的好处
- 减少重复的操作,提高工作效率
- 减少了人为出错的可能性
- ansible支持数据化管理,数据化追源,找到问题的源头
Ansible介绍
ansible是一个同时管理多个远程主机的软件,必须是任意可以通过ssh登录的机器,因为ansible可以管理的机器,包括:
- 远程虚拟机
- 物理机
- 本机机器
ansible通过ssh协议实现了,管理节点(安装了ansible服务的机器)和被管理节点的通信。
只要是通过ssh协议登录的主机,就可以完成ansible自动化部署操作
- 批量文件分发
- 批量数据复制
- 批量数据修改、删除
- 批量自动化安装软件服务
- 批量服务启动、停止
- 脚本化,自动批量服务部署
ansible特点
- 安装部署简单
- 管理主机便捷、支持多台主机并行管理
- 无须安装被管理节点的客户端(no agent),且无需占用客户端的其他端口,仅仅使用ssh服务即可
- 不仅仅支持python,还支持其他语言的二次开发
- 不用root用户也可执行,降低系统权限
Ansible实践部署
- 准备好虚拟机
准备好3个Linux虚拟机,配置在同一个局域网内,然后设置好静态ip地址
childA 192.168.xxx.129 被管理机器
childB 192.168.xxx.130 被管理机器(配置好ssh服务,以及关闭防火墙等等)
master01 192.168.xxx.128 管理机器(安装了ansible的服务器)
- 先准备ansible管理机器
#选择yum自动化安装(前提:已经安装好了阿里云yum、epel源)
yum install epel-release
yum install ansible
#检查ansible软件安装情况,查询配置文件和可执行命令
rpm -ql ansible | grep -E '^/etc|^/usr/bin'
#检查ansible版本
ansible --version
- 再准备ansible被管理机器
yum install epel-release libselinux-python -y
Ansible管理方式
ansible管理主机的方式有2种
- 传统的输入ssh密码验证
- 密钥管理
配置好ansible的配置文件,添加被管理机器的ip地址,或者主机名
#主节点备份现有的配置文件
cp /etc/ansible/hosts /etc/ansible/hosts.ori
#添加ansible需要管理的机器地址(节点A和节点B的ip地址)
[root@192 ansible]# vim hosts
[root@192 ansible]# tail -3 /etc/ansible/hosts
[qiujie]
192.168.xxx.129
192.168.xxx.130
ssh密码认证方式管理机器
ansible是直接利用linux本地的ssh服务,以及一些远程的ssh操作,一般情况下客户端的ssh服务默认都是开启的,无须额外管理
步骤:
①在master01机器上,执行如下命令
#在主机器上,告诉其他被管理的机器,你要执行什么命令,以及用什么用户去执行
ansible qiujie -m command -a 'hostname' -k -u root
qiujie /etc/ansible/hosts 文件中定义的主机组,还可以写主机的ip地址,以及通配符
-m 指定功能模块,默认就是command模块
-a 告诉模块需要执行的参数
-k 询问密码验证
-u 指定运行的用户
运行命令之后报错了:
报错原因:
使用了密码方式登录,在主机Host Key检查激活情况下,sshpass不支持该用法,得在master01机器的 ~/.ssh/known_hosts 文件中,添加客户端机器的指纹密钥
②手动ssh登录,对主机进行连接,即可使用ansible命令操作了
ssh root@192.168.xxx.129
ssh root@192.168.xxx.130
连接之后,再查看 ~/.ssh/known_hosts 文件,发现
③此时可以在master01机器上,再次执行ansible命令
ansible qiujie -m command -a 'hostname' -k -u root
配置免密登录
每次执行ansible命令的时候,都需要输入ssh的认证密码,也就是root密码,如果不同的主机密码不一样,那你还得输入多次才行。因此,我们可以配置如下的快捷登录方式
- ansible自带的密码认证参数
#可以在 /etc/ansible/hosts文件中,定义密码即可实现快速认证,远程管理主机
#修改后的内容如下:
[qiujie]
192.168.186.129 ansible_user=root ansible_ssh_pass=111111
192.168.186.130 ansible_user=root ansible_ssh_pass=111111
ansible_host 主机地址
ansible_port 端口,默认是22端口
ansible_user 认证的用户
ansible_ssh_pass 用户认证的密码
执行ansible命令(这次后面 -k -u root 那段参数就不用加了,它会自动执行配置文件中设置的账号和密码)
ansible qiujie -m command -a 'hostname'
- ssh密钥方式批量管理主机
这个方式比起hosts文件的密码参数来的更安全放心
#在master01机器上创建ssh密钥对
ssh-keygen -f ~/.ssh/id_rsa -P "" > /dev/null 2>&1
#检查公私钥文件
[root@master01 ~]# cd ~/.ssh/
[root@master01 .ssh]# ls
id_rsa id_rsa.pub known_hosts
编写公钥分发脚本
创建公钥分发脚本
mkdir /mysh
cd /mysh
touch ssh_key_send.sh
vim ssh_key_send.sh
脚本具体内容如下:
#!/bin/bash
rm -rf ~/.ssh/id_rsa*
ssh-keygen -f ~/.ssh/id_rsa -P "" > /dev/null 2>&1
SSH_Pass=123123
Key_Path=~/.ssh/id_rsa.pub
for ip in 129 130
do
sshpass -p$SSH_Pass ssh-copy-id -i $Key_Path "-o StrictHostKeyChecking=no" 192.168.xxx.$ip
done
#非交互式分发公钥命令需要用sshpass指定SSH密码,通过 -o StrictHostKeyChecking=no 跳过SSH确认连接信息
#执行
sh ssh_key_send.sh
#然后直接使用以下命令连接childA和childB节点,这样不需要输入密码
ssh -o ' StrictHostKeyChecking=no' '192.168.xxx.129'
ssh -o ' StrictHostKeyChecking=no' '192.168.xxx.130'
ansible模式
ansible实现批量化管理主机的模式,主要有2种
- ad-hoc模式:利用ansible的纯命令行实现批量管理
- playbook剧本模式:利用ansible的playbook剧本实现批量管理
ansible-doc命令
列出ansible支持的所有模块
ansible-doc -l
查看某个模块的具体用法参数
ansible-doc -s command
Ansible模块精讲
1、command模块
- 作用:在远程节点上执行一个命令
chdir 在执行命令之前,先通过cd进入该参数指定的目录
creates 在创建一个文件之前,判断该文件是否存在,如果存在了则跳过前面的动作,如果不存在,则执行前面的动作
free_form 该参数可以输入任何的系统命令,实现远程执行和管理
removes 定义一个文件是否存在,如果存在则执行前面的动作,如果不存在则跳过
command模块是ansible默认的基本模块,也可以省略不写,但是要注意如下的坑:
使用command模块,不得出现shell变量,比如$name,也不得出现特殊符号,比如 > < | ; & 这些符号command模块都不认识,如果你想用前面指定的变量、特殊符号,请使用shell模块
- command模块案例
获取所有被管理机器的负载信息
ansible qiujie -m command -a 'uptime'
让客户端机器,先切换到 /tmp 目录下,然后打印当前的工作目录
ansible qiujie -m command -a "pwd chdir=/tmp"
让客户端机器,判断 /qiujie 文件是否存在,如果不存在就打印当前路径,存在就跳过
ansible qiujie -m command -a "pwd creates=/qiujie"
让客户端机器,判断/aaa目录是否存在,如果存在就列出/aaa目录下的所有东西,不存在就跳过
ansible qiujie -m command -a "ls /aaa removes=/aaa"
warn参数,是否提供警告信息
#执行命令,并且不提示报错信息
ansible qiujie -m command -a "chmod 000 /etc/hosts warn=false"
shell模块
批量查询进程信息
ansible qiujie -m shell -a "ps -ef | grep vim"
批量在客户端机器,创建写入文件信息
ansible qiujie -m shell -a "echo 你真棒 > /tmp/heihei.txt"
批量执行脚本
#需要执行的这个脚本,必须在客户端机器上存在,否则会报错,这是shell模块的特点
#因为还有一个专门执行脚本的script模块
1.创建文件夹
2.创建sh脚本文件,还要写入脚本内容
3.赋予脚本可执行权限
4.执行脚本,并且忽略warning信息
ansible qiujie -m shell -a "mkdir -p /server/myscripts; echo 'hostname' > /server/myscripts/hostname.sh; chmod +x /server/myscripts/hostname.sh warn=false"
script 模块
功能:把 master01 管理机器上的脚本,远程地传输到被管理的节点上执行
比起shell模块,script模块功能更强大,在master01机器本地有一份脚本,就可以在所有被管理节点上去运行
1.在管理节点上创建脚本
[root@master01 /]# mkdir /myscripts
[root@master01 /]# cd /myscripts
[root@master01 myscripts]# echo -e "pwd\nhostname" > /myscripts/local_hostname.sh
[root@master01 myscripts]# cat /myscripts/local_hostname.sh
pwd
hostname
2.授权
[root@master01 myscripts]# chmod +x /myscripts/local_hostname.sh
远程地批量执行脚本,并且在客户端上不需要存在该脚本
myscripts]# ansible qiujie -m script -a "/myscripts/local_hostname.sh"
利用script模块,可以批量让所有被管理的机器执行脚本,且该脚本不需要在被管理的客户端上存在