Ansible自动化运维

  • 自动化运维工具简介
  • Puppet 自动运维工具特点:
  • Saltstack 自动运维工具特点:
  • Ansible 自动运维工具特点:
  • Ansible 运维工具原理
  • Ansible 管理工具安装配置
  • Ansible 工具参数详解
  • Ansible ping 模块实战
  • Ansible command 模块实战
  • Ansible copy 模块实战
  • Ansible yum 模块实战
  • Ansible file 模块实战
  • Ansible user 模块实战
  • Ansible cron 模块实战
  • Ansible synchronize 模块实战
  • Ansible shell 模块实战
  • Ansible service 模块实战
  • Ansible Playbook 应用
  • Ansible 配置文件详解
  • Ansible 性能调优



随着互联网 IT 运维飞速发展,目前市场上涌现了大量的自动化配置维护工具,例如 PSSH、Puppet、Chef、SaltStack、Ansible 等。目前互联网企业使用最多的两款自动化配置工具 Ansible 和 Saltstack。自动配置工具存在的初衷就是为了更方便、快捷的进行配置管理,它易于安装和使用、语法也非常简单易学。


本章向读者介绍 Ansible 工作原理、Ansible 安装配置、生产环境模块讲解、Ansible企业场景案例、PlayBook 剧本实战及 Ansible 性能调优等。

自动化运维工具简介

曾有媒体报道,Facebook 一个运维人员管理上万台服务器,如果使用手工的方法去维护是很难做到的,基于自动化工具就可以轻松的实现管理上万台、甚至十万台。
如下为 IT 运维主流自动化管理工具 Puppet、saltstack、Ansible 各自优缺点:

Puppet 自动运维工具特点:

Puppet 是早期的 Linux 自动化运维工具,是一种 Linux、Unix、Windows 平台的集中
配置管理系统,发展至今目前已经非常成熟,可以批量管理远程服务器,模块丰富,配
置复杂,基于 Ruby 语言编写。最典型的 C/S 模式,需要安装服务端与客户端。
puppet 采用 C/S 星状的结构,所有的客户端和一个或几个服务器交互,每个客户端
周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信
息同步。
每个 puppet 客户端每半小时(可以设置)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置客户端. 配置完成以后,puppet 客户端可以反馈给服务器端一个消息,如果出错也会给服务器端反馈一个消息。
Puppet 适用于服务器管理的整个过程,比如初始安装、配置、更新以及系统下线。

Saltstack 自动运维工具特点:

Saltstack 与 Puppet 均是 C/S 模式,需安装服务端与客户端,基于 Python 编写,加入 MQ 消息同步,可以使执行命令和执行结果高效返回,但其执行过程需等待客户端全部返回,如果客户端未及时返回或未响应的话,可能会导致部分机器没有执行结果。

Ansible 自动运维工具特点:

Ansible 与 Saltstack 均是基于 Python 语言开发,Ansible 只需要在一台普通的服务器上运行即可,不需要在客户端服务器上安装客户端。因为 Ansible 是基于 SSH 远程管理,而Linux服务器大都离不开SSH,所以Ansible不需要为配置工作添加额外的支持。
Ansible 安装使用非常简单,而且基于上千个插件和模块实现各种软件、平台、版本的管理,支持虚拟容器多层级的部署。很多读者在使用 Ansible 工具时,认为 Ansible比 Saltstatck 执行效率慢,其实不是软件本身慢,是由于 SSH 服务慢,可以优化 SSH 连接速度及使用 Ansible 加速模块,满足企业上万台服务器的维护和管理。

Ansible 运维工具原理

Ansible分为控制端和被控端,主要是基于SSH协议去管理客户端,被控端是无需安装Agent插件的,Ansible会读取控制端hosts文件,根据文件中定义IP列表信息,调取本地的各个模块对被控端机器实现批量、并发的配置管理和维护,如果任务比较复杂可以写成PlayBook剧本进行分发管理;

Ansible 自动运维管理工具优点:

❑ 轻量级,更新时,只需要在操作机上进行一次更新即可;

❑ 采用 SSH 协议;

❑ 不需要去客户端安装 agent;

❑ 批量任务执行可以写成脚本,而且不用分发到远程就可以执行;

❑ 使用 python 编写的,维护更简单;

❑ 支持 sudo 普通用户命令;

❑ 去中心化管理。

Ansible 自动运维管理工具工作原理拓扑,如图 21-1 所示:

自动化运维的框架 自动化运维技术栈_自动化运维的框架

Ansible 管理工具安装配置

Ansible 可以工作在 Linux、BSD、Mac OS X 等平台,对 Python 环境的版本最低要求为 Python2.6 以上,如果操作系统 Python 软件版本为 2.4,需要升级方可使用 Ansible工具。
Red Hat、CentOS 操作系统可以直接基于 YUM 工具自动安装 Ansible,CentOS6.x 或者 CentOS7.x 安装前,需先安装 epel 扩展源,代码如下:

rpm -Uvh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install epel-release -y
yum install ansible -y

Ansible 工具默认主目录为:/etc/ansible/,其中 hosts 文件为被管理机 IP 或者主机名列表,ansible.cfg 为 ansible 主配置文件,roles 为角色或者插件路径,默认该目录为空,如图所示:

自动化运维的框架 自动化运维技术栈_任务计划_02


Ansible 远程批量管理,其中执行命令是通过 Ad-Hoc 来完成,也即点对点单条执行命令,能够快速执行,而且不需要保存执行的命令。默认 hosts 文件配置主机列表,可以配置分组,可以定义各种 ip 及规则,hosts 列表默认配置如图 21-3 所示:

自动化运维的框架 自动化运维技术栈_Ansible_03


Ansible 基于多模块管理,常用的 Ansible 工具管理模块包括:command、shell、script、yum、copy、File、async、docker、cron、mysql_user、ping、sysctl、user、acl、add_host、easy_install、haproxy 等。

可以使用 ansible-doc –l|more 查看 ansible 支持的模块,也可以查看每个模块的帮助文档,ansible-doc module_name,如图 21-4 所示:

自动化运维的框架 自动化运维技术栈_任务计划_04

Ansible 工具参数详解

基于 Ansible 批量管理之前,需将被管理的服务器 IP 列表添加至/etc/ansible/hosts 文件中,如图 21-5 添加 4 台被管理端 IP 地址,分成 web 和 db 两组,本机也可以是被管理机。

自动化运维的框架 自动化运维技术栈_Ansible_05


基于 Ansible 自动运维工具管理客户端案例操作,由于 Ansible 管理远程服务器基于 SSH,在登录远程服务器执行命令时需要远程服务器的用户名和密码,也可以加入-k参数手动输入密码或者基于 ssh-keygen 生成免秘钥。

Ansible 自动化批量管理工具主要参数如下:

参数

注释

-v,–verbose

打印详细模式;

-i PATH,–inventory=PATH

指定 host 文件路径;

-f NUM,–forks=NUM

指定 fork 开启同步进程的个数,默认 5;

-m NAME,–module-name=NAME

指定 module 名称,默认模块 command;

-a MODULE_ARGS

module 模块的参数或者命令;

-k,–ask-pass

输入远程被管理端密码;

–sudo

基于 sudo 用户执行;

-K,–ask-sudo-pass

提示输入 sudo 密码与 sudo 一起使用;

-u USERNAME,–user=USERNAME

指定移动端的执行用户;

-C,–check

测试执行过程,不改变真实内容,相当于预演;

-T TIMEOUT,

执行命令超时时间,默认为 10 秒;

–version

查看 Ansible 软件版本信息。

Ansible ping 模块实战

Ansible 最基础的模块为 ping 模块,主要用于判断远程客户端是否在线,用于 ping本身服务器,返回值为 changed、ping。
(1) Ansible ping 服务器状态,如图所示:

ansible -k all -m ping

自动化运维的框架 自动化运维技术栈_客户端_06

Ansible command 模块实战

Ansible command 模块为 ansible 默认模块,主要用于执行 Linux 基础命令,可以执行远程服务器命令执行、任务执行等操作。
Command 模块使用详解:

Chdir

执行命令前,切换到目录;

Creates

当该文件存在时,则不执行该步骤;

Executable

换用 shell 环境执行命令;

Free_form

需要执行的脚本;

Removes

当该文件不存在时,则不执行该步骤;

Warn

如果在 ansible.cfg 中存在告警,如果设定了 False,不会警告此行。

Ansible command 模块企业常用案例如下:
(1) Ansible command 模块远程执行 date 命令,执行结果如图所示:

#Ansible command date 命令执行结果
ansible -k -i /etc/ansible/hosts all -m command -a "date"

自动化运维的框架 自动化运维技术栈_任务计划_07


(2) Ansible command 模块远程执行 ping 命令,执行结果如图所示:

# Ansible command ping 命令执行结果
ansible -k all -m command -a "ping -c 1 www.baidu.com"

自动化运维的框架 自动化运维技术栈_客户端_08


(3) Ansible Hosts 正则模式远程执行 df -h,执行结果如图所示:

# Ansible command df -h 命令执行结果
ansible -k 192.168.149.13* -m command -a "df -h"

自动化运维的框架 自动化运维技术栈_自动化运维的框架_09

Ansible copy 模块实战

Ansible copy 模块主要用于文件或者目录拷贝,支持文件、目录、权限、用户组功能,copy 模块使用详解:

src

Ansible 端源文件或者目录,空文件夹不拷贝;

