Ansible自动运维
课程目标
-
了解常见的自动化运维工具以及ansible的作用
-
完成ansible服务的搭建
-
掌握常用的ansible模块的使用
-
掌握playbook的编写
-
理解roles的作用与掌握roles的编写
课程实验
-
ansible场景引入及常见的自动化运维工具
-
ansible概述及服务搭建
-
ansible主机清单功能实验
-
ansible常用模块使用实验
-
playbook功能使用
-
roles使用场景及具体使用
课堂引入
- shell能够实现自动化运维,但是需要将shell基本发送到具体的主机上执行,如果要同时运维多台机器,那么就需要一个自动化运维的工具
授课进程
一、自动化运维场景及工具
1、场景描述
场景:假设我要去100台服务上做一个操作(如nginx服务器修改配置文件里的某一个参数)
方案:
按传统的方法, 一台连着一台服务器的ssh上去手动操作
缺点:效率太低
写个shell脚本来做,将所有的主机写到一个文件中,循环读取文件,通过ssh远程操作
缺点:
1)管理的机器平台不一致,脚本可能不具备通用性
2)传密码麻烦(在非免密登录的环境下, 需要expect来传密码)
3)效率较低,循环100次也需要一个一个的完成,如果用`&`符放到后台执行,则会产生100个进程
2、概述
自动化运维是指通过运维工具来解决生产中大量、繁杂的事务,监控生产环境变化、自动响应并处置事件等问题(日常检查、配置变更和软件安装),从而提升运维效率、降低重大问题发生的概率、更全面的保障生产环境
站在运维的角度来说自动化运维弥补了传统运维的人效低、响应慢,极大的提升了生产力,让人专注于生产中的关键问题。站在开发的角度来说自动化运维面向生产环境(对象),挖掘生产环境更多的属性,总结业务生命周期的规律,找到维护业务的逻辑,从而更全面的感知、保障生产环境
自动化运维主要关注的方面:
1. 管理机与被管理机的连接(管理机如何将管理指令发送给被管理机)
2. 服务器信息收集 (如果被管理的服务器有centos7.9外还有其它linux发行版,如suse,ubuntu等。当你要做的事情在不同OS上有所不同,你需要收集信息,并将其分开处理)
3. 服务器分组(因为有些时候我要做的事情不是针对所有服务器,可能只针对某一个分组)
4. 管理内容的主要分类
文件目录管理(包括文件的创建,删除,修改,查看状态,远程拷贝等)
用户和组管理
cron时间任务管理
yum源配置与通过yum管理软件包
服务管理
远程执行脚本
远程执行命令
3、常见工具

Ansible是当下火热的自动化运维工具,它基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,通过集成非常丰富的模块,它可以实现各种管理任务,如批量系统配置、批量程序部署、批量运行命令等。
重要的是,Ansible操作简单,即使新手也可以轻松上手,同时又提供非常丰富的功能,在运维领域,几乎可以做任何事。

Puppet是历史悠久的运维工具之一。它是一种基础架构即代码(IaC)工具,使用户可以定义其基础架构所需的状态,并使系统自动化以实现相同状态。
Puppet可监视用户的所有系统,并防止任何偏离已定义状态的情况。从简单的工作流程自动化到基础架构配置和合规性,Puppet都能做到。
Puppet通过让客户端检查主站的更新清单来更新节点的配置,然后从主站服务器拉下新的配置。由于这个特点,Puppet比这里提到的许多其他工具更倾向于系统管理员

