- 前言
- 读者对象
- 如何阅读本书
- 勘误和支持
- 致谢
- 第 1 篇 高性能网站构建
- 第 1 章 深入理解 DNS 原理与部署 BIND
- 第 2 章 全面解析 CDN 技术与实战
- 第 3 章 负载均衡和高可用技术
- 第 4 章 配置及调优 LVS
- 第 5 章 使用 HAProxy 实现 4 层和 7 层代理
- 第 6 章 实践 Nginx 的反向代理和负载均衡
- 第 7 章 部署商业负载均衡设备 NetScaler
- 第 8 章 配置高性能网站
- 第 9 章 优化 MySQL 数据库
- 第 2 篇 服务器安全和监控
- 第 10 章 构建企业级虚拟专用网络
- 第 11 章 实施 Linux 系统安全策略与入侵检测
- 第 12 章 实践 Zabbix 自定义模板技术
- 第 13 章 服务器硬件监控
- 第 3 篇 网络分析技术
- 第 14 章 使用 tcpdump 与 Wireshark 解决疑难问题
- 第 15 章 分析与解决运营商劫持问题
- 第 16 章 深度实践 iptables
- 第 4 篇 运维自动化和游戏运维
- 第 17 章 使用 Kickstart 完成批量系统安装
- 第 18 章 利用 Perl 编程实施高效运维
- 第 19 章 精通 Ansible 实现运维自动化
- 第 20 章 掌握端游运维的技术要点
- 第 21 章 精通手游运维的架构体系
最佳实践 92:理解 Ansible
Ansible 作为目前非常流行运维自动化工具之一,它具有以下几个优点。
- 被管理节点无需安装客户端。
- 安装配置简单。
- 功能模块丰富。
- 可扩展性强,可自行开发功能模块。
- 使用简单的编排语言 yaml 完成一系列复杂的任务。
在运维的日常工作中,有很多烦琐重复的内容,比如,程序部署、文件更新、代码发布、日志分析等,这些事情会占用很多时间。最初都会采用一些脚本来完成这些事情,但是后来发现脚本越来越多,维护这些脚本也成为一个头疼的问题。运维自动化工具的出现,大大提高了效率,减少了花费在这些重复事情上的时间。
Ansible 可以说是其中的佼佼者之一。它引入了一种思想,将一系列小的任务,按想要的顺序编排在一起,完成复杂的功能。
Playbook(编排、剧本)就是这个思想的具体实现。标准化后的任务,编写成对应的 Playbook,可以非常方便地维护和反复使用。换句话说,同一件事,你只需编写一个 Playbook。执行一下,全部搞定,听着是不是感觉很有意思,下面我们就来朝着这个方向继续。
Ansible 安装及原理
如何安装 Ansible
Ansible 提供多种安装方式,针对不同的系统,包括(Redhat、Ubuntu、Gentoo、FreeBSD、Mac OSX)都提供了安装源及安装包。这些软件源上提供的版本都是近期的稳定版,所以并非最新版,通常情况下 Ansible 会每隔两个月分布一个版本,如果你想要安装最新的 Ansible 版本,可以使用 git 下载源代码并编译安装。
#git clone https://github.com/ansible/ansible.git #cd ansible;make rpm #cd rpm-build;ls *.rpm //编译完成之后,生成一个安装包和一个 rpm 源码包 ansible-2.1.0-0.git201603022253.171c925.devel.el6.noarch.rpm ansible-2.1.0-0.git201603022253.171c925.devel.el6.src.rpm # rpm -ivh ansible-2.1.0-0.git201603022253.171c925.devel.el6.noarch.rpm < -- 安装 ansible rpm 包-- > #ansible --version|head -n 1 //查看当前 ansible 版本为 2.1.0 ansible 2.1.0
注意
编译 ansible rpm 过程中需安装如下包,yum install-y asciidoc python-setuptools rpm-build python2-devel。安装 rpm 包也有一些依赖包需要提前安装:yum install PyYAML python-crypto2.6、python-httplib2 python-jinja2、python-keyczar python-paramiko python-six sshpass。某些包在 epel 源中,需先安装 epel 的源 rpm–ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm ,读者朋友的安装环境可能各有不同,笔者的编译安装环境是 CentOS 6.5 最小化安装,具体依赖也会在实际编译及安装过程中提示,按提示即可。
通过 yum 来直接安装 Ansible,需要先添加 epel 的 yum 源。
#rpm –ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm #yum install -y ansible #ansible --version ansible 1.9.4
安装完成之后会得到以下几个程序。
- ansible:执行 Ad-hoc(临时)任务,例如:获取系统运行时间。
ansible 192.168.1.1 -a ‘uptime’
- ansible-doc:查看模块信息及用法,例如:查看 copy 模块用法。
ansible -s copy
- ansible-galaxy:方便安装官方推荐的 Ansible roles。
Ansible roles 是在 Ansible1.2 中引入的特性,roles 采用层次化的目录,将变量、文件、模块、触发器放在不同的目录中,使结构更加清晰,每个 roles 下包括多个实际的任务。在 ansible-playbook 中可以方便地引用。官方推荐的 Ansible roles 在 https://galaxy.ansible.com/ 可以直接查找,例如:安装名为 bennojoy.nginx 的 Ansible roles。
ansible-galaxy install bennojoy.nginx
- ansible-playbook:读取并运行 Playbook 中定义的任务,例如:ansible-playbook site.yml。
- ansible-pull:切换 Ansible 模式,默认 Ansible 采用 push 模式。
- ansible-vaul:加密配置文件。
Ansible 原理与架构
Ansible 的工作原理是由 Ansible 核心模块默认通过 SSH 协议(同时支持 Kerberos 和 LDAP 轻量目录访问协议)将任务推送到被管理服务器执行,待执行完成之后自动删除任务并返回执行结果。
Ansible 的组成架构,如图 19-1 所示。
主要包括以下 6 个组件。
- Ansible 核心。
- Inventory 主机清单。
- Modules 模块。