content

用来替代 src,用于将指定文件的内容,拷贝到远程文件内;

dest

客户端目标目录或者文件,需要绝对路径;

backup

拷贝之前,先备份远程节点上的原始文件;

directory_mode

用于拷贝文件夹,新建的文件会被拷贝,而老旧的不会被拷贝;

follow

支持 link 文件拷贝;

force

覆盖远程主机不一致的内容;

group

设定远程主机文件夹的组名;

mode

指定远程主机文件及文件及的权限;

owner

设定远程主机文件夹的用户名。

Ansible copy 模块企业常用案例如下:
(1) Ansible copy 模块操作,src 表示源文件,dest 表示目标目录或者文件,owner
指定拥有者,执行结果如图所示:

#Ansible copy 拷贝文件
ansible -k all -m copy -a 'src=/etc/passwd dest=/tmp/ mode=755 owner=root'

自动化运维的框架 自动化运维技术栈_Ansible_10


(2) Ansible copy 模块操作,content 文件内容,dest 目标文件,owner 指定拥有者,执行结果如图所示:

# Ansible copy 追加内容
ansible -k all -m copy -a 'content="Hello World" dest=/tmp/jfedu.txt mode=755 owner=root'

自动化运维的框架 自动化运维技术栈_任务计划_11


(3) Ansible copy 模块操作,content 文件内容,dest 目标文件,owner 指定拥有者,backup=yes 开启备份,执行结果如图所示:

# Ansible copy 客户端备份结果
ansible -k all -m copy -a 'content="Hello World" dest=/tmp/jfedu.txt backup=yes mode=755 owner=root'

自动化运维的框架 自动化运维技术栈_客户端_12

Ansible yum 模块实战

Ansible yum 模块主要用于软件的安装、升级、卸载,支持红帽.rpm 软件的管理,YUM 模块使用详解:

conf_file

设定远程 yum 执行时所依赖的 yum 配置文件

disable_gpg_check

安装软件包之前是否坚持 gpg key;

name

需要安装的软件名称,支持软件组安装;

update_cache

安装软件前更新缓存;

enablerepo

指定 repo 源名称;

skip_broken

跳过异常软件节点;

state

软件包状态,包括:installed、present、latest、absent、removed。

Ansible yum 模块企业常用案例如下:
(1) Ansible yum 模块操作,name 表示需安装的软件名称,state 表示状态,常见state= installed 表示安装软件,执行结果如图所示:

#Ansible YUM 安装软件包
ansible all -k -m yum -a "name=sysstat,screen state=installed"

自动化运维的框架 自动化运维技术栈_Ansible_13


(2) Ansible yum 模块操作,name 表示需安装的软件名称,state 表示状态,常见state= installed 表示安装软件,执行结果如图 21-14 所示:

#Ansible YUM 卸载软件包
ansible all -k -m yum -a "name=sysstat,screen state=absent"

自动化运维的框架 自动化运维技术栈_客户端_14

(3) Ansible yum 模块操作,name 表示需安装的软件名称,state 表示状态,常见state= installed,表示安装软件,disable_gpg_check=no 不检查 key,执行结果如图所示:

#Ansible YUM 安装软件包,不检查 KEY
ansible 192.168.149.129 -k -m yum -a "name=sysstat,screen state=installed disable_gpg_check=no"

自动化运维的框架 自动化运维技术栈_自动化运维的框架_15

Ansible file 模块实战

Ansible file 模块主要用于对文件的创建、删除、修改、权限、属性的维护和管理,File 模块使用详解:

src

Ansible 端源文件或者目录;

follow

支持 link 文件拷贝;

force

覆盖远程主机不一致的内容;

group

设定远程主机文件夹的组名;

mode

指定远程主机文件及文件及的权限;

owner

设定远程主机文件夹的用户名;

path

目标路径,也可以用 dest,name 代替;

state

状态包括:file、link、directory、hard、touch、absent;

attributes

文件或者目录特殊属性。

Ansible file 模块企业常用案例如下:
(1) Ansible file 模块操作,path 表示目录的名称和路径, state=directory 表示
创建目录,执行结果如图所示:

#Ansible file 创建目录
ansible -k 192.168.* -m file -a "path=/tmp/`date +%F` state=directory
mode=755"

自动化运维的框架 自动化运维技术栈_任务计划_16


(2) Ansible file 模块操作,path 表示目录的名称和路径, state=touch 表示创建

文件,执行结果如图所示:

#Ansible file 创建文件
ansible -k 192.168.* -m file -a "path=/tmp/jfedu.txt state=touch mode=755"

自动化运维的框架 自动化运维技术栈_任务计划_17

Ansible user 模块实战

Ansible user 模块主要用于操作系统用户、组、权限、密码等操作,user 模块使用详解:

system

默认创建为普通用户,为yes则创建系统用户;

append

添加一个新的组;

comment

新增描述信息;

createhome

给用户创建家目录;

force

用于删除强制删除用户;

group

创建用户主组;

groups

将用户加入组或者附属组添加;

home

指定用户的家目录;

name

表示状态,是否 create、remove、modify;

password

指定用户的密码,此处为加密密码;

remove

删除用户;

shell

设置用户的 shell 登录环境;

uid

设置用户 id;

update_password

修改用户密码;

state

用户状态,默认为 present 表示新建用户。

Ansible user 模块企业常用案例如下:
(1) Ansible user 模块操作,name 表示用户名称,home 表示其家目录,执行结果如图所示:

#Ansible user 创建新用户
ansible -k 192.168.149.* -m user -a "name=jfedu home=/tmp/"

自动化运维的框架 自动化运维技术栈_Ansible_18


(2) Ansible user 模块操作,name 表示用户名称,home 表示其家目录,执行结果如图所示:

#Ansible user 指定 Shell 环境
ansible -k 192.168.149.* -m user -a "name=jfedu home=/tmp/ shell=/sbin/nologin"

自动化运维的框架 自动化运维技术栈_自动化运维的框架_19


(3) Ansible user 模块操作,name 表示用户名称,state=absent 表示删除用户,执行结果如图所示:

# Ansible user 删除用户
ansible -k 192.168.149.* -m user -a "name=jfedu state=absent force=yes"

自动化运维的框架 自动化运维技术栈_任务计划_20

Ansible cron 模块实战

Ansible cron 模块主要用于添加、删除、更新操作系统 Crontab 任务计划,Cron 模块使用详解:

name

任务计划名称;

cron_file

替换客户端该用户的任务计划的文件;

minute

分( 0-59 ,* ,*/2 );

hour

时( 0-23 ,* ,*/2 );

day

日( 1-31 ,* ,*/2 );

month

月( 1-12 ,* ,*/2 );

weekday

周( 0-6 或 1-7 ,* );

job

任何计划执行的命令,state 要等于 present;

backup

是否备份之前的任务计划;

user

新建任务计划的用户;

state

指定任务计划 present、absent。

Ansible cron 模块企业常用案例如下:
(1) Ansible cron 模块操作,基于 cron 模块,创建 crontab 任务计划,执行结果如图所示:

#Ansible cron 添加任务计划
ansible -k all -m cron -a "minute=0 hour=0 day=* month=* weekday=* name='Ntpdate server for sync time' job='/usr/sbin/ntpdate 139.224.227.121'"

自动化运维的框架 自动化运维技术栈_任务计划_21


(2) Ansible cron 模块操作,基于 cron 模块,备份 crontab 任务计划,backup=yes表示开启备份,备份文件存放于客户端/tmp/,执行结果如图所示:

# Ansible cron 删除任务计划
ansible -k all -m cron -a "minute=0 hour=0 day=* month=* weekday=* name='Ntpdate server for sync time' backup=yes job='/usr/sbin/ntpdate pool.ntp.org'"

自动化运维的框架 自动化运维技术栈_自动化运维的框架_22


(3) Ansible cron 模块操作,基于 cron 模块,删除 crontab 任务计划,执行结果如图

#Ansible cron 删除任务计划
ansible -k all -m cron -a "name='Ntpdate server for sync time' state=absent"

自动化运维的框架 自动化运维技术栈_Ansible_23

Ansible synchronize 模块实战

Ansible synchronize 模块主要用于目录、文件同步,基于 Rsync 命令同步目录,Synchronize 模块使用详解:

compress

开启压缩,默认为开启;

archive

是否采用归档模式同步,保证源和目标文件属性一致;

checksum

是否效验;

dirs

以非递归的方式传输目录;

links

同步链接文件;

recursive

是否递归 yes/no;

rsync_opts

使用 rsync 的参数;

copy_links

同步的时候是否复制连接;

delete

删除源中没有而目标存在的文件;

src

源目录及文件;

dest

目标目录及文件;

dest_port

目标接受的端口;

rsync_path

服务的路径,指定 rsync 命令来在远程服务器上运行;

rsync_timeout

指定 rsync 操作的 IP 超时时间;

set_remote_user

设置远程用户名;–exclude=.log 忽略同步.log 结尾的文件;

mode

同步的模式,rsync 同步的方式 PUSH、PULL,默认都是推送 push。

Ansible synchronize 模块企业常用案例如下:
(1) Ansible synchronize 模块操作,src 源目录、dest 目标目录,执行结果如图所示:

# Ansible 目录同步
ansible -k all -m synchronize -a 'src=/tmp/ dest=/tmp/'

自动化运维的框架 自动化运维技术栈_任务计划_24