Salt由Salt Master和被称为Salt Minions的客户端组成,后者作为代理在每个节点机器上运行。Puppet的工作方式是由节点请求更新,而Salt的工作方式与此相反,Salt Master将所有配置推送给所有客户机。
Salt还可以在多主机配置中运行。如果一个Salt主服务器发生故障,代理将连接到配置中列出的另一个主服务器。这一功能提高了整个系统的整体可用性和冗余度。
Salt的另一个好处是,它允许一次并行执行多个命令。这些命令通过AES(高级加密标准)进行加密,并通过SSH协议推送给客户端节点
小结:
puppet:基于ruby语言,成熟稳定。适合于大型架构,相对于ansible和saltstack会复杂些
saltstack:基于python语言。相对简单,大并发能力比ansible要好, 需要维护被管理端的服务。如果服务断开,连接就会出问题
ansible:基于python语言。简单快捷,被管理端不需要启服务。直接走ssh协议,需要验证所以机器多的话速度会较慢
二、ansible概述及搭建
1、概述
1)概述
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography) 后面讲Python的时候会着重提到
2)特点
-
部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
-
默认使用SSH协议对设备进行管理;
-
有大量常规运维操作模块,可实现日常绝大部分操作;
-
配置简单、功能强大、扩展性强;
-
支持API及自定义模块,可通过Python轻松扩展;
-
通过Playbooks来定制强大的配置、状态管理;
-
轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
-
提供一个功能强大、操作性强的Web管理界面和REST API接口------AWX平台。
-
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
3)架构图

Ansible:Ansible核心程序。
HostInventory:记录由Ansible管理的主机信息,包括端口、密码、ip等。
Playbooks:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
CoreModules:核心模块,主要操作是通过调用核心模块来完成管理任务。
CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
ConnectionPlugins:连接插件,Ansible和Host通信使用
2、搭建
1)环境准备
| IP地址 | 主机名称 | 配置要求 | 服务器角色 |
|---|---|---|---|
| 192.168.217.139 | ansible | 4CPU、4GB内存、20G磁盘 | ansible服务器 |
| 192.168.217.140 | host01 | 1CPU、1GB内存、20G磁盘 | 目标主机 |
| 192.168.217.141 | host02 | 1CPU、1GB内存、20G磁盘 | 目标主机 |
| 192.168.217.142 | host03 | 1CPU、1GB内存、20G磁盘 | 目标主机 |
ansible主机
#!/bin/bash
# 1. 设置主机名
hostnamectl set-hostname $1
# 2. 修改hosts文件
echo 192.168.169.153 host01 >> /etc/hosts
echo 192.168.169.154 host02 >> /etc/hosts
echo 192.168.169.155 host03 >> /etc/hosts
# 3. 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
# 4. 配置yum源
cd /etc/yum.repos.d
rm -rf *
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
yum install epel-release -y
# 5. 安装必要软件
yum install vim -y
yum install net-tools -y
yum install wget -y
yum install yum-utils -y
yum install ntp -y
# 6. 时间同步
systemctl enable ntpd --now
# 7. 重启
reboot
目标主机
1. 设置主机名
hostnamectl set-hostname host01
hostnamectl set-hostname host02
hostnamectl set-hostname host03
2. 确认sshd服务开启(同时确认sshd服务是否监听的是22端口)
systemctl status sshd
2)ansible安装
只需要在ansible主机中安装即可,其他机器中不需要安装
yum install ansible -y
ansible --version

3、ansible命令
语法格式:
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
ansible 匹配主机模式 -m 模块 -a '需要执行的内容'
< host-pattern> 匹配主机的列表
- ALL 表示列表中的所有主机
ansible all -m ping #匹配所有主机
ansible "*" -m ping #匹配所有主机
ansible 192.168.1.* -m ping #匹配IP地址以192.168.1开头的主机
ansible “*srvs” -m ping #匹配分组名 以 srvs结尾的主机
ansible websrvs -m ping #匹配分组名为websrvs
4、主机清单
通过ansible的ping模块测试ansible的主机清单文件,主要验证以下几项内容:分组,子分组,组变量
需求1:ping三台主机
ansible host01 -m ping
ansible host02 -m ping
ansible host03 -m ping

需求2:编辑主机清单文件,ping三台主机
vim /etc/ansible/hosts
host01
host02
host03
ansible host01 -m ping

ansible host01 -m ping -u root -k

需求3:给host02主机设置ssh免密登录,之后使用ping模块测试一下
ssh-keygen -P '' -f /root/.ssh/id_rsa
ssh-copy-id root@host02
ssh root@host02
ansible host02 -m ping -o

