任务背景
公司的服务器越来越多, 维护⼀些简单的事情都会变得很繁琐。⽤
shell脚本来管理少量服务器效率还⾏, 服务器多了之后, shell脚本⽆
法实现⾼效率运维。这种情况下,我们需要引⼊⾃动化运维⼯具, 对
多台服务器实现⾼效运维。
任务要求任务要求
通过管理服务器能够按照需求灵活⾼效地管理所有应⽤服务器的运维
操作
任务拆解
1, 需要⼀台服务器做管理端, 来连接管理所有的应⽤服务器
2, 考虑如果只针对⼀部分应⽤服务器进⾏运维操作如何实现(服务器
分组)
3, 学会将平台烂熟于⼼的linux操作命令转化为⾃动化运维的⽅式(常
⻅模块的学习)
4, 如果操作⾮常的冗⻓, 学会使⽤playbook和role的⽅式来管理
学习⽬标学习⽬标
能够安装ansible服务器和客户端
能够定义ansible主机清单进⾏服务器分组
能够使⽤hostname模块修改主机名
√ 能够使⽤file模块做基本的⽂件操作
能够使⽤copy模块把⽂件拷⻉到远程机器
能够使⽤fetch模块把⽂件从远程拷⻉到本地
能够使⽤user模块管理⽤户
能够使⽤group模块管理⽤户组
能够使⽤cron模块管理时间任务
能够使⽤yum_repository模块配置yum
能够使⽤yum模块安装软件包
能够使⽤service模块控制服务的启动,关闭,开机⾃启动
能够使⽤script模块在远程机器上执⾏本地脚本
能够使⽤command与shell模块远程执⾏命令
能够编写playbook实现httpd
能够使⽤roles实现lamp⼀、认识⾃动化运维
问题:
假设我要去1000台服务上做⼀个操作(如nginx服务器修改配置⽂件
⾥的某⼀个参数), 下⾯两种⽅法缺点明显:
- 按传统的⽅法, ⼀台连着⼀台服务器的ssh上去⼿动操作。
缺点:
效率太低。 - 写个shell脚本来做。
缺点:
管理的机器平台不⼀致,脚本可能不具备通⽤性。
传密码麻烦(在⾮免密登录的环境下, 需要expect来传密码)
效率较低,循环1000次也需要⼀个⼀个的完成,如果⽤ & 符
放到后台执⾏,则会产⽣1000个进程。
⾃动化运维 : 将⽇常IT运维中⼤量的重复性⼯作,⼩到简单的⽇常检
查、配置变更和软件安装,⼤到整个变更流程的组织调度,由过去的
⼿⼯执⾏转为⾃动化操作,从⽽减少乃⾄消除运维中的延迟,实现
"零延时"的IT运维。⾃动化运维主要关注的⽅⾯
假如管理很多台服务器,主要关注以下⼏个⽅⾯: - 管理机与被管理机的连接(管理机如何将管理指令发送给被管理
机) - 服务器信息收集 (如果被管理的服务器有centos7.5外还有其它
linux发⾏版,如suse,ubuntu等。当你要做的事情在不同OS上有
所不同,你需要收集信息,并将其分开处理) - 服务器分组(因为有些时候我要做的事情不是针对所有服务器,
可能只针对某⼀个分组) - 管理内容的主要分类
⽂件⽬录管理(包括⽂件的创建,删除,修改,查看状态,远程拷⻉等)
⽤户和组管理
cron时间任务管理
yum源配置与通过yum管理软件包
服务管理
远程执⾏脚本
远程执⾏命令常⻅的开源⾃动化运维⼯具⽐较 - puppet(拓展)
基于ruby语⾔,成熟稳定。适合于⼤型架构,相对于ansible和
saltstack会复杂些。 - saltstack(拓展)
基于python语⾔。相对简单,⼤并发能⼒⽐ansible要好, 需要维
护被管理端的服务。如果服务断开,连接就会出问题。 - ansible
基于python语⾔。简单快捷,被管理端不需要启服务。直接⾛
ssh协议,需要验证所以机器多的话速度会较慢。
⼆、ansible⼆、ansible
ansible是⼀种由Python开发的⾃动化运维⼯具,集合了众多运维⼯
具(puppet、cfengine、chef、func、fabric)的优点,实现了批量
系统配置、批量程序部署、批量运⾏命令等功能。
特点:
部署简单
默认使⽤ssh进⾏管理,基于python⾥的paramiko模块开发
管理端和被管理端不需要启动服务配置简单,功能强⼤,扩展性强
能过playbook(剧本)进⾏多个任务的编排
ansible环境搭建
**实验准备:**三台机器,⼀台管理,两台被管理1. 静态ip - 主机名及主机名互相绑定
- 关闭防⽕墙, selinux
- 时间同步
- 确认和配置yum源(需要epel源)
实验过程:
第1步: 管理机上安装ansible,被管理节点必须打开ssh服务.# yum install epel-release
yum install ansible
ansible --version
ansible 2.8.4
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 30 2018,
23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
第2步: 实现master对agent的免密登录,只在master上做。(如果这
⼀步不做,则在后⾯操作agent时都要加-k参数传密码;或者在主机清
单⾥传密码)
master# ssh-keygen
master# ssh-copy-id -i 10.1.1.12
master# ssh-copy-id -i 10.1.1.13
第3步: 在master上定义主机组,并测试连接性master# vim /etc/ansible/hosts
[group1]
10.1.1.12
10.1.1.13
master# ansible -m ping group1
10.1.1.13 | SUCCESS => {
"changed": false,
"ping": "pong"
}
10.1.1.12 | SUCCESS => {
"changed": false,
"ping": "pong"
}
master# ansible -m ping all
10.1.1.13 | SUCCESS => {
"changed": false,
"ping": "pong"
}
10.1.1.12 | SUCCESS => {
"changed": false,
"ping": "pong"
}服务器分组
ansible通过⼀个主机清单功能来实现服务器分组。
Ansible的默认主机清单配置⽂件为/etc/ansible/hosts.
示例:
示例:
示例: 定义10.1.1.12:2222这台服务器的别名为nginx1
示例: 没有做免密登录的服务器可以指定⽤户名与密码
[nginx] 组名
apache[1:10].aaa.com 表示apache1.aaa.com
到apache10.aaa.com这10台机器
nginx[a:z].aaa.com 表示nginxa.aaa.com
到nginxz.aaa.com共26台机器
10.1.1.[11:15] 表示10.1.1.11到10.1.1.15这5台机器
[nginx]
10.1.1.13:2222 表示10.1.1.13这台,但ssh端⼝为2222
nginx1 ansible_ssh_host=10.1.1.13
ansible_ssh_port=2222nginx1 ansible_ssh_host=10.1.1.13
ansible_ssh_port=2222 ansible_ssh_user=root
ansible_ssh_pass="123456"
示例: 利⽤别名来分组
nginx1 ansible_ssh_host=10.1.1.13
ansible_ssh_port=2222 ansible_ssh_user=root
ansible_ssh_pass="123456"
nginx2 ansible_ssh_host=10.1.1.12
[nginx]
nginx1
nginx2
⼩结:
主机清单的作⽤: 服务器分组。
主机清单的常⻅功能:
- 可以通过IP范围来分, 主机名名字的范围来分
- 如果ssh端⼝不是22的,可以传⼊新的端⼝。
- 没有做免密登录,可以传密码。**练习:**不论你⽤哪种环境(免密或不免密,端⼝是否22), 请最终将两
台被管理机器加⼊到group1组即可
ansible模块
ansible是基于模块⼯作的,本身没有批量部署的能⼒。真正具有批
量部署的是ansible所运⾏的模块,ansible只是提供⼀种框架。
vim /etc/ansible/hosts
web01 ansible_ssh_host=192.168.71.200
ansible_ssh_user=root ansible_ssh_pass=root
ansible_ssh_port=22
web02 ansible_ssh_host=192.168.71.201
ansible_ssh_user=root ansible_ssh_pass=root
ansible_ssh_port=2222
[group1]
web01
web02
Ansbile 主机ip|域名|组名|别名 -m ping|copy|.... '参数'ansible⽀持的模块⾮常的多,我们并不需要把每个模块都记住,⽽
只需要熟悉⼀些常⻅的模块,其它的模块在需要⽤到时再查询即可。
查看所有⽀持的模块
ansible-doc -l
a10_server
Manage A10 Networks AX/SoftAX...
a10_server_axapi3
Manage A10 Networks AX/SoftAX...
a10_service_group
Manage A10 Networks AX/SoftAX...
a10_virtual_server
Manage A10 Networks AX/SoftAX...
aci_aaa_user
Manage AAA users (aaa:User)
。。。。。。
如果要查看ping模块的⽤法,使⽤下⾯命令(其它模块以此类推)
ansible-doc ping
官⽹模块⽂档地址: https://docs.ansible.com/ansible/latest/modules
/list_of_all_modules.htmlhostname模块
hostname模块⽤于修改主机名(注意: 它不能修改/etc/hosts⽂件)
https://docs.ansible.com/ansible/latest/modules/hostname_modul
e.html#hostname-module
将其中⼀远程机器主机名修改为agent1.cluster.com
file模块(重点)
file模块⽤于对⽂件相关的操作(创建, 删除, 软硬链接等)
https://docs.ansible.com/ansible/latest/modules/file_module.html#f
ile-module
创建⼀个⽬录
master# ansible 10.1.1.12 -m hostname -a
'name=agent1.cluster.com'
基本格式为: ansible 操作的机器名或组名 -m 模块名 -a "参数
1=值1 参数2=值2"
master# ansible group1 -m file -a 'path=/test
state=directory'创建⼀个⽂件
master# ansible group1 -m file -a 'path=/test/111
state=touch'
递归修改owner,group,mode
master# ansible group1 -m file -a 'path=/test
recurse=yes owner=bin group=daemon mode=1777'
删除⽬录(连同⽬录⾥的所有⽂件)
master# ansible group1 -m file -a 'path=/test
state=absent'
创建⽂件并指定owner,group,mode等
master# ansible group1 -m file -a 'path=/tmp/111
state=touch owner=bin group=daemon mode=1777'
删除⽂件
master# ansible group1 -m file -a 'path=/tmp/111
state=absent'
创建软链接⽂件创建硬链接⽂件
stat模块(了解)
stat模块类似linux的stat命令,⽤于获取⽂件的状态信息。
https://docs.ansible.com/ansible/latest/modules/stat_module.html
#stat-module
获取/etc/fstab⽂件的状态信息
copy模块(重点)
copy模块⽤于对⽂件的远程拷⻉操作(如把本地的⽂件拷⻉到远程
的机器上)
master# ansible group1 -m file -a 'src=/etc/fstab
path=/tmp/fstab state=link'
master# ansible group1 -m file -a 'src=/etc/fstab
path=/tmp/fstab2 state=hard'
master# ansible group1 -m stat -a 'path=/etc/fstab'https://docs.ansible.com/ansible/latest/modules/copy_module.htm
l#copy-module
在master上准备⼀个⽂件,拷⻉此⽂件到group1的所有机器上
master# echo master > /tmp/222
master# ansible group1 -m copy -a 'src=/tmp/222
dest=/tmp/333'
使⽤content参数直接往远程⽂件⾥写内容(会覆盖原内容)
master# ansible group1 -m copy -a 'content="ha
ha\n" dest=/tmp/333'
注意:ansible中-a后⾯的参数⾥也有引号时,记得要单引双引交叉
使⽤,如果都为双引会出现问题
使⽤force参数控制是否强制覆盖
如果⽬标⽂件已经存在,则不覆盖
master# ansible group1 -m copy -a 'src=/tmp/222
dest=/tmp/333 force=no'
如果⽬标⽂件已经存在,则会强制覆盖
master# ansible group1 -m copy -a 'src=/tmp/222
dest=/tmp/333 force=yes'
使⽤backup参数控制是否备份⽂件backup=yes表示如果拷⻉的⽂件内容与原内容不⼀样,则会备份⼀
份
group1的机器上会将/tmp/333备份⼀份(备份⽂件命名加上时
间),再远程拷⻉新的⽂件为/tmp/333
master# ansible group1 -m copy -a 'src=/etc/fstab
dest=/tmp/333 backup=yes owner=daemon group=daemon
mode=1777'
copy模块拷⻉时要注意拷⻉⽬录后⾯是否带"/"符号
/etc/yum.repos.d后⾯不带/符号,则表示
把/etc/yum.repos.d整个⽬录拷⻉到/tmp/⽬录下
master# ansible group1 -m copy -a
'src=/etc/yum.repos.d dest=/tmp/'
/etc/yum.repos.d/后⾯带/符号,则表示
把/etc/yum.repos.d/⽬录⾥的所有⽂件拷⻉到/tmp/⽬录下
master# ansible group1 -m copy -a
'src=/etc/yum.repos.d/ dest=/tmp/'
练习: 在master上配置好所有的yum源,然后拷⻉到group1的远程
机器上(要求⽬录内的内容完全⼀致)
master# ansible group1 -m file -a
"path=/etc/yum.repos.d/ state=absent"
master# ansible group1 -m copy -a
"src=/etc/yum.repos.d dest=/etc/"练习: 使⽤hostname模块修改过主机名后.在master上修
改/etc/hosts⽂件,并拷⻉到group1的远程机器上
关于DNS的补充:
域名为公⽹的唯⼀名字,主机名为内⽹的名字(可以重名,但最好不
要这么做)
⽬前⾃建DNS做域名解析已经很少了, 但可以通过DNS解析主机
名来实现内⽹多台服务器的解析
现在学了ansible的hostname与copy模块,轻松实现N多台服务器
的主机名管理,DNS也不需要再搭建了
template模块(拓展)
与copy模块功能⼏乎⼀样.
先在master上修改好/etc/hosts⽂件,然后使⽤下⾯命令拷⻉过去
覆盖
master# ansible group1 -m copy -a "src=/etc/hosts
dest=/etc/hosts"template模块⾸先使⽤变量渲染jinja2模板⽂件成普通⽂件,然后再复
制过去.⽽copy模块不⽀持.(jinja2是⼀个基于python的模板引擎)
https://docs.ansible.com/ansible/latest/modules/template_module.
html#template-module
template模块不能拷⻉⽬录
fetch模块
fetch模块与copy模块类似,但作⽤相反。⽤于把远程机器的⽂件拷
⻉到本地。
https://docs.ansible.com/ansible/latest/modules/fetch_module.htm
l#fetch-module
第1步: 在两台被管理机上分别创建⼀个同名⽂件(但内容不同)
master# ansible -m template group1 -a
"src=/etc/hosts dest=/tmp/hosts"
master# ansible -m template group1 -a
"src=/etc/yum.repos.d/ dest=/etc/yum.repos.d/"agent1# echo agent1 > /tmp/1.txt
agent2# echo agent2 > /tmp/1.txt
第2步: 从master上fecth⽂件(因为group1⾥有2台机器,为了避免同名
⽂件⽂件冲突,它使⽤了不同的⽬录)
master# ansible group1 -m fetch -a 'src=/tmp/1.txt
dest=/tmp/'
10.1.1.12 | CHANGED => {
"changed": true,
"checksum":
"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",
"dest": "/tmp/10.1.1.12/tmp/1.txt", 10.1.1.12
的在这⾥
"md5sum": "0d59da0b2723eb03ecfbb0d779e6eca5",
"remote_checksum":
"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",
"remote_md5sum": null
}
10.1.1.13 | CHANGED => {
"changed": true,
"checksum":
"b27fb3c4285612643593d53045035bd8d972c995",
"dest": "/tmp/10.1.1.13/tmp/1.txt", 10.1.1.13
的在这⾥
"md5sum": "cd0bd22f33d6324908dbadf6bc128f52","remote_checksum":
"b27fb3c4285612643593d53045035bd8d972c995",
"remote_md5sum": null
}
第3步: 先删除上⾯fetch过来的, 然后尝试只fetch其中⼀台机器的,
也会使⽤名称来做⼦⽬录区分
master# rm /tmp/10.1.1.* -rf
master# ansible 10.1.1.12 -m fetch -a
'src=/tmp/1.txt dest=/tmp/'
10.1.1.12 | CHANGED => {
"changed": true,
"checksum":
"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",
"dest": "/tmp/10.1.1.12/tmp/1.txt", 只fetch⼀
个,也会这样命名
"md5sum": "0d59da0b2723eb03ecfbb0d779e6eca5",
"remote_checksum":
"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",
"remote_md5sum": null
}
注意 : fetch模块不能从远程拷⻉⽬录到本地user模块
user模块⽤于管理⽤户账号和⽤户属性。
https://docs.ansible.com/ansible/latest/modules/user_module.html
#user-module
创建aaa⽤户,默认为普通⽤户,创建家⽬录
创建bbb系统⽤户,并且登录shell环境为/sbin/nologin
创建ccc⽤户, 使⽤uid参数指定uid, 使⽤password参数传密码
master# ansible group1 -m user -a 'name=aaa
state=present'
master# ansible group1 -m user -a 'name=bbb
state=present system=yes shell="/sbin/nologin"'master# echo 123456 | openssl passwd -1 -stdin
1DpcyhW2G$Kb/y1f.lyLI4MpRlHU9oq0
下⼀句命令注意⼀下格式,密码要⽤双引号引起来,单引号的话验证
时会密码不正确
master# ansible group1 -m user -a 'name=ccc
uid=2000 state=present
password="1DpcyhW2G$Kb/y1f.lyLI4MpRlHU9oq0"'
创建⼀个普通⽤户叫hadoop,并产⽣空密码密钥对
master# ansible group1 -m user -a 'name=hadoop
generate_ssh_key=yes'
删除aaa⽤户,但家⽬录默认没有删除
master# ansible group1 -m user -a 'name=aaa
state=absent'
删除bbb⽤户,使⽤remove=yes参数让其删除⽤户的同时也删除家⽬
录
master# ansible group1 -m user -a 'name=bbb
state=absent remove=yes'group模块
group模块⽤于管理⽤户组和⽤户组属性。
https://docs.ansible.com/ansible/latest/modules/group_module.ht
ml#group-module
创建组
删除组(如果有⽤户的gid为此组,则删除不了)
cron模块
cron模块⽤于管理周期性时间任务
https://docs.ansible.com/ansible/latest/modules/cron_module.html
#cron-module
master# ansible group1 -m group -a 'name=groupa
gid=3000 state=present'
master# ansible group1 -m group -a 'name=groupa
state=absent'创建⼀个cron任务,不指定user的话,默认就是root(因为我这⾥是⽤
root操作的)。
如果minute,hour,day,month,week不指定的话,默认都为*
删除cron任务
yum_repository模块
yum_repository模块⽤于配置yum仓库。
https://docs.ansible.com/ansible/latest/modules/yum_repository_m
odule.html
增加⼀个/etc/yum.repos.d/local.repo配置⽂件
master# ansible group1 -m cron -a 'name="test
cron1" user=root job="touch /tmp/111" minute=*/2'
master# ansible group1 -m cron -a 'name="test
cron1" state=absent'
master# ansible group1 -m yum_repository -a
"name=local description=localyum
baseurl=file:///mnt/ enabled=yes gpgcheck=no"删除/etc/yum.repos.d/local.repo配置⽂件
yum模块(重点)
yum模块⽤于使⽤yum命令来实现软件包的安装与卸载。
https://docs.ansible.com/ansible/latest/modules/yum_module.html
#yum-module
使⽤yum安装⼀个软件(前提:group1的机器上的yum配置都已经
OK)
使⽤yum安装httpd,httpd-devel软件,state=latest表示安装最新版本
注意:此模块只帮助配置yum仓库,但如果仓库⾥没有软件包,安装⼀
样会失败。所以可以⼿动去挂载光驱到/mnt⽬录
mount /dev/cdrom /mnt
master# ansible group1 -m yum_repository -a
"name=local state=absent"
master# ansible group1 -m yum -a 'name=vsftpd
state=present'使⽤yum卸载httpd,httpd-devel软件
service模块(重点)
service模块⽤于控制服务的启动,关闭,开机⾃启动等。
https://docs.ansible.com/ansible/latest/modules/service_module.ht
ml#service-module
启动vsftpd服务,并设为开机⾃动启动
关闭vsftpd服务,并设为开机不⾃动启动
master# ansible group1 -m yum -a 'name=httpd,httpd
devel state=latest'
master# ansible group1 -m yum -a 'name=httpd,httpd
devel state=absent'
master# ansible group1 -m service -a 'name=vsftpd
state=started enabled=on'
master# ansible group1 -m service -a 'name=vsftpd
state=stopped enabled=false'练习: 在group1的被管理机⾥的mariadb⾥创建⼀个abc库
练习:
假设我主机清单⾥定义的group1⾥有多台机器,它们现在要做⼀个
集群。此集群要求实现⼀个名为hadoop的普通⽤户之间的两两免密
登录,如何实现(要求只在master上进⾏操作)?
script模块
script模块⽤于在远程机器上执⾏本地脚本。
https://docs.ansible.com/ansible/latest/modules/script_module.ht
ml#script-module在master上准备⼀个脚本
master# vim /tmp/1.sh
#!/bin/bash
mkdir /tmp/haha
touch /tmp/haha/{1..10}
在group1的远程机器⾥都执⾏master上的/tmp/1.sh脚本(此脚本
不⽤给执⾏权限)
master# ansible group1 -m script -a '/tmp/1.sh'
扩展:使⽤shell脚本实现在group1的被管理机⾥的mariadb⾥创建⼀
个abc库command与shell模块
两个模块都是⽤于执⾏linux命令的,这对于命令熟悉的⼯程师来说,
⽤起来⾮常high。
shell模块与command模块差不多(command模块不能执⾏⼀些类似
$HOME,>,<,|等符号,但shell可以)
https://docs.ansible.com/ansible/latest/modules/command_modul
e.html
#!/bin/bash
yum install mariadb-server -y &> /dev/null
systemctl start mariadb
systemctl enable mariadb
mysql << EOF
create database abc;
quit
EOF
把上⾯的脚本使⽤script模块在group1被管理机⾥执⾏即可https://docs.ansible.com/ansible/latest/modules/shell_module.html
master# ansible -m command group1 -a "useradd
user2"
master# ansible -m command group1 -a "id user2"
master# ansible -m command group1 -a "cat
/etc/passwd |wc -l" --报错
master# ansible -m shell group1 -a "cat /etc/passwd
|wc -l" --成功
master# ansible -m command group1 -a "cd $HOME;pwd"
--报错
master# ansible -m shell group1 -a "cd $HOME;pwd"
--成功
注意: shell模块并不是百分之百任何命令都可以,⽐如vim或ll别名就不
可以。不建议⼤家去记忆哪些命令不可以,⼤家只要养成任何在⽣产
环境⾥的命令都要先在测试环境⾥测试⼀下的习惯就好。
三、playbook三、playbook
playbook(剧本): 是ansible⽤于配置,部署,和管理被控节点的剧本。⽤
于ansible操作的编排。
参考:https://docs.ansible.com/ansible/latest/user_guide/playbooks
_intro.html
使⽤的格式为yaml格式(saltstack,elk,docker,docker
compose,kubernetes等也都会⽤到yaml格式)
YMAL格式
以.yaml或.yml结尾
⽂件的第⼀⾏以 "---"开始,表明YMAL⽂件的开始(可选的)
以#号开头为注释
列表中的所有成员都开始于相同的缩进级别, 并且使⽤⼀个 "-
" 作为开头(⼀个横杠和⼀个空格)
⼀个字典是由⼀个简单的 键: 值 的形式组成(这个冒号后⾯必须
是⼀个空格)
注意: 写这种⽂件不要使⽤tab键,都使⽤空格参考: https://docs.ansible.com/ansible/latest/reference_appendices
/YAMLSyntax.html#yaml-syntax
下⾯看⼀个官⽅的示例感受⼀下
playbook实例
先直接来看⼀个实例
⼀位职⼯记录
name: Example Developer
job: Developer
skill: Elite
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
ruby: Elite
python: Elite
dotnet: Lame第1步: 创建⼀个存放playbook的⽬录(路径⾃定义)
master# mkdir /etc/ansible/playbook
第2步: 准备httpd配置⽂件,并修改成你想要的配置
master# yum install httpd -y
按需要修改你想要的配置(为了测试可以随意改动标记⼀下)
master# vim /etc/httpd/conf/httpd.conf
第3步: 写⼀个playbook⽂件(后缀为.yml或.yaml)
vim /etc/ansible/playbook/example.yaml
- hosts: group1
remote_user: root
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
notify:第4步: 执⾏写好的palybook
会显示出执⾏的过程,并且执⾏的每⼀步都有ok,changed,failed
等标识
执⾏如果有错误(failed)会回滚,解决问题后,直接再执⾏这条命
令即可,并会把failed改为changed(幂等性)
Playbook常⻅语法
hosts:⽤于指定要执⾏任务的主机,其可以是⼀个或多个由冒号分
隔主机组. - 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
ansible-playbook
/etc/ansible/playbook/example.yamlremote_user:⽤于指定远程主机上的执⾏任务的⽤户.
- hosts: group1
remote_user: root
**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也只会被执⾏⼀次.handlers最佳的应⽤场景是⽤来重启服务,或者触发系统重启操
作.除此以外很少⽤到了.
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
**练习:**修改httpd的端⼝为8080,再执⾏playbook测试
**variables:**变量
定义变量可以被多次⽅便调⽤案例: playbook编排vsftpd
写⼀个playbook实现
- 配置yum
- 安装vsftpd包
- 修改配置⽂件(要求拒绝匿名⽤户登录)
- 启动服务并实现vsftpd服务开机⾃动启动
master# vim /etc/ansible/playbook/example2.yaml
- hosts: group1
remote_user: root
vars: - user: test1
tasks: - name: create user
user: name={{user}} state=present
master# ansible-playbook
/etc/ansible/playbook/example2.yaml
- hosts: group1remote_user: root
tasks: - name: rm yum repository
file: path=/etc/yum.repos.d/ state=absent - name: 同步master上的yum源到group1
copy: src=/etc/yum.repos.d dest=/etc/ - name: ensure vsftpd is at the latest version
yum: name=vsftpd state=latest - name: write the apache config file
copy: src=/etc/vsftpd/vsftpd.conf
dest=/etc/vsftpd/vsftpd.conf
notify: - restart vsftpd
- name: ensure vsftpd is running (and enable it
at boot)
service: name=vsftpd state=started enabled=yes
handlers: - name: restart vsftpd
service: name=vsftpd state=restartedplaybook编排多个hosts任务
案例: 编排nfs搭建与客户端挂载
1, 在master上准备nfs配置⽂件
--- # ---代表开始(可选项,不写也可以) - hosts: 10.1.1.12
remote_user: root
tasks: - name: 创建/test1/⽬录
file: path=/test1/ state=directory
这⾥不能⽤---分隔,会报语法错误(后⾯课程玩k8s编排也写YAML
⽂件,是可以⽤---来分隔段落的)
- hosts: 10.1.1.13
remote_user: root
tasks: - name: 创建/test2/⽬录
file: path=/test2/ state=directory
... # ...代表结束(可选项,不写也可以)# vim /etc/exports
/share *(ro)
2, 编写yaml编排⽂件
vim /etc/ansible/playbook/nfs.yml
- hosts: 10.1.1.12
remote_user: root
tasks: - name: 安装nfs服务相关软件包
yum: name=nfs-utils,rpcbind,setup state=latest - name: 创建共享⽬录
file: path=/share/ state=directory - name: 同步nfs配置⽂件
copy: src=/etc/exports dest=/etc/exports
notify: restart nfs - name: 启动rpcbind服务,并设置为开机⾃启动
service: name=rpcbind state=started enabled=on - name: 启动nfs服务,并设置为开机⾃启动
service: name=nfs state=started enabled=onhandlers: - name: restart nfs
service: name=nfs state=restarted - hosts: 10.1.1.13
remote_user: root
tasks: - name: 安装nfs客户端软件包
yum: name=nfs-utils state=latest - name: 挂载nfs服务器的共享
shell: mount 10.1.1.12:/share /mnt
3, 执⾏playbook
ansible-playbook /etc/ansible/playbook/nfs.yaml
四、roles(难点)四、roles(难点)
roles介绍
roles(⻆⾊): 就是通过分别将variables, tasks及handlers等放置于单独
的⽬录中,并可以便捷地调⽤它们的⼀种机制。
假设我们要写⼀个playbook来安装管理lamp环境,那么这个
playbook就会写很⻓。所以我们希望把这个很⼤的⽂件分成多个功能
拆分, 分成apache管理,php管理,mysql管理,然后在需要使⽤的时候
直接调⽤就可以了,以免重复写。就类似编程⾥的模块化的概念,以
达到代码复⽤的效果。
创建roles的⽬录结构
files:⽤来存放由copy模块或script模块调⽤的⽂件。
tasks:⾄少有⼀个main.yml⽂件,定义各tasks。
handlers:有⼀个main.yml⽂件,定义各handlers。
templates:⽤来存放jinjia2模板。
vars:有⼀个main.yml⽂件,定义变量。
meta:有⼀个main.yml⽂件,定义此⻆⾊的特殊设定及其依赖关
系。**注意:**在每个⻆⾊的⽬录中分别创建files,
tasks,handlers,templates,vars和meta⽬录,⽤不到的⽬录可以创建
为空⽬录.
通过roles实现lamp
需定制三个⻆⾊: httpd,mysql,php
第1步: 创建roles⽬录及⽂件,并确认⽬录结构
master# cd /etc/ansible/roles/
master# mkdir -p
{httpd,mysql,php}/{files,tasks,handlers,templates,v
ars,meta}
master# touch
{httpd,mysql,php}/{tasks,handlers,vars,meta}/main.y
ml
master# yum install tree -y
master# tree /etc/ansible/roles/
/etc/ansible/roles/
"## httpd
$ "## files$ "## handlers
$ $ %## main.yml
$ "## meta
$ $ %## main.yml
$ "## tasks
$ $ %## main.yml
$ "## templates
$ %## vars
$ %## main.yml
"## mysql
$ "## files
$ "## handlers
$ $ %## main.yml
$ "## meta
$ $ %## main.yml
$ "## tasks
$ $ %## main.yml
$ "## templates
$ %## vars
$ %## main.yml
%## php
"## files
"## handlers
$ %## main.yml
"## meta
$ %## main.yml
"## tasks$ %## main.yml
"## templates
%## vars
%## main.yml
第2步: 准备httpd服务器的主⻚⽂件,php测试⻚和配置⽂件等
master# echo "test main page" >
/etc/ansible/roles/httpd/files/index.html
master# echo -e "<?php\n\tphpinfo();\n?>" >
/etc/ansible/roles/httpd/files/test.php
master# yum install httpd -y
按需求修改配置⽂件后,拷⻉到httpd⻆⾊⽬录⾥的files⼦⽬录
master# vim /etc/httpd/conf/httpd.conf
master# cp /etc/httpd/conf/httpd.conf
/etc/ansible/roles/httpd/files/
第3步: 编写httpd⻆⾊的main.yml⽂件
- name: 安装httpdyum: name=httpd,httpd-devel state=present
- name: 同步httpd配置⽂件
copy:
src=/etc/ansible/roles/httpd/files/httpd.conf
dest=/etc/httpd/conf/httpd.conf
notify: restart httpd - name: 同步主⻚⽂件
copy:
src=/etc/ansible/roles/httpd/files/index.html
dest=/var/www/html/index.html - name: 同步php测试⻚
copy:
src=/etc/ansible/roles/httpd/files/test.php
dest=/var/www/html/test.php - name: 启动httpd并开机⾃启动
service: name=httpd state=started enabled=yes
第4步: 编写httpd⻆⾊⾥的handlermaster# vim
/etc/ansible/roles/httpd/handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
第5步: 编写mysql⻆⾊的main.yml⽂件
- name: 安装mysql
yum: name=mariadb,mariadb-server,mariadb-devel
state=present - name: 启动mysql并开机⾃启动
service: name=mariadb state=started enabled=yes
第6步: 编写php⻆⾊的main.yml⽂件master# vim /etc/ansible/roles/php/tasks/main.yml
- name: 安装php及依赖包
yum: name=php,php-gd,php-ldap,php-odbc,php
pear,php-xml,php-xmlrpc,php-mbstring,php-snmp,php
soap,curl,curl-devel,php-bcmath,php-mysql
state=present
notify: restart httpd
第7步:编写lamp的playbook⽂件调⽤前⾯定义好的三个⻆⾊
master# vim /etc/ansible/playbook/lamp.yaml
- hosts: group1
remote_user: root
roles: - httpd
- mysql
- php
第8步: 执⾏lamp的playbook⽂件
master# ansible-playbook
/etc/ansible/playbook/lamp.yaml拓展案例: 通过roles实现lamp并安装
discuz
第1步: 创建roles⽬录及⽂件,并确认⽬录结构
第2步: 准备httpd相关⽂件
第3步: 编写httpd⻆⾊的main.yml⽂件
master# cd /etc/ansible/roles/
master# mkdir -p
{httpd,mysql,php}/{files,tasks,handlers,templates,v
ars,meta}
master# touch
{httpd,mysql,php}/{tasks,handlers,vars,meta}/main.y
ml
master# ls /etc/ansible/roles/httpd/files/
Discuz_X3.2_SC_UTF8.zip Discuz相关软件包
httpd.conf 配置好的httpd.conf配置⽂
件
master# vim /etc/ansible/roles/httpd/tasks/main.yml - name: 安装httpd相关软件包yum: name=httpd,httpd-devel state=latest
- name: 同步配置⽂件
copy:
src=/etc/ansible/roles/httpd/files/httpd.conf
dest=/etc/httpd/conf/httpd.conf
notify: restart httpd - name: 拷⻉discuz压缩包
copy:
src=/etc/ansible/roles/httpd/files/Discuz_X3.2_SC_U
TF8.zip dest=/tmp/ - name: 解压并mv⽹站⽂件到httpd家⽬录
shell: rm -rf /var/www/html/* && rm -rf /test/
&& mkdir -p /test/ && unzip
/tmp/Discuz_X3.2_SC_UTF8.zip -d /test/ &> /dev/null
&& mv /test/upload/* /var/www/html/ && chown -R
apache.apache /var/www/html/
上⾯的命令有点多,可以写成脚本,然后使⽤script模块来调⽤执
⾏
- name: 启动httpd并开机⾃启动
service: name=httpd state=started enabled=on第4步: 编写httpd⻆⾊⾥的handler
master# vim
/etc/ansible/roles/httpd/handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
第5步: 编写mysql⻆⾊的main.yml⽂件
master# vim /etc/ansible/roles/mysql/tasks/main.yml
- name: 安装mariadb相关软件包
yum: name=mariadb-server,mariadb-devel
state=latest - name: 启动mariadb服务并设置开机⾃启动
service: name=mariadb state=started enabled=on - name: 执⾏建库脚本
script: /etc/ansible/roles/mysql/files/create.sh
第6步: 编写mysql的建库脚本master# vim
/etc/ansible/roles/mysql/files/create.sh
#!/bin/bash
mysql << EOF
create database if not exists discuz default
charset=utf8;
grant all on discuz.* to 'discuz'@'localhost'
identified by '123';
flush privileges;
EOF
第7步: 编写php⻆⾊的main.yml⽂件
master# vim /etc/ansible/roles/php/tasks/main.yml
- name: 安装php相关软件包
yum: name=php,php-gd,php-ldap,php-odbc,php
pear,php-xml,php-xmlrpc,php-mbstring,php-snmp,php
soap,curl,curl-devel,php-bcmath,php-mysql
state=present
notify: restart httpd第8步:编写lamp的playbook⽂件调⽤前⾯定义好的三个⻆⾊
第9步: 执⾏lamp的playbook⽂件
练习
请使⽤role来实现lnmp
master# vim /etc/ansible/playbook/lamp.yaml
- hosts: group1
remote_user: root
roles: - httpd
- mysql
- php
master# ansible-playbook
/etc/ansible/playbook/lamp.yaml