学习资源
Ansible自动化运维的简单介绍 人工运维:维护多台机器,需要在不同机器部署相同的服务,执行相同的命令。(效率较低)
自动化运维:结合SSH免密登录以及shell脚本来完成自动化的部署操作。
Ansible是基于python开发的一款自动化运维软件,可以同时管理多个远程主机(必须是任意可以通过ssh登录的机器)。
Ansible通过ssh协议实现了 管理节点(安装了ansible服务的机器)、被管理节点(被管理的机器)的通信。
ansible可以管理的机器:远程虚拟机、物理机、本机机器;
主要特点:
安装部署简单
无须安装被管理机器的客户端,且无须占用其他端口
不用root也可操作,降低系统权限
不仅仅支持python,还支持其他语言的二次开发
部署测试环境 准备虚拟机 准备3个虚拟机,配置在一个局域网内,并设置好静态IP
hadoop101 192.168.10.101 被管理机器
hadoop102 192.168.10.102 被管理机器(配置好ssh服务,以及关闭防火墙等)
CentOSByCC 192.168.10.100 管理机器(安装好ansible的服务端)
部署管理机器 选择yum自动化安装,阿里云yum源、epel源(配置yum源相关操作请看这篇文章—-后面补地址———)
1 2 3 4 5 6 7 8 # 配置epel源 sudo yum install epel-release # 安装 ansible 服务以及依赖 yum install ansible libselinux-python -y # 检查 ansible 软件安装情况 rpm -ql ansible | grep -E '^/etc|^/usr/bin' # 查看 ansible 版本 ansible --version
部署被管理机器 1 2 # 安装依赖 yum install epel-release libselinux-python -y
批量管理主机 ansible批量管理主机的方式主要有两种
1 2 3 4 5 6 7 8 9 10 11 12 # 管理机器(CentOSByCC) # 备份现有的配置文件 cp /etc/ansible/hosts{,.ori} # 修改hosts文件,添加ansible需要管理的机器地址 (配置域名解析后,添加主机名也可) [root@CentOSByCC ansible]# tail -3 /etc/ansible/hosts [chaoge] 192.168.10.101 192.168.10.102 # 主机列表也可写成以下形式 192.168.10.[101:102] host[1:2]
ssh密码认证方式管理机器 1 2 3 4 5 6 # 在管理机器上,告诉其它被管理的机器,你要执行什么命令,以及什么用户去执行 # -m 指定功能模块,默认就是 command 模块 # -a 告诉模块需要执行的参数 # -k 询问密码验证 # -u 指定运行的用户 ansible chaoge -m command -a 'hostname' -k -u root # 显示被管理机器的主机名
执行上面的命令时,默认情况下会有错误提示,需要手动ssh对主机进行一次连接
ssh root@192.168.10.101
ssh root@192.168.10.102
exit 退出远程连接
cat ~/.ssh/known_hosts 查看ssh连接信息
然后再执行命令即可
批量免密管理机器 每次执行ansible命令,需要输入ssh密码,因此配置免密登录,更加方便远程管理,有以下几种方式可以实现。
ansible自带的密码认证参数 在 /etc/ansible/hosts文件中,定义好密码即可,即可实现快速认证
1 2 3 4 5 6 # 修改 hosts 文件 [chaoge] 192.168.10.101 ansible_user=root ansible_ssh_pass=root ansible_ssh_port="2222" # 依次为 登录用户、登录密码、默认端口(可更改) 192.168.10.102 ansible_user=root ansible_ssh_pass=root # 此时不需要指定用户,也不需要输入密码即可通过认证 ansible chaoge -m command -a "ifconfig ens33"
ssh密钥批量管理 上面那种方式明文暴露了密码,不安全,这种方式更加安全放心。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 1.在管理机器上创建 ssh密钥对 ssh-keygen -f ~/.ssh/id_rsa -P "" > /dev/null 2>&1 # 2.检查公私钥文件 [root@CentOSByCC cc]# cd ~/.ssh/ [root@CentOSByCC .ssh]# ls id_rsa id_rsa.pub known_hosts # 3.编写公钥分发脚本 并执行 # !/bin/bash rm -rf ~/.ssh/id_rsa* ssh-keygen -f ~/.ssh/id_rsa -P "" > /dev/null 2>&1 SSH_Pass=root Key_Path=~/.ssh/id_rsa.pub for ip in 101 102 do sshpass -p $SSH_Pass ssh-copy-id -i $Key_Path "-o StrictHostKeyChecking=no" 192.168.10.$ip done # 非交互式分发密钥命令需要用 sshpass 指定SSH密码,通过 -o StrictHostKeyChecking=no 跳过ssh连接确认信息
此时管理机器连接被管理机器时就无需输入密码了
1 ansible chaoge -m command -a "uname -a"
组变量 给主机组统一赋值变量
1 2 3 4 5 6 7 8 9 10 vim /etc/ansible/hosts [webserver] host1 host2 host3 host4 [webserver:vars] ansible_user=root ansible_ssh_pass=root
子分组 管理多个主机组
1 2 3 4 5 6 7 8 9 10 11 vim /etc/ansible/hosts [webserver1] host1 host2 [webserver2] host3 host4 [webserver:children] webserver1 webserver2
自定义主机列表 我们可以在任何位置使用自己创建的主机列表文件进行连接,用 -i 选项实现
1 2 3 4 5 6 7 8 9 10 11 12 # 创建主机列表文件 vim hostlist [webserver] host1 host2 [webserver:vars] ansible_user=root ansible_ssh_pass=root # 使用此文件连接主机列表 ansible -i hostlist webserver -m ping
模式与命令 ansible实现批量化主机管理的模式,主要有两种
利用ansible的纯命令行实现的批量管理(简单的shell命令管理)
利用ansible的playbook剧本来实现批量管理(复杂的shell脚本管理)
ad-hoc模式 直接使用ansible的命令行,处理一些临时的、简单的任务,比如
临时批量查看被管理机器的内存情况、cpu负载情况、网络情况
临时分发配置文件
playbook模式 主要针对比较具体的任务,比如
一键部署rsync备份服务器
一键部署lnmp环境
ansible模块 ansible-doc命令 1 2 3 4 # 列出所有的ansible支持的模块 ansible-doc -l # 查看某个模块的具体用法以及参数 ansible-doc -s 模块名
command模块 作用:在远程节点上执行一个命令
command模块是ansible的默认基本模块,也可以省略不写。
使用command模块时,不得出现 $name,> < | ; & 等shell变量和特殊符号,因为command模块无法识别。
参数:
chdir 在执行命令之前,先进入该参数指定的目录
creates 在执行命令之前,判断该文件是否存在,如果存在则跳过,如果不存在则执行
removes 在执行命令之前,判断该文件是否存在,如果存在则执行,如果不存在则跳过
free-form 该参数可以输入任何的系统命令,实现远程执行和管理
warn 是否提供告警信息
1 2 3 4 5 6 # 执行命令前切换目录 ansible chaoge -m command -a 'pwd chdir=/tmp/' # 存在该目录执行则执行命令 ansible chaoge -m command -a 'pwd removes=/tmp/' # 关闭告警信息 ansible chaoge -m command -a 'chmod 000 /etc/hosts warn=false'
shell模块 作用:在远程机器上执行复杂的命令
参数:
chdir 在执行命令之前,先进入该参数指定的目录
creates 在执行命令之前,判断该文件是否存在,如果存在则跳过,如果不存在则执行
removes 在执行命令之前,判断该文件是否存在,如果存在则执行,如果不存在则跳过
free-form 该参数可以输入任何的系统命令,实现远程执行和管理
warn 是否提供告警信息
1 2 3 4 5 6 # 批量创建写入文件信息 ansible -m shell -a 'echo 哈哈哈哈 > /tmp/haha.txt' # 批量远程执行脚本 # !!! 需要执行的脚本,必须在客户端机器上存在,否则会报错文件不存在 ansible chaoge -m shell -a "mkdir -p /server/myscripts;echo 'hostname' > /server/myscripts/hostname.sh;chmodl+x /server/myscripts/hostname.sh;bash /server/myscripts/hostname.sh warn=False"
script模块 作用:把管理机器上的脚本远程传输到远程机器上去执行(远程机器上不需要有该脚本)
参数:
chdir、creates、removes
1 2 # 在管理机器上执行,被管理机器返回结果 ansible chaoge -m script -a '/script.sh'
拷贝模块 作用:复制文件到到远程机器的某个位置
1 2 3 4 5 6 7 # src 要复制的文件 # des 要复制去的位置 # owner 所属用户 # group 所属组 # mode 权限分配 # backup 如果目标文件存在,是否在覆盖前创建一个备份 ansible chaoge -m copy -a 'src=/etc/hosts dest=/tmp/2.txt owner=root group=bin mode=777'
用户模块 作用:可以批量为远程机器创建用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 创建用户 # name 用户名 # state # group 指定基本组 # password 指定用户密码 # shell 指定默认shell ansible chaoge -m user -a 'name=testUser state=present' # 生成加密密码并修改 echo '123456' | openssl passwd -1 -stdin # 会生成对应的加密密码 ansible chaoge -m user -a 'name=testUser state=present password="$1$oUWbRo3r$mwVPTEXn3fGuvPC9VLpBp."' # 测试 ssh testUser@192.168.10.101 # 输入密码 123456
yum模块 作用:批量进行软件的安装
1 2 3 # name 包名,值为 * 代表对所有软件进行升级 # state 操作(present--->安装, latest--->安装最新的,absent---> 卸载软件) ansible chaoge -m yum -a 'name="httpd" state="latest"'
服务模块 作用:服务状态控制
1 2 3 4 # name 服务名 # state started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置 # enabled 设置开机启动 ansible chaoge -m service -a 'name=httpd state=started enabled=yes'
文件模块 作用:操作文件
1 2 3 4 # path 文件/文件夹路径 # state directory--->如果目录不存在,就创建目录 file--->即使文件不存在,也不会被创建 link --->创建软链接 hard--->创建硬链接 touch --->如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间 absent--->删除目录、文件或者取消链接文件 # mode 文件/文件夹权限 ansible chaoge -m file -a 'path=/tmp/77.txt mode=777 state=touch'
收集模块 作用:显示主机相关信息
1 2 3 # filter 过滤出相关信息 ansible chaoge -m setup ansible chaoge -m setup -a 'filter=ansible_processor'
fetch模块 作用:用于从远程某主机获取(复制)文件到本地
1 2 3 # src 在远程拉取的文件,并且必须是一个file,不能是目录 # dest 用来存放文件的目录 ansible host1 -m fetch -a 'src=/data/test dest=/data'
cron模块 作用:管理cron计划任务
1 2 3 4 5 6 7 8 9 10 11 12 # day 日应该运行的工作( 1-31, *, */2, ) # hour 小时 ( 0-23, *, */2, ) # minute 分钟( 0-59, *, */2, ) # month 月( 1-12, *, /2, ) # weekday 周 ( 0-6 for Sunday-Saturday,, ) # job 指明运行的命令是什么 # name 定时任务描述 # reboot 任务在重启时运行,不建议使用,建议使用special_time # special_time 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时) # state 指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务 # user 以哪个用户的身份执行 ansible host1 -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
group模块 作用:主要用于添加或删除组
1 2 3 4 5 # gid 设置组的GID号 # name 指定组的名称 # state 指定组的状态,默认为创建,设置值为absent为删除 # system 设置值为yes ,表示创建为系统组 ansible chaoge -m group -a 'name=hhh state=present'
unarchive模块 作用:解压缩包
1 2 3 4 # src 要解压的包名 # dest 解压到哪个目录下 # remote_src yes --->解压远程主机上的包 no--->将管理机上的包传到远程主机上解压 ansible host1 -m unarchive -a 'src=/root/11.tar dest=/home'
剧本实战 了解 YAML 语言 语法 1 2 3 4 5 6 7 8 9 10 # 列表 fruits: - Apple - Orange - Mangp # 字典 John: name:John James job:doctor sex:man
web服务器的部署配置 准备工作,在管理机器上操作
1 2 3 4 5 6 7 # ansible 管理机器 yum install -y httpd mkdir apache cd apache cp -rf /etc/httpd/conf/httpd.conf . vim httpd.conf Listen 8080 #修改为监听 8080 端口
编写剧本 , vim apache.yaml
1 2 3 4 5 6 7 8 - hosts: host1 tasks: - name: install apache package yum: name=httpd state=present - name: copy apache conf copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf - name: ensure apache is running service: name=httpd state=started enabled=yes
测试编写的剧本
1 2 3 4 5 6 7 8 9 10 # 检验语法是否正确 ansible-playbook apache.yaml --syntax-check # 列出任务 ansible-playbook apache.yaml --list-tasks # 列出主机 ansible-playbook apache.yaml --list-hosts # 执行 ansible-playbook apache.yaml # 在被管理机器上访问 ip:8080 https://192.168.10.101:8080
如果我们更改再次端口,并重新执行剧本,虽然配置文件已推送,但目标主机服务并不会重新启动,所以无法立即用更改后的端口进行访问。
对于这个问题,我们可以用handlers触发器解决,在剧本文件里修改
1 2 3 4 5 6 7 8 9 10 11 12 - hosts: host1 tasks: - name: install apache package yum: name=httpd state=present - name: copy apache conf copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf notify: restart apache service - name: ensure apache is running service: name=httpd state=started enabled=yes handlers: - name: restart apache service service: name=httpd state=restarted
当 copy 模块发生变化时,就会执行对应的 handlers 模块
部署并配置Nginx 准备目录结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 mkdir roles/nginx/{files,handlers,tasks.templates,vars} -p touch roles/site.yaml roles/nginx/{handlers,tasks,vars}/main.yaml echo 1234 > roles/nginx/files/index.html yum install -y nginx && cp /etc/nginx/nginx.conf roles/nginx/templates/nginx.conf.j2 # 使用 tree 命令查看目录结构 roles/ ├── nginx │ ├── files │ │ └── index.html │ ├── handlers │ │ └── main.yaml │ ├── tasks │ │ └── main.yaml │ ├── templates │ │ └── nginx.conf.j2 │ └── vars │ └── main.yaml └── site.yaml # nginx 角色名 # files 普通文件 # handlers 触发器文件 # tasks 主任务 # templates 金甲模板(有变量) # vars 自定义变量
编写剧本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 - name: install epel-release packge yum: name=epel-release state=latest - name: install nginx packge yum: name=nginx state=latest - name: copy index.html copy: src=index.html dest=/usr/share/nginx/html/index.html - name: copy nginx.conf template template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart nginx - name: make sure nginx service running service: name=nginx state=started enabled=yes worker_processes {{ ansible_processor_cores }} worker_connections {{ worker_connections }} worker_connections: 10234 - name: restart nginx service: name=nginx state=restarted - hosts: host1 roles: - nginx
在金甲模板中,可以将某些值替换为内置变量,可以用setup模块查出变量的值
1 > ansible host1 -m setup -a 'filter=ansible_processor_cores'
执行剧本并验证 1 2 3 4 cd roles ansible-playbook site.yaml --syntax-check ansible-playbook site.yaml # 访问IP进行验证
通过IP访问失败,通过定位发现是前端目录文件路径不对
1 2 3 # server块 root /data/web # 修改为 root /usr/share/nginx/html # 之前在主任务剧本里定义过的