需求4:添加组nginxServer,将host01,host02添加到nginxServer组中,ping组nginxServer
host03
[nginxServer]
host01
host02
ansible nginxServer -m ping -o

需求5:更改host文件,给nginxServer组内的host01主机设置用户名与密码
host03
[nginxServer]
host01 ansible_ssh_user=root ansible_ssh_pass="root"
host02
ansible nginxServer -m ping -o

需求6:添加分组tomcatServer,将host03添加到tomcatServer中,添加分组webServer,将nginxServer及tomcatServer添加到webServer中,ping组webServer,同时通过组变量设置组内所有机器的账号与密码
[tomcatServer]
host03
[nginxServer]
host01
host02
[webServer:children]
nginxServer
tomcatServer
[webServer:vars]
ansible_ssh_user="root"
ansible_ssh_pass="root"
ansible webServer -m ping -o

描述1:
如果SSH连接较慢的话,将主机中的sshd_config配置文件中的UseDNS改为no,再重启sshd服务即可
描述2:
普通的ping命令与ansible的ping模块的区别?
普通的ping命令是查看目录网络是否通畅,系统自带的服务
ansible的ping模块需要依赖于ssh服务,用于验证目标主机是否可连接
需求1:ping三台主机
需求2:编辑主机清单文件,ping三台主机
需求3:给host02主机设置ssh免密登录,之后使用ping模块测试一下
需求4:添加组nginxServer,将host01,host02添加到nginxServer组中,ping组nginxServer
需求5:更改host文件,给nginxServer组内的host01主机设置用户名与密码
需求6:添加分组tomcatServer,将host03添加到tomcatServer中,添加分组webServer,将nginxServer及tomcatServer添加到webServer中,ping组webServer,同时通过组变量设置组内所有机器的账号与密码
三、ansible模块
1、概述
ansible的模块就是提供了特定的功能的命令,比如之前使用的ping模块,就是用于检测目标主机是否可以联通
2、常用模块

3、file模块
常用选项:
path: #必选项,定义文件/目录的路径
force: #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group: #定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner: #定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse: #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest: #被链接到的路径,只应用于state=link的情况
state: #状态,有以下选项:
directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
#创建新目录
#创建新文件
#删除文件
#创建软连接
#创建文件指定所有者,权限
#创建新目录
ansible nginxServer -m file -a "name=/data state=directory"
#创建新文件
ansible nginxServer -m file -a "name=/data/file state=touch"
#删除文件
ansible nginxServer -m file -a "name=/data/file state=absent"
#创建软连接
ansible nginxServer -m file -a "src=/data dest=/data/datalink state=link"
#创建文件指定所有者,权限
ansible nginxServer -m file -a "path=/data/a.sh owner=zhangsan mode=755"

