ansible自动化运维
人工运维时代
运维人员早期需要维护数量众多的机器,因此需要反复执行,执行重复的动作
自动化运维时代
早期运维人员会结合ssh 免密登录以及shell 脚本来完成自动化的部署操作
系统管理员面临的问题主要是,配置管理系统,远程执行命令,批量安装服务,启停服务等
后来也诞生了众多的开源软件,自动化运维软件
- fabric
- puppet
- saltsack
- chef
- Ansible
其中saltsack、Ansible是基于python编写
自动化运维的趋势
人肉运维,人力运维 > 自动化运维 > 数据化运维, 可视化运维 > AI智能运维 ,devops
自动化运维的好处
- 提高工作效率,减少重复性的劳动力操作
- 大大的减少了人为出错的可能性
- ansible支持数据化管理,数据化追源,找到问题的来源点
ansible介绍
ansible是一个同时管理多个远程主机的软件,必须是任意可以通过ssh登录的机器,因此ansible可以管理的机器如
- 远程虚拟机
- 物理机
- 本机机器
ansible通过ssh协议实现了,管理节点,被管理节点的通信
只能是通过ssh协议登录的主机,就可以完成ansible自动化部署操作
- 批量文件分发
- 批量数据复制
- 批量数据修改、删除
- 批量自动化安装软件服务
- 批量服务启停
- 脚本化、自动批量服务部署
ansible特点
ansible可以出色的完成各种任务配置管理,ansible在流程控制,资源部署等方面很强大,并且ansible无须安装客户端软件,管理简洁,使用 yaml 配置文件语法,功能强大,便于维护
ansible是基于 python语言开发的,主要由 python的两个ssh 处理模块,paramiko,以及PyYAML模块
- 安装部署简单
- 管理主机便捷,支持多台主机并行管理
- 无需安装被管理节点的客户端(no,agent),且无须占用客户端的其他端口,仅仅使用ssh服务即可
- 不仅仅支持 python,还支持其他语言的二次开发
- 不用root用户也可以执行,降低系统权限
Ansible实践部署
准备好虚拟机
#修改名字
[root@localhost ~]# hostnamectl set-hostname m01
#准备好3个Linux虚拟机
m01 192.168.1.10 管理机器(安装了ansible的服务器)
nfs01 192.168.1.20 被管理机器(配置好ssh,关闭防火墙等)
rsync01 192.168.1.30 被管理机器
先准备ansible管理机器
1、选择yum自动化安装,阿里云yum,epel源,提前配置好
[root@m01 ~]# yum install epel-release -y
[root@m01 ~]# yum install anasible libselinux-python -y
2、检查ansible安装,查询配置文件,可执行命令
[root@m01 ~]# rpm -ql ansible| grep -E '^etc|^/usr/bin'
/usr/bin/ansible
/usr/bin/ansible-2
/usr/bin/ansible-2.7
/usr/bin/ansible-config
/usr/bin/ansible-connection
/usr/bin/ansible-console
/usr/bin/ansible-console-2
/usr/bin/ansible-console-2.7
/usr/bin/ansible-doc
/usr/bin/ansible-doc-2
/usr/bin/ansible-doc-2.7
/usr/bin/ansible-galaxy
/usr/bin/ansible-galaxy-2
/usr/bin/ansible-galaxy-2.7
/usr/bin/ansible-inventory
/usr/bin/ansible-playbook
/usr/bin/ansible-playbook-2
/usr/bin/ansible-playbook-2.7
/usr/bin/ansible-pull
/usr/bin/ansible-pull-2
/usr/bin/ansible-pull-2.7
/usr/bin/ansible-vault
/usr/bin/ansible-vault-2
/usr/bin/ansible-vault-2.7
3、检查ansible版本
[root@m01 ~]# ansible --version
ansible 2.9.27
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, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
再准备ansible被管理机器
安装ansibles所需的系统模块
nfs01
rsync01
[root@nfs01 ~]# yum install epel-release -y
[root@rsync01 ~]# yum install epel-release -y
ansible管理方式
ansible批量管理主机的方式有两种
- 传统的输入ssh密码验证
- 密钥管理
配置好ansible的配置文件,添加被管理机器的ip地址,或者主机名
1、备份现有的配置文件
[root@m01 ~]# cp /etc/ansible/hosts{,.ori}
[root@m01 ~]# ls /etc/ansible/
ansible.cfg hosts hosts.ori roles
2、添加ansible需要管理的机器地址
[root@m01 ~]# vim /etc/ansible/hosts
[asong]
192.168.1.20
192.168.1.30
[root@m01 ~]# tail -3 /etc/ansible/hosts
[asong]
192.168.1.20
192.168.1.30
ssh密码认证方式管理机器
ansible是直接利用linux本地的ssh服务,以及一些远程的ssh操作,一般情况下客户端的ssh服务默认都是开启的,无须额外管理
1、在m01机器上执行如下命令
ansible 主机列表 -m command -a 'hostname' -k -u root
-m 指定功能模块,默认就是command模块
-a 告诉模块需要执行的参数
-k 询问密码验证
-u 指定运行的用户
在m01机器上,告诉其他被管理的机器,要执行什么命令,用什么用户去执行
[root@m01 ~]# ansible asong -m command -a 'hostname' -k -u root
SSH password:
192.168.1.30 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.
192.168.1.20 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.
[root@m01 ~]# vim ~/.ssh/known_hosts
2、如上操作,一般默认会有错误提升,需要执行以下操作,只需要手动ssh对主机进行一次连接,即可使用ansible命令操作
ssh root@192.168.1.20
ssh root@192.168.1.30
[root@m01 ~]# ssh root@192.168.1.20
The authenticity of host '192.168.1.20 (192.168.1.20)' can't be established.
ECDSA key fingerprint is SHA256:UQo0yhqYYNC0B7ynor8QxtW1pqqtXfGgMQofSM+5dEw.
ECDSA key fingerprint is MD5:ae:63:a9:2b:b4:85:2a:31:d9:30:a8:52:6a:49:ba:db.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.20' (ECDSA) to the list of known hosts.
root@192.168.1.20's password:
Last login: Tue Nov 29 18:14:38 2022 from 192.168.1.2
[root@nfs01 ~]# exit
登出
Connection to 192.168.1.20 closed.
[root@m01 ~]# cat ~/.ssh/known_hosts
192.168.1.10 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKxbf+tKhzZ+rE5469PSzrST7hVDknSIHHAld/FyTyastG0p6cKaP592s4ArrHb7theyBgYUJsH8QiahWHzK1Mw=
192.168.1.20 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBK3ZuKzPUyvl/qXNZt9VOpqYLVMQia2gYvQ2geogplHcRqiJCp1AhuVmFE+9qxx/NB7byNSioHrpc0xTtvrk74=
3、此时可以再次执行 ansible命令
[root@m01 ~]# ansible asong -m command -a "hostname" -k -u root
SSH password:
192.168.1.20 | CHANGED | rc=0 >>
nfs01
192.168.1.30 | CHANGED | rc=0 >>
rsync01
[root@m01 ~]# ansible asong -m command -a "ifconfig ens33" -k -u root
配置免密登录
ansible自带的密码认证参数
可以在 /etc/ansible/hosta文件中,定义好密码即可
参数
ansible_host 主机地址
ansible_port 端口,默认是22端口
ansible_user 认证的用户
ansible_ssh_pass 用户认证的密码
使用hosts文件的参数形式,来实现ssh认证
1、修改hosts文件,改为
[root@m01 ~]# vim /etc/ansible/hosts
[asong]
192.168.1.20 ansible_user=root ansible_ssh_pass=111111
192.168.1.30 ansible_user=root ansible_ssh_pass=111111
2、无密码登录
[root@m01 ~]# ansible asong -m command -a 'hostname'
192.168.1.30 | CHANGED | rc=0 >>
rsync01
192.168.1.20 | CHANGED | rc=0 >>
nfs01
ssh密钥方式批量管理主机
1、在m01机器上创建ssh密钥对
[root@m01 ~]# ssh-keygen -f ~/.ssh/id_rsa -P "" > /dev/null 2>&1
2、此时检查公私钥文件
[root@m01 ~]# cd ~/.ssh/
[root@m01 .ssh]# ls
id_rsa id_rsa.pub known_hosts
编写公钥
[root@m01 .ssh]# mkdir /mysh
[root@m01 .ssh]# cd /mysh/
[root@m01 mysh]# touch ssh_key_send.sh
[root@m01 mysh]# 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=123
Key_Path=~/.ssh/id_rsa.pub
for ip in 20 30
do
sshpass -p$SSH_Pass ssh-copy-id -i $Key_Path "-o StrictHostKeyChecking=no" 192.168.1.$ip
done
#非交换式分发公钥命令需要用sshpass指定SSH密码,通过 -o StrictHostKeyChecking=no 跳过SSH链接确认信息
[root@m01 mysh]# sh ssh_key_send.sh
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o ' StrictHostKeyChecking=no' '192.168.1.20'"
and check to make sure that only the key(s) you wanted were added.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o ' StrictHostKeyChecking=no' '192.168.1.30'"
and check to make sure that only the key(s) you wanted were added.
[root@m01 mysh]# ssh -o 'StrictHostKeyChecking=no' '192.168.1.20'
Last login: Tue Nov 29 19:53:52 2022 from 192.168.1.10
[root@nfs01 ~]#
此时无须输入密码即可登录
[root@m01 mysh]# ansible asong -m command -a "df -h"
192.168.1.30 | CHANGED | rc=0 >>
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.7M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.1G 15G 13% /
/dev/sda1 1014M 137M 878M 14% /boot
tmpfs 98M 0 98M 0% /run/user/0
192.168.1.20 | CHANGED | rc=0 >>
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.7M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.5G 16G 9% /
/dev/sda1 1014M 137M 878M 14% /boot
tmpfs 98M 0 98M 0% /run/user/0
[root@m01 mysh]# ansible asong -m command -a "uname -a"
192.168.1.20 | CHANGED | rc=0 >>
Linux nfs01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
192.168.1.30 | CHANGED | rc=0 >>
Linux rsync01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
总结
在生产环境中,ansible的连接方式,二选一即可,最好的是配置 ssh 公私钥免密登录
如果生产环境的要求更高,可以用普通用户去执行,在提权操作,sudo
ansible模式与命令
ansible实现批量主机管理 的模式,主要有两种
- 利用ansible的纯命令行实现的批量管理,ad-hoc模式 --------好比简单的shell命令管理
- 利用ansible的playbook剧本来实现批量管理,playbook剧本模式-----好比复杂的shell脚本管理
ad-hoc模式
ansible的ad-hoc模式是ansible的命令行形式
比如
- 临时批量查看被管理机器的内存情况,cpu负载情况,网络情况
- 比如临时的分发配置文件等
playbook模式
ansible的playbook模式是针对比较具体,且比较大的任务,就得提前写好剧本应用场景
- 一键部署rsync备份服务器
- 一键部署lnmp环境
ansible的ad-hoc命令解析
#准备好3个Linux虚拟机
m01 192.168.1.10 管理机器
nfs01 192.168.1.20 被管理机器
rsync01 192.168.1.30 被管理机器
让被管理机器返回命令行
[root@m01 mysh]# ansible asong -m command -a "hostname"
192.168.1.30 | CHANGED | rc=0 >>
rsync01
192.168.1.20 | CHANGED | rc=0 >>
nfs01
ad-hoc命令解释
- ansible----自带提供的命令操作
- asong----/etc/ansible/hosts文件中定义的主机组,还可以写主机ip,以及通配符 *
- -m command ansible 的指定模块的参数,以及指定了command模块
- -a 指定给command模块的什么参数,hostname,uname -f
ansible-doc命令
列出所有的ansible支持的模块
[root@m01 mysh]# ansible-doc -l
[root@m01 mysh]# ansible-doc -l | grep ^command
查看某个模块的具体用法参数
[root@m01 mysh]# ansible-doc -s command
ansible模块精讲
Ansible-doc -l
command模块
作用:在远程节点上执行一个命令
ansible-doc -s command 查看该模块支持的参数
chdir 在执行命令之前,先通过cd 进入该参数指定的目录
creates 在创建一个文件之前,判断该文件知否存在,存在跳过前面的东西,不存在执行前面的动作
free_form 该参数可以输入任何的系统命令,实现远程执行和管理
removes 定义一个文件是否存在,存在执行前面的动作,不存在则跳过动作
command模块是ansible的默认基本模块,也可以省略不屑,但要注意如下的坑
- 使用command模块,不得出现shell变量 $name ,也不得出现特殊符号 < > | ; & 这些符号command模块都不认识,如果你想用前面的变量,特殊符号,请使用shell模块,command就不适合了
command模块案例
获取所有被管理机器的负载信息
ansible asong -m command -a "uptime"
[root@m01 ~]# ansible asong -m command -a "uptime"
192.168.1.30 | CHANGED | rc=0 >>
22:04:53 up 3:50, 4 users, load average: 0.16, 0.05, 0.06
192.168.1.20 | CHANGED | rc=0 >>
22:05:23 up 3:51, 4 users, load average: 0.00, 0.01, 0.05
让客户端机器,先切换到/tmp目录下,然后在打印当前的工作目录
ansible asong -m command -a "pwd"
[root@m01 ~]# ansible asong -m command -a "pwd chdir=/tmp/"
192.168.1.20 | CHANGED | rc=0 >>
/tmp
192.168.1.30 | CHANGED | rc=0 >>
/tmp
练习creates参数
creates 在创建一个文件之前,判断该文件知否存在,存在跳过前面的东西,不存在执行前面的动作
ansible 192.168.1.20 -m command -a "pwd creates=/asong"
[root@m01 ~]# ansible 192.168.1.20 -m command -a "pwd creates=/asong"
192.168.1.20 | CHANGED | rc=0 >>
/root
[root@m01 ~]# ansible 192.168.1.20 -m command -a "pwd creates=/opt"
192.168.1.20 | SUCCESS | rc=0 >>
skipped, since /opt exists
removes 定义一个文件是否存在,存在执行前面的动作,不存在则跳过动作
ansible asong -a "ls /opt removes=/asong"
[root@m01 ~]# ansible asong -a "ls /op removes=/op"
192.168.1.20 | SUCCESS | rc=0 >>
skipped, since /op does not exist
192.168.1.30 | SUCCESS | rc=0 >>
skipped, since /op does not exist
[root@m01 ~]# ansible asong -a "ls /opt removes=/opt"
192.168.1.20 | CHANGED | rc=0 >>
192.168.1.30 | CHANGED | rc=0 >>
warn参数,是否提供告警信息
ansible asong -m command -a "chmod 000 /etc/hosts"
[root@m01 ~]# ansible asong -m command -a "chmod 000 /etc/hosts"
[WARNING]: Consider using the file module with mode rather than running 'chmod'. If you need to use
command because file is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.1.30 | CHANGED | rc=0 >>
192.168.1.20 | CHANGED | rc=0 >>
执行命令且忽略告警信息
[root@m01 ~]# ansible asong -m command -a "chmod 000 /etc/hosts warn=False"
192.168.1.30 | CHANGED | rc=0 >>
192.168.1.20 | CHANGED | rc=0 >>
shell模块
作用:在远程机器上执行命令 (复杂的命令)
了解 模块用法的渠道
- linux命令行里面通过 ansible-doc
- ansible网查看帮助信息https://docs.ansible.com/ansible/latest/modules/shell_module.html
shell 模块支持的参数和解释
chdir 在执行命令之前,先通过cd 进入该参数指定的目录
creates 在创建一个文件之前,判断该文件知否存在,如果存在不执行命令,如果存在该文件,则执行shell命令
free_form 该参数可以输入任何的系统命令,实现远程执行和管理
removes 定义一个文件是否存在,存在执行前面的动作,不存在则跳过动作
shell模块
批量查询进程信息
[root@m01 ~]# ansible asong -m shell -a "ps -ef| grep vim|grep -v grep"
192.168.1.30 | CHANGED | rc=0 >>
root 2804 2162 0 23:11 pts/0 00:00:00 vim heiheihei.sh
192.168.1.20 | CHANGED | rc=0 >>
root 5376 4596 0 23:10 pts/0 00:00:00 vim xixixi.sh
批量在客户端机器,创建写入文件信息
[root@m01 ~]# ansible asong -m shell -a "echo nizhenbang > /tmp/heihei.txt"
192.168.1.30 | CHANGED | rc=0 >>
192.168.1.20 | CHANGED | rc=0 >>
批量执行脚本
该需要执行的脚本,必须要求在客户端机器上存在,否则会报错文件不存在,这是shell模块的特点。是因为有一个专门执行脚本的script模块
注意这个脚本必须在客户机器上存在才行
1、创建文件夹
2、创建ssh脚本文件,还要写入脚本内容
3、赋予脚本的可执行权限
4、执行脚本
5、忽略warning信息
思路分析
最好所有的操作都是在 管理机器上
ansible asong -m shell -a "mkdir -p /server/myscripts/;echo 'hostname' > /server/myscripts/hostname.sh;chmod +x /server/myscripts/hostname.sh;bash /server/myscripts/hostname.sh warn=False"
[root@m01 ~]# ansible asong -m shell -a "mkdir -p /server/myscripts/;echo 'hostname' > /server/myscripts/hostname.sh;chmod +x /server/myscripts/hostname.sh;bash /server/myscripts/hostname.sh warn=False"
192.168.1.30 | CHANGED | rc=0 >>
rsync01
192.168.1.20 | CHANGED | rc=0 >>
nfs01
script脚本
功能:把m01管理机器上的脚本远程传输到被管理节点上去执行
比起shell模块,script模块功能更强大,在m01机器本地有一份脚本,就可以在所有被管理的节点上去运行
script 模块支持的参数和解释
chdir 在执行命令之前,先通过cd 进入该参数指定的目录
creates 在创建一个文件之前,判断该文件知否存在,如果存在不执行命令,如果存在该文件,则执行shell命令
free_form 该参数可以输入任何的系统命令,实现远程执行和管理
removes 定义一个文件是否存在,存在执行前面的动作,不存在则跳过动作
应用
1、在管理节点上创建脚本
[root@m01 ~]# mkdir -p /myscripts
[root@m01 ~]# cd /myscripts/
[root@m01 myscripts]# ls
[root@m01 myscripts]# echo -e "pwd\nhostname" > /myscripts/local_hostname.sh
[root@m01 myscripts]# ls
local_hostname.sh
[root@m01 myscripts]# cat local_hostname.sh
pwd
hostname
2、授权
[root@m01 myscripts]# chmod +x /myscripts/local_hostname.sh
远程的批量执行脚本,且在客户端上不需要存在该脚本
ansible asong -m script -a "/myscripts/local_hostname.sh"
[root@m01 myscripts]# ansible asong -m script -a "/myscripts/local_hostname.sh"
192.168.1.30 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.1.30 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.30 closed."
],
"stdout": "/root\r\nrsync01\r\n",
"stdout_lines": [
"/root",
"rsync01"
]
}
192.168.1.20 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.1.20 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.20 closed."
],
"stdout": "/root\r\nnfs01\r\n",
"stdout_lines": [
"/root",
"nfs01"
]
}
利用script模块 可以批量让所有被管理的机器执行脚本,且该脚本不需要在客户端上存在