任务背景
公司的服务器越来越多 , 维护⼀些简单的事情都会变得很繁琐。⽤ 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 是⼀种由 Python 开发的⾃动化运维⼯具,集合了众多运维⼯具(puppet 、 cfengine 、 chef 、 func 、 fabric )的优点,实现了批量系统配置、批量程序部署、批量运⾏命令等功能。
特点 :
部署简单
默认使⽤ ssh 进⾏管理,基于 python ⾥的 paramiko 模块开发
管理端和被管理端不需要启动服务
配置简单,功能强⼤,扩展性强
能过 playbook( 剧本 ) 进⾏多个任务的编排
ansible 环境搭建
实验准备 : 三台机器,⼀台管理,两台被管理
- 静态 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.
示例 :
[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
示例 : 定义 10.1.1.12:2222 这台服务器的别名为 nginx1
nginx1 ansible_ssh_host= 10.1.1.13
ansible_ssh_port= 2222
示例 : 没有做免密登录的服务器可以指定⽤户名与密码
nginx1 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 组即可
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 是基于模块⼯作的,本身没有批量部署的能⼒。真正具有批量部署的是ansible 所运⾏的模块, ansible 只是提供⼀种框架。
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.html
hostname 模块
hostname 模块⽤于修改主机名( 注意 : 它不能修改 /etc/hosts ⽂件 )
https://docs.ansible.com/ansible/latest/modules/hostname_modul
e.html#hostname-module
将其中⼀远程机器主机名修改为 agent1.cluster.com
master # ansible 10.1.1.12 -m hostname -a
'name=agent1.cluster.com'
基本格式为 : ansible 操作的机器名或组名 -m 模块名 -a " 参数
1= 值 1 参数 2= 值 2"
file 模块 ( 重点 )
file 模块⽤于对⽂件相关的操作 ( 创建 , 删除 , 软硬链接等 )
https://docs.ansible.com/ansible/latest/modules/file_module.html#file-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'
创建软链接⽂件
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'
stat 模块 ( 了解 )
stat 模块类似 linux 的 stat 命令,⽤于获取⽂件的状态信息。
https://docs.ansible.com/ansible/latest/modules/stat_module.html
#stat-module
获取 /etc/fstab ⽂件的状态信息
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'
copy 模块 ( 重点 )
copy 模块⽤于对⽂件的远程拷⻉操作(如把本地的⽂件拷⻉到远程的机器上)
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 的远程机器上
先在 master 上修改好 /etc/hosts ⽂件,然后使⽤下⾯命令拷⻉过去
覆盖
master # ansible group1 -m copy -a "src=/etc/hosts
dest=/etc/hosts"
关于 DNS 的补充 :
域名为公⽹的唯⼀名字 , 主机名为内⽹的名字 ( 可以重名 , 但最好不要这么做)
⽬前⾃建 DNS 做域名解析已经很少了 , 但可以通过 DNS 解析主机名来实现内⽹多台服务器的解析
现在学了 ansible 的 hostname 与 copy 模块 , 轻松实现 N 多台服务器的主机名管理,DNS 也不需要再搭建了