4、copy模块
常用选项:
src: # 源文件绝对路径或相对路径
dest: #必选项,将源文件复制到的远程主机的绝对路径
content: #用于替换"src",可以直接指定文件的值
backup: #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode: #递归设定目录的权限,默认为系统默认权限
force: #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others: #所有的 file 模块中的选项可以在这里使用
mode: #设置文件权限
owner: #属主
group: #属组
#给定内容生成文件,并制定权限
#在家目录中创建abc.txt文件,将文件拷贝到目标主机中的/usr/local下面
#更改abc.txt文件内容,将文件拷贝到目标主机中的/usr/local下面,并将目标主机源文件进行备份
#给定内容生成文件,并制定权限
ansible tomcatServer -m file -a "name=/data state=directory"
ansible tomcatServer -m copy -a "content='I am keeper\n' dest=/data/name mode=777"
#在家目录中创建abc.txt文件,将文件拷贝到目标主机中的/usr/local下面
touch abc.txt
ansible tomcatServer -m copy -a "src=/root/abc.txt dest=/usr/local/abc.txt mode=777"
#更改abc.txt文件内容,将文件拷贝到目标主机中的/usr/local下面,并将目标主机源文件进行备份
echo "123" > abc.txt
ansible tomcatServer -m copy -a "src=/root/abc.txt dest=/usr/local/abc.txt backup=yes"
练习:
需求1: 在ansible上配置好所有的yum源,然后拷贝到webServer的远程机器上(要求目录内的内容完全一致)
ansible tomcatServer -m file -a "path=/etc/yum.repos.d/ state=absent"
ansible tomcatServer -m copy -a "src=/etc/yum.repos.d dest=/etc/"
ansible tomcatServer -m yum -a "update_cache=yes"
需求2: 使用hostname模块修改过主机名后.在ansible上修改/etc/hosts文件,并拷贝到webServer的远程机器上
5、user模块
常用选项:
comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用state=absent时, 行为与userdel –force一致.
group # 指定基本组
groups # 指定附加组,如果指定为(groups=)表示删除所有组
home # 指定用户家目录
move_home # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用state=absent时, 行为是与userdel –remove一致
shell # 指定默认shell
state # 设置帐号状态,不指定为创建,指定值为absent表示删除
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid # 指定用户的uid
#创建aaa用户,设置系统用户,创建家目录,执行shell类型为/sbin/nologin
#创建bbb系统用户,设置为普通用户,并且登录shell环境为/bin/bash,使用password参数传密码
#删除bbb用户不删除家目录
#删除aaa用户,同时删除家目录
#创建aaa用户,设置系统用户,创建家目录,执行shell类型为/sbin/nologin
ansible tomcatServer -m user -a 'name=aaa system=yes shell="/sbin/nologin"'
#创建bbb系统用户,设置为普通用户,并且登录shell环境为/bin/bash,使用password参数传密码
echo 123456 | openssl passwd -1 -stdin
ansible tomcatServer -m user -a 'name=bbb password="$1$iQYFYdvf$sKwtPklJM/5Jchwp4PQRJ."'
#删除bbb用户不删除家目录
ansible tomcatServer -m user -a "name=bbb state=absent"
#删除aaa用户,同时删除家目录
ansible tomcatServer -m user -a "name=aaa state=absent remove=yes"
6、yum模块
常用选项:
name #所安装的包的名称
state #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于presentor latest。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
在使用yum模块之前,前提是所有目标主机的yum源已经配置好
#安装vsftpd包
#安装vsftpd包与httpd包
#卸载vsftpd包
#安装本地的包,且排除某些包不安装
#安装vsftpd包
ansible tomcatServer -m yum -a 'name=vsftpd'
#安装vsftpd包与httpd包
ansible tomcatServer -m yum -a 'name=vsftpd,httpd'
#卸载vsftpd包
ansible tomcatServer -m yum -a 'name=vsftpd state=removed'
#安装本地的包,且排除某些包不安装
ansible tomcatServer -m yum -a "name=/tmp/*.rpm exclude=*unix* state=present"
7、service模块
常用选项:
enabled=[yes|no] #是否开机启动 默认no
name: #必选项,服务名称
pattern: #定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
sleep: #如果执行了restarted,在则stop和start之间沉睡几秒钟
state: #对当前服务执行启动,停止、重启、重新加载等操作
#(started,stopped,restarted,reloaded)
#启动vsftpd服务,并设为开机自动启动
#关闭vsftpd服务,并设为开机不自动启动
#启动vsftpd服务,并设为开机自动启动
ansible tomcatServer -m service -a 'name=vsftpd state=started enabled=on'
#关闭vsftpd服务,并设为开机不自动启动
ansible tomcatServer -m service -a 'name=vsftpd state=stopped enabled=false'
8、cron模块
常用选项:
name: #定时任务描述
job: #指明运行的命令是什么,可以写shell命令
cron_file: # 自定义cron_file的文件名,使用相对路径则在/etc/cron.d中。
user: # 以哪个用户的身份执行
minute: # 分(0-59, *, */N),不写时,默认为*
hour: # 时(0-23, *, */N),不写时,默认为*
day: # 日(1-31, *, */N),不写时,默认为*
month: # 月(1-12, *, */N),不写时,默认为*
weekday: # 周(0-6 for Sunday-Saturday, *),不写时,默认为*
special_time #特殊的时间范围,参数: reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态
present表示添加定时任务,也是默认设置
absent表示删除定时任务
#创建计划任务:每周1,3,5,每分钟打印warning,任务名称:test
#删除计划任务
#创建计划任务:每周1,3,5,每分钟打印warning,任务名称:test
ansible tomcatServer -m cron -a 'minute=* weekday=1,3,5 job="/usr/bin/wall warning" name=test'
#删除计划任务
ansible tomcatServer -m cron -a 'job="/usr/bin/wall warning" name=test state=absent'
9、shell模块
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能
#统计主机中一共有多少个用户
ansible tomcatServer -m shell -a "wc -l /etc/passwd"