(2) Ansible synchronize 模块操作,src 源目录、dest 目标目录、compress=yes开启压缩、delete=yes 数据一致、rsync_opts 同步参数、–exclude 排除文件,执行结果如图所示:

# Ansible 目录同步排除.txt 文件
ansible -k all -m synchronize -a 'src=/tmp/ dest=/tmp/ compress=yes delete=yes rsync_opts=--no-motd,--exclude=.txt'

自动化运维的框架 自动化运维技术栈_任务计划_25


(3)基于synchronize模块,将源目录同步至目标目录(增量同步):

ansible 192.168.0.2 -m synchronize -a 'src=/tmp/ dest=/tmp/'

(4)基于synchronize模块,将源目录同步至目标目录(完全同步):

ansible 192.168.0.2 -m synchronize -a 'src=/tmp/ dest=/tmp/ delete=yes'

Ansible shell 模块实战

Ansible shell 模块主要用于远程客户端上执行各种 Shell 命令或者运行脚本,远程执行命令通过/bin/sh 环境来执行,支持比 command 更多的指令,Shell 模块使用详解:

Chdir

执行命令前,切换到目录;

Creates

当该文件存在时,则不执行该步骤;

Executable

换用 shell 环境执行命令;

Free_form

需要执行的脚本;

Removes

当该文件不存在时,则不执行该步骤;

Warn

如果在 ansible.cfg 中存在告警,如果设定了 False,不会警告此行。

Ansible shell 模块企业常用案例如下:
(1) Ansible shell 模块操作,-m shell 指定模块为 shell,远程执行 Shell 脚本,远程执行脚本也可采用 script 模块。并把执行结果追加至客户端服务器/tmp/var.log 文件,执行结果如图所示:

#Ansible shell 远程执行脚本
ansible -k all -m shell -a "/bin/sh /tmp/variables.sh >>/tmp/var.log"

自动化运维的框架 自动化运维技术栈_任务计划_26


(2) Ansible shell 模块操作,远程执行创建目录命令,执行之前切换在/tmp 目录,屏蔽警告信息,执行结果如图所示:

# Ansible shell 远程执行脚本
ansible -k all -m shell -a "mkdir -p `date +%F` chdir=/tmp/ state=directory warn=no"

自动化运维的框架 自动化运维技术栈_自动化运维的框架_27


(3) Ansible shell 模块操作,-m shell 指定模块为 shell,远程客户端查看 http进程是否启动,执行结果如图所示:

#Ansible shell 远程查看进程
ansible -k all -m shell -a "ps -ef |grep http"

自动化运维的框架 自动化运维技术栈_任务计划_28


(4) Ansible shell 模块操作,-m shell 指定模块为 shell,远程客户端查看 crontab

任务计划,执行结果如图所示:

#Ansible shell 远程查看任务计划
ansible -k all -m shell -a "crontab -l"

自动化运维的框架 自动化运维技术栈_Ansible_29

Ansible service 模块实战

Ansible service 模块主要用于远程客户端各种服务管理,包括启动、停止、重启、
重新加载等,service 模块使用详解:

enabled

是否开启启动服务;

name

服务名称;

runlevel

服务启动级别;

arguments

服务命令行参数传递;

state

服务操作状态,状态包括 started, stopped, restarted,reloaded。

Ansible service 模块企业常用案例如下:
(1) Ansible service 模块操作,远程重启 httpd 服务,执行结果如图所示:

#Ansible service 重启 httpd 服务
ansible -k all -m service -a "name=httpd state=restarted"

自动化运维的框架 自动化运维技术栈_Ansible_30


(2) Ansible service 模块操作,远程重启网卡服务,指定参数 eth0,执行结果如图所示:

#  Ansible service 重启 network 服务
ansible -k all -m service -a "name=network args=eth0 state=restarted"

自动化运维的框架 自动化运维技术栈_Ansible_31


(3) Ansible service 模块操作,远程开机启动 nfs 服务,设置 3,5 级别自动启动,执行结果如图所示:

#Ansible service 开机启动 nfs 服务
ansible -k all -m service -a "name=nfs enabled=yes runlevel=3,5"

自动化运维的框架 自动化运维技术栈_Ansible_32

Ansible Playbook 应用

如上使用 Ad-hoc 方式点对点命令执行,可以管理远程主机,如果服务器数量很多,配置信息比较多,还可以利用 Ansible Playbook 编写剧本、从而以非常简便的方式实现任务处理的自动化与流程化。
Playbook 由一个或多个"play"组成的列表,play 的主要功能 Ansible 中的 Task 定义好的角色,指定剧本对应的服务器组。
从根本上说,Task 是一个任务,Task 调用 Ansible 各种模块 module,将多个 paly组织在一个 playbook 剧本中,然后组成一个非常完整的流程控制集合。
基于 Ansible Playbook 还可以收集命令、可以创建任务集,这样能够大大降低管理工作的复杂程度,Playbook 采用 YAML 语法结构,易于阅读、方便配置。
YAML(Yet Another Markup Language),是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。它参考了其它多种语言,包括:XML、C 语言、Python、Perl 以及电子邮件格式 RFC2822,是类似于标准通用标记语言的子集 XML 的数据描述语言,语法比 XML简单很多。