图 19-1 Ansible 组成架构
- Playbook 剧本。
- Plugins 插件。
- 连接插件。
以下来逐一讲解各组件的功能和原理。
Ansible 核心:Ansible 提供了两种方式来执行任务。第一,直接用 Ansible 命令,这个命令是 Ansible 的指令核心,它用来执行 ad-hoc(笔者理解为临时的)命令,一般对于一些需要马上执行且简单的任务可以使用 ansible 命令来完成,例如:
#ansible webserver -m command -a "uptime"
命令中 webserver 表示执行这个任务的主机组,-m 之后是命令模块,-a 之后的模块中的参数。
第二,使用 ansible-playbook 命令,这个命令使用的最多,后面直接跟一个写好的 Playbook 文件,在 Playbook 中,可以定义非常复杂的任务。自动化运维,大部分是靠它来实现的,例如:
ansible-playbook webserver.yml
命令中 webserver.yml 是一个定义好的 Playbook。
Inventory 主机清单:也就是定义的被管理主机清单,在执行 Ansible 任务时,必须指明被管理的主机清单。默认在/etc/ansible/hosts 文件中定义,也可以使用-i/path/hosts 来指定主机清单文件的路径。
Modules 模块:Ansible 的模块分为三类:核心模块、扩展模块、自定义模块,在本章后面章节将做详细的介绍。
Playbook 剧本:Ansible 引入了 Playbook,在 Playbook 中可以将一个复杂的任务,非常清晰地表述出来。Playbook 采用 YAML(Yet Another Markup Language 另一种标记语言)格式编写。
Plugins 插件:插件是对 Ansible 功能的补充,比如日志、邮件功能。
连接插件:Ansible 默认使用 SSH 协议连接被管理服务器,并提供 4 种连接方式支持:OpenSSH,local(执行本地任务),paramiko(Python 的 SSH 连接库),zeromq(一个基于消息队列的多线程网络库)。在 Ansbile 1.3 之后默认会使用本地的 OpenSSH 连接被管理服务器,但是必须被管理的服务器的 OpenSSH 执行 ControlPersist(一个用于提升连接性能的参数)特性,该特性从 OpenSSH 5.6 之后提供支持,默认 RHEL 6.0,CentOS 6.0 中提供的版本较老(OpenSSH 5.3),并不支持 ControlPersist。所在 CentOS 6.0 系统中 Ansible 将继续使用 Python 的 SSH 连接库 paramiko 来提升性能,这也是 Ansible 1.3 之前默认采用的连接库。性能上支持 ControlPersist 的本地 OpenSSH 是 paramiko 的两倍左右。
此外,Ansible 还提供了一种特别的加速模式,为不支持 ControlPersist 特性的 OpenSSH 版本提供优化,在定义的 Playbook 中通过 accelerate:true 来开启该功能,该功能需要被管理服务器中安装 python-keyczar 包。
Ansible 配置项说明
Ansible 的配置文件的默认路径为/etc/ansible/ansible.cfg,配置文件格式,是通过分块来定义各项参数,以[分块名称]表示,一共包含以下几块。
- defaults:定义一些通用的配置参数,比如下面所列,就是常用的。
inventory = /etc/ansible/hosts //定义主机清单路径 forks = 5 //定义任务的并发数,默认是 5 个,执行时通过-f 指定 sudo_user = root //定义默认的 sudo 用户,默认为 root gathering = implicit <--!允许获取 facts 的值,如果定义为 explicit,将无法获取 setup 模块所能获取到的变量值!--> host_key_checking = False //关闭第一次连接系统是检查 keys 的提示 action_plugins = /usr/share/ansible_plugins/action_plugins callback_plugins = /usr/share/ansible_plugins/callback_plugins connection_plugins = /usr/share/ansible_plugins/connection_plugins lookup_plugins = /usr/share/ansible_plugins/lookup_plugins vars_plugins = /usr/share/ansible_plugins/vars_plugins filter_plugins = /usr/share/ansible_plugins/filter_plugins <--!定义各类插件的路径!--> fact_caching = memory //定义 fact 的缓存方式,可以选 memory 和 radis
- privilege_escalation:定义一些提升权限的参数,一般保持默认即可。
- paramiko_connection:定义 Python 的 paramiko 模块相关的配置优化参数,一般默认即可。
- ssh_connection:定义 SSH 配置参数。
pipelining = False //默认为 false,定义为 True 时,Ansible 通过管道的方式,减少在远程被管理机器上执行任务模块过程的 SSH 连接数量,来提高性能,注意,如果需要使用 sudo 切换用户的话,需要在被管理服务器/etc/sudoers 中定义 Disable requiretty
- accelerate:上一节介绍连接插件的时候,介绍 Ansible 对于 OpenSSH 不支持 ControlPersist 参数的情况下,提供了 accelerate 模式,在这个配置块中,定义具体的端口、超时时间等参数,一般默认即可。
- selinux:定义文件系统的安全上下文设置,正常情况下操作将复制现有的安全上下文或者使用用户默认,对于某些文件系统,需要文件依照该文件系统中的上下文权限来继承,默认的例外的文件系统是 nfs,vboxsf,fuse,ramfs,一般保持默认配置即可。
Inventory 定义格式
在使用 Ansible 命令执行操作时,可以使用-i 参数指定 inventory(主机清单)文件的路径,默认在 ansible.cfg 中定义的 inventory 路径为/etc/ansible/hosts。
在 inventory 中定义主机时,自由度非常高,Ansible 可以支持主机名、IP、主机分组、简单的正则、变量参数、主机分组之间的包含关系等。下面通过一个 inventory 文件来详细说明。
[dbservers] //定义一个主机组,执行任务时可以指定某个主机组。
db.example.com //定义被管理主机名称,注意该主机名需要能被 dns 解析为 IP 地址。
192.168.1.100 //定义被管理服务器的 IP 地址。
[gameservers]
gs[1:5] //使用通配符匹配主机,将包括 gs1,gs2...gs5。5 台主机。
192.168.2.[101:115] //定义主机 IP 地址时,也可以使用数字通配符。
[dnsservers]
dns.sh[a:b].example.com
<-! 支持字母匹配,得到两台主机 dns.sha.example.com,dns.shb.example.com !->
[test01]
192.168.2.103 ansible_connection=ssh ansible_ssh_user=root
ansible_ssh_pass=P@ssw0rd//为特定的参数赋值,此处定义了连接类型,ssh 用户名和密码。
192.168.2.104 vsftpd_port=2121 //自定义变量,在 playbook 中可以引用。
[test02]
192.168.2.105
192.168.2.106
[test02:vars] //为一组主机定义相同的变量参数
ansible_connection=ssh
ansible_ssh_user=root
ansible_ssh_pass=P@ssw0rd
[testserver:children] //定义主机组 testserver 其中包含 test01,test02 两个分组
test01
test02
注意
所有的主机都包含在 all 分组中,所以请慎用 ansible all-m modules 执行任务。
最后说明一下,inventory 定义中有常用的自带变量。
ansible_ssh_port: //定义连接主机的 ssh 端口 ansible_ssh_user: //定义连接到该主机的 ssh 用户 ansible_ssh_pass: //定义连接到该主机的 ssh 密码 ansible_sudo_pass: //定义 sudo 的密码 ansible_connection: //定义 ansibles 的连接类型,可以是 local、ssh 或 paramiko ansible_ssh_private_key_file: //定义私钥文件路径
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论