四、playbook
1、概述
Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事。使用易读的YAML格式组织Playbook。
playbook是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务
2、核心元素
-
Hosts 执行的远程主机列表
-
Tasks 任务集
-
Varniables 内置变量或自定义变量在playbook中调用
-
Templates 模板,即使用模板语法的文件,比如配置文件,模板的后缀必须为xxx.j2等
-
Handlers 和notify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
-
tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码。
-
remote_user:在远程主机以哪个用户身份执行;
hosts: 用于指定要执行任务的主机,其可以是一个或多个由冒号分隔主机组
remote_user: 用于指定远程主机上的执行任务的用户
tasks: 任务列表, 按顺序执行任务,如果一个host执行task失败, 整个tasks都会回滚, 修正playbook 中的错误, 然后重新执行即可.
tasks:
- name: ensure apache is at the latest version
yum: name=httpd,httpd-devel state=latest
- name: write the apache config file
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
handlers: 类似task,但需要使用notify通知调用
不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次
andlers最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了
tasks:
- name: ensure apache is at the latest version
yum: name=httpd,httpd-devel state=latest
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
variables: 变量,定义变量可以被多次方便调用
---
- hosts: group1
remote_user: root
vars:
- user: test1
tasks:
- name: create user
user: name={{user}} state=present
3、格式语法(yaml)
playbook使用yaml语法格式,后缀可以是yaml,也可以是yml
--- #表示文档开始
- hosts: host01 # "- "表示一个块序列的节点,注意:横杠后面有空格,可以写主机名,主机组名,多个使用逗号隔开
remote_user: root #指定在进行远程操作时使用root用户进行操作
tasks: #使用tasks关键字指明要进行操作的任务列表,之后的行都属于tasks键值对中的值。
- name: Ping #每个任务都以"- "开头,每个任务都有自己的名字,任务名使用name关键字进行指定
ping: #ansible模块
- name: make directory test #第二个任务使用file模块,使用file模块时,指定了path参数与state参数的值。
file: #ansible模块
path: /data/test #模块的参数
state: directory
--- #标记文件的开始
- hosts: webserver #指定该playbook在哪个服务器上执行
vars: #表示下面是定义的变量,
http_port: 80 #变量的形式,key: value,这里http_port是变量名,80是值
max_clients: 200
remote_user: root #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。
tasks: #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。
- name: ensure apache is at the latest version #指定该任务的名称。
yum: pkg=httpd state=latest #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。
- name: write the apache config file #每个task之间可以使用空行来做区分。
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
#需要说明的是缩进的意义和python中缩进的意义是一样,是来区分代码块的。
4、相关命令
#检测语法
ansible-playbook --syntax-check /path/to/playbook.yaml
#测试运行
ansible-playbook -C /path/to/playbook.yaml
#运行
ansible-playbook /path/to/playbook.yaml
5、课堂案例
需求1:使用playbook给tomcatServer主机创建用户及用户组(创建组httpd,创建用户httpd并指定主组为httpd)
mkdir /etc/ansible/playboot
cd /etc/ansible/playboot
vim sysuser.yaml
---
- hosts: tomcatServer
remote_user: root
tasks:
- name: create httpd group
group: name=httpd system=yes
- name: create httpd user
user: name=httpd system=yes group=httpd
ansible-playbook --syntax-check sysuser.yaml # 检查语法
ansible-playbook -C sysuser.yaml # 测试运行,并不会真正的执行,也就是不会创建用户
ansible-playbook sysuser.yaml # 执行