YAML 使用空白字符和分行来分隔资料,适合用 grep、Python、Perl、Ruby 操作。
(1) YAML 语言特性如下:
❑ 可读性强;
❑ 和脚本语言的交互性好;
❑ 使用实现语言的数据类型;
❑ 一致的信息模型;
❑ 易于实现;
❑ 可以基于流来处理;
❑ 可扩展性强。
(2) Playbooks 组件包括如下:

Target

定义 playbook 的远程主机组;

Variable

定义 playbook 使用的变量;

Task

定义远程主机上执行的任务列表;

Handler

定义 task 执行完成以后需要调用的任务,例如配置文件被改动,则启动 handler 任务重启相关联的服务。

(3) Target 常用参数如下:

hosts

定义远程主机组;

user

执行该任务的用户;

sudo

设置为 yes 的时候,执行任务的时候使用 root 权限;

sudo_user

指定 sudo 普通用户;

connection

默认基于 SSH 连接客户端;

gather_facks

获取远程主机 facts 基础信息。

(4) Variable 常用参数如下:

vars

定义格式,变量名:变量值;

vars_files

指定变量文件;

vars_prompt

用户交互模式自定义变量;

setup

模块去远程主机的值;

(5) Task 常用参数如下:

name

任务显示名称也即屏幕显示信息;

action

定义执行的动作;

copy

复制本地文件到远程主机;

template

复制本地文件到远程主机,可以引用本地变量;

service

定义服务的状态。

Ansible playbook 案例演示如下:
(1) 远程主机安装 Nginx WEB 服务,playbook 代码如下,执行结果如图所示:

# Ansible Playbook 远程 Nginx 安装
- hosts:all
remote_user:root
tasks:
- name:Jfedu Pcre-devel and Zlib LIB Install.
yum:name=pcre-devel,pcre,zlib-devel state=installed
- name:Jfedu Nginx WEB Server Install Process.
shell:cd /tmp; rm -rf nginx-1.16.0.tar.gz; wget http://nginx.org/download/nginx-1.16.0.tar.gz;tar xzf nginx-1.16.0.tar.gz;
cd nginx-1.16.0;./configure --prefix=/usr/local/nginx;make;make install

自动化运维的框架 自动化运维技术栈_自动化运维的框架_33


(2) 检测远程主机 Nginx 目录是否存在,不存在则安装 Nginx WEB 服务,安装完并启动 Nginx,playbook 代码如下,执行结果如图所示:

# Ansible Playbook Nginx 触发安装
- hosts:all
remote_user:root
tasks:
- name:Nginx server Install 2020
file:path=/usr/local/nginx/ state=directory
notify:
- nginx install
- nginx start
handlers:
- name:nginx install
shell:cd /tmp; rm -rf nginx-1.16.0.tar.gz; wget http://nginx.org/download/nginx-1.16.0.tar.gz;tar xzf nginx-1.16.0.tar.gz;cd nginx-1.16.0;./configure --prefix=/usr/local/nginx;make;make install
- name:nginx start
shell:/usr/local/nginx/sbin/nginx

自动化运维的框架 自动化运维技术栈_自动化运维的框架_34


(3) 检测远程主机内核参数配置文件是否更新,如果更新则执行命令 sysctl –p 使内核参数生效,playbook 代码如下,执行结果如图所示:

#Ansible Playbook 内核参数优化
- hosts:all
remote_user:root
tasks:
- name:Linux kernel config 2017
copy:src=/data/sh/sysctl.conf dest=/etc/
notify:
- source sysctl
handlers:
- name:source sysctl
shell:sysctl -p

自动化运维的框架 自动化运维技术栈_Ansible_35


(4)基于列表 items 多个值创建用户,通过{{}}定义列表变量,with_items 选项传

入变量的值,执行结果如图 21-36(a)、21-36(b)所示:

# Ansible Playbook item 变量创建用户
- hosts: all
remote_user: root
tasks:
- name: Linux system Add User list.
user: name={{ item }} state=present
with_items:
- jfedu1
- jfedu2
- jfedu3
- jfedu4

自动化运维的框架 自动化运维技术栈_Ansible_36


