学习资源 
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 # 之前在主任务剧本里定义过的