需求2:使用playbook给tomcatServer主机安装httpd,修改httpd监听的端口号为8080,并启动(ansible机器要准备一个httpd的配置文件)
vim httpd.yml
---
- hosts: tomcatServer
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
tags: install
- name: configure
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: configure
- name: start httpd service
service: name=httpd state=started enable=yes
tags: start
ansible-playbook httpd.yml
ansible-playbook -t start httpd.yml

需求3:在需求2的基础上使用模板(端口号跟Servername使用变量的方式,使用handlers重启httpd)
要使用模板的话,需要创建一个templates的目录,目录的层级关系为:
httpd-template.yaml templates httpd.conf.j2
vim httpd-template.yaml
---
- hosts: tomcatServer
remote_user: root
vars:
- port: 10087
- Servername: localhost
tasks:
- name: install httpd
yum: name=httpd
tags: install
- name: configure
template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
tags: configure
notify:
- restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
mkdir templates && cd templates && cp /etc/httpd/conf/httpd.conf ./httpd.conf.j2
vim httpd.conf.j2
Listen {{port}}
ServerName {{Servername}}:{{port}}
ansible-playbook -t configure httpd-template.yaml

6、课堂练习
需求3:playbook编排vsftpd,配置yum,安装vsftpd包,修改配置文件(要求拒绝匿名用户登录),启动服务并实现vsftpd服务开机自动启动
五、roles
1、概述
ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令引入即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。主要使用场景代码复用度较高的情况下。
2、目录结构

