返回介绍

最佳实践 92:理解 Ansible

发布于 2025-04-20 17:44:53 字数 7794 浏览 0 评论 0 收藏

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: //定义私钥文件路径

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。