(5) Ansible Playbook 可以自定义 template 模板文件,模板文件主要用于服务器需求不一致的情况,需要独立定义的,例如两台服务器安装了 Nginx,安装完毕之后将服务器 A 的 HTTP 端口改成 80,服务器 B 的 HTTP 端口改成 81,基于 tempalte 模块轻松实现,方法步骤如下:

  1. Ansible hosts 文件指定不同服务器不同 httpd_port 端口,代码如下:
[web]
192.168.149.128 httpd_port=80
192.168.149.129 httpd_port=81
  1. Ansible 创建 nginx.conf jinja2 模板文件,cp nginx.conf nginx.conf.j2,
    并修改 listen 80 为 listen {{httpd_port}},Nginx 其他配置项不变,代码如
    下:
cp nginx.conf nginx.conf.j2
listen {{httpd_port}};
  1. Ansible playbook 剧本 yaml 文件创建,代码如下:
- hosts:all
remote_user:root
tasks:
- name:Nginx server Install 2017
file:path=/usr/local/nginx/ state=directory
notify:
- nginx install
- nginx config
handlers:
- name:nginx install
shell:cd /tmp ; rm -rf nginx-1.16.0.tar.gz ; wget http://nginx.org/download/nginx-1.16.0.tar.gz;tar xzf nginx-1.16.0.tar.gz;cd nginx-1.16.0;./configure --prefix=/usr/local/nginx;make;make install
- name:nginx config
template:src=/data/sh/nginx.conf.j2
dest=/usr/local/nginx/conf/nginx.conf
  1. Ansible playbook 执行剧本文件,如图 21-37(a)、21-37(b)、21-37(c)所
    示:
    Ansible Playbook 执行模板 yaml

    149.128 服务器 Nginx HTTP Port 80

    149.129 服务器 Nginx HTTP Port 81

Ansible 配置文件详解

Ansible 默认配置文件为/etc/ansible/ansible.cfg,配置文件中可以对 ansible进行各项参数的调整,包括并发线程、用户、模块路径、配置优化等,如下为 Ansible.cfg
常用参数详解:

[defaults]

通用默认配置段;

inventory = /etc/ansible/hosts

被控端 IP 或者 DNS 列表;

library = /usr/share/my_modules/

Ansible 默认搜寻模块的位置;

remote_tmp = $HOME/.ansible/tmp

Ansible 远程执行临时文件;

pattern = *

对所有主机通信;

forks = 5

并行进程数;

poll_interval = 15

回频率或轮训间隔时间;

sudo_user = root

sudo 远程执行用户名;

ask_sudo_pass = True

使用 sudo,是否需要输入密码;

ask_pass = True

是否需要输入密码;

transport = smart

通信机制;

remote_port = 22

远程 SSH 端口;

module_lang = C

模块和系统之间通信的语言;

gathering = implicit

控制默认 facts 收集(远程系统变量);

roles_path= /etc/ansible/roles

用于 playbook 搜索 Ansible roles;

host_key_checking = False

检查远程主机密钥;

#sudo_exe = sudo sudo

远程执行命令;

#sudo_flags = -H

传递 sudo 之外的参数;

timeout = 10 SSH

超时时间;

remote_user = root

远程登陆用户名;

log_path = /var/log/ansible.log

日志文件存放路径;

module_name = command Ansible

命令执行默认的模块;

#executable = /bin/sh

执行的 Shell 环境,用户 Shell 模块;

#hash_behaviour = replace

特定的优先级覆盖变量;

#jinja2_extensions

允许开启 Jinja2 拓展模块;

#private_key_file = /path/to/file

私钥文件存储位置;

#display_skipped_hosts = True

显示任何跳过任务的状态;

#system_warnings = True

禁用系统运行 ansible 潜在问题警告;

#deprecation_warnings = True

Playbook 输出禁用“不建议使用”警告;

#command_warnings = False

command 模块 Ansible 默认发出警告;

#nocolor = 1

输出带上颜色区别,开启/关闭:0/1;

pipelining = False

开启 pipe SSH 通道优化;

[accelerate]

accelerate 缓存加速。

accelerate_port = 5099

accelerate_timeout = 30

accelerate_connect_timeout = 5.0

accelerate_daemon_timeout = 30

accelerate_multi_key = yes

Ansible 性能调优

Ansible 企业实战环境中,如果管理的服务器越来越多,Ansibe 执行效率会变得比较慢,可以通过优化 Ansible 提供工作效率,由于 Ansible 基于 SSH 协议通信,SSH 连接慢会导致整个基于 Ansible 执行变得缓慢,也需要对 Openssh 进行优化,具体优化的方法如下:
(1) Ansible SSH 关闭秘钥检测
默认以 SSH 登录远程客户端服务器,会检查远程主机的公钥(public key),并将该主机的公钥记录在~/.ssh/known_hosts 文件中。下次访问相同主机时,OpenSSH 会核对公钥,如果公钥不同,OpenSSH 会发出警告,如果公钥相同,则提示输入密码。
SSH对主机的public_key的检查等级是根据StrictHostKeyChecking变量来设定的StrictHostKeyChecking 检查级别包括:no(不检查)、ask(询问)、yes(每次都检查)、False(关闭检查)。
Ansible 配置文件中加入如下代码,即可关闭 StrictHostKeyChecking 检查:

host_key_checking = False

2) OpenSSH 连接优化
使用 OpenSSH 服务时,默认服务器端配置文件 UseDNS=YES 状态,该选项会导致服务器根据客户端的 IP 地址进行 DNS PTR 反向解析,得到客户端的主机名,然后根据获取到的主机名进行 DNS 正向 A 记录查询,并验证该 IP 是否与原始 IP 一致。关闭 DNS 解析代码如下:

sed -i '/^GSSAPI/s/yes/no/g; /UseDNS/d; /Protocol/aUseDNS no' /etc/ssh/sshd_config
/etc/init.d/sshd restart

(3) SSH pipelining 加速 Ansible
SSH pipelining 是一个加速 Ansible 执行速度的简单方法,SSH pipelining 默认是关闭的,关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。
如果不使用 Sudo 建议开启该选项,打开此选项可以减少 Ansible 执行没有文件传输时,SSH 在被控机器上执行任务的连接数。使用 Sudo 操作的时候, 必须在所有被管理的主机上将配置文件/etc/sudoers 中 requiretty 选项禁用。

sed -i '/^pipelining/s/False/True/g' /etc/ansible/ansible.cfg

(4) Ansible Facts 缓存优化
Ansible-playbook 在执行过程中,默认会执行 Gather facts,如果不需要获取客户端的 fact 数据的话,可以关闭获取 fact 数据功能,关闭之后可以加快 ansible-playbook的执行效率。如需关闭 fact 功能,在 playbook yaml 文件中加入如下代码即可:

gather_facts: nogather_facts: no

Ansible facts 组件主要用于收集客户端设备的基础静态信息,这些信息可以在做配置管理的时候方便引用。Facts 信息直接当做 Ansible Playbook 变量信息进行引用,通过定制 facts 以便收集我们想要的信息,同时可以通过 Facter 和 Ohai 来拓展 facts 信息,也可以将 facts 信息存入 Redis 缓存中,如下为 Facts 使用 Redis 缓存的步骤

  1. 部署 Redis 服务
wget http://download.redis.io/releases/redis-2.8.13.tar.gz
tar zxf redis-2.8.13.tar.gz
cd redis-2.8.13
make PREFIX=/usr/local/redis install
cp redis.conf /usr/local/redis/

将/usr/local/redis/bin/目录加入至环境变量配置文件/etc/profile 末尾,然后
Shell 终端执行 source /etc/profile 让环境变量生效。

export PATH=/usr/local/redis/bin:$PATH

启动及停止 Redis 服务命令:

nohup /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf &
  1. 安装 Python Redis 模块
easy_install pip
pip install redis
  1. Ansible 整合 Redis 配置
    在配置文件/etc/ansible/ansible.cfg 中 defaluts 段中加入代码,如果 redis 密码为 admin,则开启 admin 密码行:
gathering = smart
fact_caching = redis
fact_caching_timeout = 86400
fact_caching_connection = localhost:6379
#fact_caching_connection = localhost:6379:0:admin
  1. 测试 Redis 缓存
    Ansible-playbook 执行 nginx_wget.yaml 剧本文件,如图 21-38 所示:
ansible-playbook nginx_wget.yaml

ansible playbook 执行 yaml

自动化运维的框架 自动化运维技术栈_自动化运维的框架_37


检查 Redis 服务器,facts key 已存入 Redis 中,如图 21-39 所示:

Redis 缓存服务器缓存 facts 主机信息

自动化运维的框架 自动化运维技术栈_任务计划_38


(5) ControlPersist SSH 优化

ControlPersist 特性需要高版本的 SSH 支持,CentOS6 默认是不支持的,如果需要

使用,需要自行升级 Openssh。

ControlPersist 即持久化的 Socket,一次验证多次通信。并且只需要修改 SSH 客户端配置,也即 Ansible 被管理主机。

可使用 YUM 或者源码编译升级 OpenSSH 服务,升级完毕 ControlPersist 的设置办法如下,在其用户的家目录创建 config 文件,如果 ansible 以 root 用户登录客户端,至需要在客户端的/root/.ssh/config 目录中添加如下代码即可:

Host *
Compression yes
ServerAliveInterval 60
ServerAliveCountMax 5
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 4h

开启 ControlPersist 特性后,SSH 在建立 sockets 后,节省了每次验证和创建的时间,对 Ansible 执行速度提升是非常明显的。