roles: <--所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在/etc/ansible/roles
project: <---具体的角色项目名称,比如nginx、tomcat、php
files: <--用来存放由copy模块或script模块调用的文件。
templates: <--用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。
tasks: <--此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
main.yml
handlers: <--此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
main.yml
vars: <--此目录应当包含一个main.yml文件,用于定义此角色用到的变量。
main.yml
defaults: <--此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。
main.yml
meta: <--此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。
main.yml
roles/example_role/files/ 所有文件,都将可存放在这里
roles/example_role/templates/ 所有模板都存放在这里
roles/example_role/tasks/main.yml: 主函数,包括在其中的所有任务将被执行
roles/example_role/handlers/main.yml:所有包括其中的 handlers 将被执行
roles/example_role/vars/main.yml: 所有包括在其中的变量将在roles中生效
roles/example_role/meta/main.yml: roles所有依赖将被正常登入
> 用不到的目录可以创建为空目录,也可以不创建
3、编写步骤
第1步: 创建roles目录及文件,并确认目录结构
第2步: 准备nginx服务器的主页文件
第3步: 编写nginx角色的main.yml文件
第4步: 编写nginx角色里的handler
4、课堂案例
需求:通过ansible的roles安装配置nginx服务
通过yum安装的nginx的配置目录为:/etc/nginx/nginx.conf
页面目录为:/usr/share/nginx/html
1. 在roles目录中创建目录及文件,并确认目录结构
cd /etc/ansible/roles/
mkdir -p nginx/{files,tasks,handlers,templates,vars}
touch nginx/{tasks,handlers,vars}/main.yml
yum install tree -y
tree /etc/ansible/roles/
├── nginx
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
│ └── main.yml
2. 在files目录中创建文件用于nginx页面部署,将yum镜像源相关的文件到files中
cd files
echo "hello roles; this is my first roles" > index.html
cp -r /etc/yum.repos.d/ /etc/ansible/roles/nginx/files/yum.repos.d
cp /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 /etc/ansible/roles/nginx/files/RPM-GPG-KEY-EPEL-7
3. 编辑vars/main.yml文件,定义nginx配置文件变量
vim main.yml
nginxPort: 8080
4. 将nginx配置文件拷贝到templates目录中,修改名称,并指定端口号从变量中读取
cp ~/nginx.conf /etc/ansible/roles/nginx/templates/nginx.conf.j2
cd /etc/ansible/roles/nginx/templates
vim nginx.conf.j2
server {
listen {{nginxPort}};
listen [::]:{{nginxPort}};
5. 编辑handlers/main.yml文件,定义启动,重启nginx
vim main.yml
---
- name: start nginx
service: name=nginx state=started
- name: restart nginx
service: name=nginx state=restarted
6. 编辑tasks/main.yml文件,编写剧本(同步yum,安装nginx,复制配置文件,定义nginx开机自启)
---
- name: remove repos
file: path=/etc/yum.repos.d/ state=absent
- name: nginx html
copy: src=/etc/ansible/roles/nginx/files/index.html dest=/usr/share/nginx/html/
- name: copy repos
copy: src=/etc/ansible/roles/nginx/files/yum.repos.d dest=/etc/
- name: copy epel key
copy: src=/etc/ansible/roles/nginx/files/RPM-GPG-KEY-EPEL-7 dest=/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
- name: install nginx
yum: name=nginx state=latest
- name: configure
template: src=/etc/ansible/roles/nginx/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify:
- restart nginx
- name: start enable nginx
service: name=nginx state=started enabled=yes
7. 在roles目录中创建nginx.yml文件,汇总其它文件,形成一个roles
cd /etc/ansible/roles
vim nginx.yml
---
- hosts: tomcatServer
remote_user: root
roles:
- nginx
8. 检测执行nginx.yml
ansible-playbook --syntax-check nginx.yml # 检查语法
ansible-playbook nginx.yml # 执行


5、课堂练习
需求:通过ansible的roles在host01,host02,host03主机上安装配置httpd服务
六、综合练习
需求:通过ansible实现多台机器lnmp项目的部署
课堂小结
-
ansible场景引入及常见的自动化运维工具
-
ansible概述及服务搭建
-
ansible主机清单功能实验
-
ansible常用模块使用实验
-
playbook功能使用
-
roles使用场景及具体使用
课后作业
-
完成课堂的案例及练习
-
将今天的内容整理为思维导图的形式
-
通过ansible实现多台机器lamp环境搭建,并实现discuz论坛项目部署(所有软件基于yum方式安装即可)
扩展内容
1、ansible的执行模式与执行流程?
执行模式:Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook
ad-hoc模式(点对点模式):
使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell
playbook模式(剧本模式):
是Ansible 主要管理方式 ,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件
执行流程:
简单理解就是Ansible在运行时, 首先读取ansible.cfg中的配置, 根据规则获取Inventory中的管理主机列表, 并行的在这些主机中执行配置的任务, 最后等待执行返回的结果
具体流程:
1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg;
2. 查找对应的主机配置文件,找到要执行的主机或者组;
3. 加载自己对应的模块文件,如 command;
4. 通过ansible将模块或命令生成对应的临时py文件(python脚本), 并将该文件传输至远程服务器;
5. 对应执行用户的家目录的.ansible/tmp/XXX/XXX.PY文件;
6. 给文件 +x 执行权限;
7. 执行并返回结果;
8. 删除临时py文件,sleep 0退出;
2、ansible有哪些常用的模块?具体如何使用?
Ansible 模块是 Ansible 提供的可用于执行特定任务的代码单元
常用的模块有:copy文件拷贝 yum软件安装与卸载 file文件管理 shell执行shell命令 user用户管理 service服务管理等
3、你用Ansible实现了什么功能?
1. 通过ansible批量jdk,nginx等软件的安装
2. 根据指定内容查找文件,统一处理。比如FastJson反序列化漏洞,通过'FastJson'关键字查找有无对应文件,如果有则进行整改
4、简单讲一下用Ansible在一百台机器上安装Nginx的过程?
1. 收集被管主机的信息(IP,账号,密码登)
2. 编写主机清单文件
3. 准备相关配置文件(yum源文件,nginx配置文件)
4. 编写playbook剧本,主要是以下几个方面(定义变量,yum配置,软件安装,基于模板的配置文件,服务管理等)
5. 修改nginx配置文件,通过变量获取数据
6. 检查剧本格式
7. 执行
8. 找其中一台主机确认结果