前言

即使是在传统的企业当中,日常的备份、服务器状态监控和日志,通过手动的方式来进行的效率也很低,是一种人力的浪费。因此,自动化早已是每个运维都必须掌握的看家本领。

在不同的企业中,自动化的规模、需求与实现方式都各不相同,因此在技术细节层面,运维之间很难将别的企业的方法整个套用过来。然而在很多情况下,自动化的思路是有共通之处的。

运维自动化前三阶段

◆纯手工阶段:手工操作重复地进行软件部署和运维。

◆脚本阶段:通过编写脚本、方便地进行软件部署和运维。

◆工具阶段:借助第三方工具高效、方便地进行软件部署和运维。

这几个阶段是随着运维知识、经验、教训不断积累而不断演进的。而且,第2个阶段和第3个阶段可以说是齐头并进,Linux下的第三方工具虽说已经不少了,但是Linux下的脚本编写对运维工作的促进作用是绝对不可以忽视的。

在DevOps出现之前,运维工作者在工作中还是以这两种方式为主。

下面的研究,都是一些linux下开源的第三方工具,借助第三方工具高效、方便地进行软件部署和运维。

运维自动化工具介绍

在日常服务器维护中,从系统安装到程序部署再到发布应用,在大规模的生产环境中,如果需要手动的每台服务器进行安装配置将会给运维人员带来许多繁琐而又重复的工作。这就促使了在每个运维层次中出现了不同的自动化运维工具。
常见的自动化运维工具分类有以下几类:

系统安装运维工具(OS Provisioning):

常见的有:PXE,Cobbler,Red Hat Satelite(redhat)系统专用等


操作系统的配置运维工具(OS Config):

常见的有:cfengine,puppet,saltsack,chef等


应用程序部署工具(Application Service Orchestration):

常见的有:Func,Fabric,ControITier,Capistrano等


根据工作模式不同上面的运维工具有分为以下两类:

agent:基于ssl协议实现,agent工作在被监控端,例如:puppet,saltstack
agentless: 基于ssh key实现,例如:ansible


选择Ansible的原因:

Puppet 和 SaltStack 我曾用过,但不是十分符合预期,所以先行排除。至于 Chef,虽然老早就听说过,但却一直没有找到机会尝试。翻了翻文档,Chef 跟 Puppet 及 SaltStack 也是一样采用服务端/客户端模式,对于在现有一定数量的机器上部署仍然有  些麻烦。最后落单到 Ansible 上。经过对 Ansible 的把玩,我感觉 Ansible 于我比较相投。我喜欢 Ansible 的方面包括:

  • 充分利用现有设施。使用 Ansible 无需安装服务端和客户端,只要 SSH 即可。这意味着,任何一台装有 Ansible 的机器都可以成为强大的管理端。我觉得,这种去中心化的思路显得更为灵活。可能有人会担心 SSH 的效率,Ansible 的并行执行及加速模式或许可以打消你的顾虑。

  • 使用简单,快速上手相当容易。我在用 Puppet 之前,就没少花时间钻研它。想想吧,我们使用这类自动化管理工具不就是想把自己从重复的、复杂的事情中解放出来么?为了简化一件事,而沉入另一件复杂的事,是不是有些不划算?从我的体验来看,Ansible 上手十分快,用 Ad-Hoc 可以应付简单的管理任务,麻烦点的也可以定义 Playbook 文件来搞定。

  • 采用人类易读的格式。Ansible 的主机定义文件使用 INI 格式,支持分组,能够指定模式;此外也能动态生成,这对管理云主机应当很有用。而 Playbook 则是 YAML 格式,我觉得它比 Puppet 的 DSL 要易读易写多了。

  • 能够使用你熟悉的语言来编写模块。虽然 Ansible 是使用 Python 开发的,但它不会将你限制到某种具体的编程语言,Bash、Python、Perl、Ruby 等等都可以,你擅长什么就用什么。

一言以蔽之,Ansible 背后的简单化哲学深得我心。这也比较符合我选择软件的一贯原则。可能还有人会比较关心目前 Ansible 都有谁在用。毕竟,榜样的力量是无穷。Puppet 不正是因为 Google 在用而吸引了不少眼球么?据我所知,当前使用 Ansible 较为知名的用户包括 Fedora、Rackspace、Evernote 等等。



对管理主机的要求


目前,只要机器上安装了 Python 2.6 或 Python 2.7 (windows系统不可以做控制主机),都可以运行Ansible.
主机的系统可以是 Red Hat, Debian, CentOS, OS X, BSD的各种版本,等等.

对节点主机的要求


通常我们使用 ssh 与托管节点通信,默认使用 sftp.如果 sftp 不可用,可在 ansible.cfg 配置文件中配置成 scp 的方式. 在托管节点上也需要安装 Python 2.4 或以上的版本.如果版本低于 Python 2.5 ,还需要额外安装一个模块:

python-simplejson

Ansible 与其它配置管理的对比


选择了目前几款主流的与 Ansible 功能类似的配置管理软件 Puppet、Saltstack,这里所做的对比不针对各个软件的性能作比较,只是对各个软件的特性做个对比。


Puppet Saltstack Ansible
开发语言 Ruby Python Python
是否有客户端
是否支持二次开发 不支持 支持 支持
服务器与远程机器是否相互验证
服务器与远程机器通信是否加密 是,标准 SSL 协议 是,使用 AES 加密 是,使用 OpenSSH
平台支持 支持 AIX、BSD、HP-UX、Linux、 MacOSX、Solaris、 Windows 支持 BSD、Linux、Mac OS X、Solaris、 Windows 支持 AIX、BSD、 HP-UX、 Linux、Mac OSX、Solaris
是否提供 web ui    提供 提供 提供,不过是商业版本
配置文件格式 Ruby 语法格式 YAML YAML
命令行执行 不支持,但可通过配置模块实现 支持 支持



Ansible基本架构

  Ansible 是一个模型驱动的配置管理器,支持多节点发布、远程任务执行。默认使用 SSH 进行远程连接。无需在被管理节点上安装附加软件,可使用各种编程语言进行扩展。


上图为ansible的基本架构,从上图可以了解到其由以下部分组成:

远程调用管理模块,从Inventory里调用主机名字
ansible特性
    基于python语言实现, 模块化 设计 ,调用特定的模块来完成特定任务 ,本身是核心组件,短小精悍 。
    由Paramiko来实现创建ssh连接,基于ssh协议连接每一个被管理主机
    YAML格式是基于PyYAML模块来实现功能的,因为这个模块还支持模板语言,所以还需要jinjia2模板语言
    由Paramiko,PyYAML和Jinjia2三个关键模块;

(1)、no agents:部署简单,不需要在被管控主机上安装任何客户端;

(2)、no server:无服务器端,使用时直接运行命令即可;

(3)、modules in any languages:支持自定义模块,基于“模块”完成各种“任务”,支持各种可使用任意语言开发模块;

(4)、yaml,not code:使用yaml语言定制剧本playbook;

(5)、ssh by default:,使用SSH协议并基于SSH工作((1) 基于密钥认证;(2) 在inventory文件中指定账号和密码);

(6)、strong multi-tier solution:可实现多级指挥。

Ansible 工作机制

Ansible 在管理节点将 Ansible 模块通过 SSH 协议(或者 Kerberos、LDAP)推送到被管理端执 行,执行完之后自动删除,可以使用 SVN 等来管理自定义模块及编排

 

1、管理端支持local 、ssh、zeromq 三种方式连接被管理端,默认使用基于ssh的连接---这部分对应基本架构图中的连接模块;

2、可以按应用类型等方式进行Host Inventory(主机群)分类,管理节点通过各类模块实现相应的操作---单个模块,单条命令的批量执行,我们可以称之为ad-hoc;

3、管理节点可以通过playbooks 实现多个task的集合实现一类功能,如web服务的安装部署、数据库服务器的批量备份等。playbooks我们可以简单的理解为,系统通过组合多条ad-hoc操作的配置文件 。

ansible的任务执行流程

(1)读取配置

(2)抓取全量机器&分组列表

       可从多个静态文件、文件夹、脚本中读取机器,分组及其变关联量信息。

(3)使用host-pattern过滤机器列表

(4)根据参数确定执行模块和配置

       从modules目录动态读取,用户可以自行开发模块。

(5)Runner执行返回

       Connection环节定义连接方式 => Action阶段机器列表(Lookup plugin Action变量/文件等资源的获取)

       Callback plugin各阶段的钩子调用

(6)输出结束

       Filter plugin过滤算子

       Callback plugin各阶段的钩子调用

 

Ansible—轻量级的自动化部署工具

Ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。

ansible是基于模块工作的ansible本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块ansible只是提供一种框架。架构包括

连接插件connection plugins负责和被监控端实现通信。

Host Inventory:指定操作的主机,是一个配置文件里面定义监控的主机

各种模块核心模块command模块自定义模块

借助于插件完成记录日志邮件等功能

PlayBooks:剧本执行多个任务时。并非必需可以让节点一次性运行多个任务

Ansible的优点

优点:

应用代码自动化部署。
系统管理配置自动化。
支持持续交付自动化。
支持云计算、大数据平台(如AWS、OpenStack、VMWare等)环境。
轻量级,无需在客户端安装agent,更新时只需在控制机上进行一次更新即可。
批量任务执行可以写成脚本,不用分发到远程就可以执行。
使用Python编写,维护更简单,Ruby语法过于复杂。
支持非root用户管理操作,支持sudo。

Ansible 结合 Docker、Mesos、Puppet、Vagrant、Git 等系统可以构建出非常好的自动化运维平台。Ansible 比起其他自动化运维工具更适合对 Docker 实例进行维护和管理。如果你的机器实例数量超过 1000,也可以选择Ansible 的 Web 控制工具 Ansible Tower 。


安装配置


安装包:

[root@John src]# wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
[root@John src]# wget https://pypi.python.org/packages/source/s/setuptools/setuptools-7.0.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/p/pycrypto/pycrypto-2.6.1.tar.gz
[root@John src]# wget http://pyyaml.org/download/libyaml/yaml-0.1.5.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.11.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/M/MarkupSafe/MarkupSafe-0.9.3.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.7.3.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/e/ecdsa/ecdsa-0.11.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/p/paramiko/paramiko-1.15.1.tar.gz
[root@John src]# wget https://pypi.python.org/packages/source/s/simplejson/simplejson-3.6.5.tar.gz
[root@John src]# wget http://releases.ansible.com/ansible/ansible-2.0.0.0.tar.gz


安装:
python2.7安装
[root@John src]# tar zxvf Python-2.7.8.tgz
[root@John src]# cd Python-2.7.8
[root@John Python-2.7.8]# ./configure --prefix=/usr/local/
[root@John Python-2.7.8]# make && make install
[root@John Python-2.7.8]# python -V
Python 2.7.8
setuptools模块安装
[root@John src]# tar zxvf setuptools-7.0.tar.gz
[root@John src]# cd setuptools-7.0
[root@John setuptools-7.0]# python setup.py install


pycrypto模块安装
[root@John src]# tar zxvf pycrypto-2.6.1.tar.gz
[root@John src]# cd pycrypto-2.6.1
[root@John pycrypto-2.6.1]# python setup.py install


PyYAML模块安装
[root@John src]# tar zxvf yaml-0.1.5.tar.gz
[root@John src]# cd yaml-0.1.5
[root@John yaml-0.1.5]# ./configure  --prefix=/usr/local/
[root@John yaml-0.1.5]# make && make install

[root@John src]# tar zxvf PyYAML-3.11.tar.gz
[root@John src]# cd PyYAML-3.11
[root@John PyYAML-3.11]# python setup.py install


Jinja2模块安装
[root@John src]# tar zxvf MarkupSafe-0.9.3.tar.gz ^C
[root@John src]# cd MarkupSafe-0.9.3
[root@John MarkupSafe-0.9.3]# python setup.py install


paramiko模块安装
[root@John src]# tar zxvf ecdsa-0.11.tar.gz
[root@John src]# cd ecdsa-0.11
[root@John ecdsa-0.11]# python setup.py install

[root@John src]# tar zxvf paramiko-1.15.1.tar.gz 
[root@John src]# cd paramiko-1.15.1
[root@John paramiko-1.15.1]# python setup.py  install


simplejson模块安装
[root@John src]# tar zxvf simplejson-3.6.5.tar.gz
[root@John src]# cd simplejson-3.6.5
[root@John simplejson-3.6.5]# python setup.py install


ansible安装
[root@John src]# tar zxvf ansible-2.0.0.0.tar.gz ^C
[root@John src]# cd ansible-2.0.0.0
[root@John ansible-2.0.0.0]# python setup.py install

[root@John ansible-2.0.0.0]# mkdir /etc/ansible/
[root@John ansible-2.0.0.0]# cp -rp examples/*  /etc/ansible/

YUM安装

[root@John src]# wget -O /etc/yum.repos.d/epel.repo  http://mirrors.aliyun.com/repo/epel-6.repo
[root@John src]# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto ansible        #需epel源



配置文件

/etc/ansible/ansible.cfg
主机清单:
/etc/ansible/hosts
角色目录:
 /etc/ansible/roles
插件目录:
/usr/share/ansible_plugins/


报错:

[root@John ansible-2.0.0.0]# ansible test -m command -a 'ls /home'
/usr/local/lib/python2.7/site-packages/Crypto/Util/number.py:57: PowmInsecureWarning: Not using mpz_powm_sec.  You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.
  _warn("Not using mpz_powm_sec.  You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning)
192.168.159.2 | SUCCESS | rc=0 >>
www
wwwlogs
wwwroot

192.168.159.3 | SUCCESS | rc=0 >>
www

rc=0 返回值

 解决方法:

打开 /usr/lib64/python2.6/site-packages/Crypto/Util/number.py 文件,可以 看到 56 行上的注释说明,要求 libgmp 为 v5 以上版本。而系统现有版本为 4.1.4,把以下两行暂时注释掉,Ansible 执行正常。
不过,此方法只是临时加以解决,更好的方式是去将 libgmp 升级到符合要求的版本。libgmp包去网上找

命令格式

#常用格式
ansible  [-f forks] [-m module] [-a args]
host-pattern # 可以是all,或者配置文件中的主机组名
-f forks # 指定并行处理的进程数
-m module # 指定使用的模块,默认模块为command
-a args # 指定模块的参数
#查看各模块
ansible-doc [options] [modules]
# 主要选项有:
-l或--list # 列出可用的模块
-s或--snippet #显示指定模块的简略使用方法


Ansible命令参数介绍

-v,–verbose   详细模式,如果命令执行成功,输出详细的结果(-vv –vvv -vvvv)
-i PATH,–inventory=PATH   指定host文件的路径,默认是在/etc/ansible/hosts 
-f NUM,–forks=NU  NUM是指定一个整数,默认是5,指定fork开启同步进程的个数。 
-m NAME,–module-name=NAME   指定使用的module名称,默认是command
-m DIRECTORY,–module-path=DIRECTORY   指定module的目录来加载module,默认是/usr/share/ansible, 
-a,MODULE_ARGS   指定module模块的参数 
-k,-ask-pass     提示输入ssh的密码,而不是使用基于ssh的密钥认证
-sudo                   指定使用sudo获得root权限
-K,-ask-sudo-pass       提示输入sudo密码,与–sudo一起使用 
-u USERNAME,-user=USERNAME  指定移动端的执行用户 
-C,-check               测试此命令执行会改变什么内容,不会真正的去执行


主机清单介绍hosts

Ansible 通过读取默认的主机清单配置/etc/ansible/hosts,可以同时连接到多个远程主机上执行任务,默认路径可以通过修改 ansible.cfg 的 hostfile 参数指定路径。

[dbserver]  []表示主机的分组名,可以按照功能,系统进行分类,便于进行操作
192.168.10.2 
one.example.com 
www.bds.com:5309         #支持指定ssh端口5309 
jumper ansible_ssh_port=5309 ansible_ssh_host=192.168.10.2   #设置主机别名为jumper
www[01:50].bds.com       #支持通配符匹配www01.bds.com www02.bds.com
[web]                    #提醒下这里面字母是随便定义的
web-[a:f].bds.com        #支持字母匹配 web-a.bds.com ..web-f.bds.com

为主机指定类型和连接用户

[bds]
Localhost  ansible_connection=local
other1.example.com ansible_connection=ssh ansible_ssh_user=deploy
other2.example.com ansible_connection=ssh ansible_ssh_user=deploy
ansible hosts配置文件中支持指令

注意: 前面如果不配置主机免密钥登录,可以在/etc/ansible/hosts中定义用户和密码,主机ip地址,和ssh端口,这样也可以进行免密码访问,但是这个/hosts文件要保护好,因为所有的密码都写在里面

hosts文件配置参数介绍

1, ansible_ssh_host :
指定主机别名对应的真实 IP,如:100 ansible_ssh_host=192.168.1.100,随后连接该主机无须指定完整 IP,只需指定 251 就行
2, ansible_ssh_port :
指定连接到这个主机的 ssh 端口,默认 22
3, ansible_ssh_user:
连接到该主机的 ssh 用户
4, ansible_ssh_pass:
连接到该主机的 ssh 密码(连-k 选项都省了),安全考虑还是建议使用私钥或在命令行指定-k 选项输入
5, ansible_sudo_pass:                              sudo 密码
6, ansible_sudo_exe:                                sudo 命令路径
7, ansible_connection :
连接类型,可以是 local、ssh 或 paramiko,ansible1.2 之前默认为 paramiko
8, ansible_ssh_private_key_file :               私钥文件路径
9, ansible_shell_type  :
目标系统的 shell 类型,默认为 sh,如果设置 csh/fish,那么命令需要遵循它们语法
10, ansible_python_interpreter  :
python 解释器路径,默认是/usr/bin/python,但是如要要连BSD系统的话,就需要该指令修改 python 路径
11, ansible__interpreter  :
这里的"*"可以是 ruby 或 perl 或其他语言的解释器,作用和 ansible_python_interpreter 类似



实现基于ssh密钥通信

[root@John ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
ad:c8:99:6b:70:b2:c0:10:2e:4b:c7:68:52:2d:17:e0 root@John
The key's randomart p_w_picpath is:
+--[ RSA 2048]----+
|  .o..           |
|..o o            |
|.oEo             |
|+= o     .       |
|=+.     S .      |
|. o o..+ .       |
|   . == .        |
|    . ..         |
|     ..          |
+-----------------+
[root@John ~]# chmod 700 /root/.ssh

[root@John ~]# cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keys
[root@John ~]# chmod 600 /root/.ssh/authorized_keys

rsync -av /root/.ssh [email protected]:/root/

Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts

配置文件:ansible.cfg,hosts
 #cat /etc/ansible/ansible.cfg   主配置文件,可以根据实际应用自行修改

[defaults]
# some basic default values...
hostfile       = /etc/ansible/hosts   \\指定默认hosts配置的位置
# library_path = /usr/share/my_modules/  
remote_tmp     = $HOME/.ansible/tmp
pattern        = *
forks          = 5
poll_interval  = 15
sudo_user      = root  \\远程sudo用户
#ask_sudo_pass = True  \\每次执行ansible命令是否询问ssh密码
#ask_pass      = True  \\每次执行ansible命令时是否询问sudo密码
transport      = smart
remote_port    = 22
module_lang    = C
gathering = implicit
host_key_checking = False    \\关闭第一次使用ansible连接客户端是输入命令提示
log_path    = /var/log/ansible.log \\需要时可以自行添加。chown -R root:root ansible.log
system_warnings = False    \\关闭运行ansible时系统的提示信息,一般为提示升级
  
# set plugin path directories here, separate with colons
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
  
[accelerate]
accelerate_port = 5099
accelerate_timeout = 30
accelerate_connect_timeout = 5.0
# The daemon timeout is measured in minutes. This time is measured
# from the last activity to the accelerate daemon.
accelerate_daemon_timeout = 30

#cat /etc/ansible/hosts  主机清单信息配置文件,可以自定义主机,支持IP,域名,支持分组

[host01]  \\分组名,[]表示主机的分组名,可以按照功能、系统等进行分类,便于对某些主机或者某一组功能相同的主机进行操作
10.11.8.21 ansible_ssh_user=root ansible_ssh_pass=Passwd     \\远程ip,ssh登录用户,密码 
10.11.8.28 ansible_ssh_user=root ansible_ssh_pass=GxwLaXOs&1SK
10.10.30.50                \\若主机间进行的秘钥通信,则只需要添加主机 ip 就行了
[host02]
10.11.2.28
  
[web]
10.11.0.25
10.11.0.26
[web:var]            \\统一对web组设置变量
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=123456
 
[db]
10.11.1.10
test ansible_ssh_port=5555 ansible_ssh_host=10.11.15    \\设置主机别名为 test
10.11.1.11:2156                   \\指定ssh端口
www[001:006].example.com          \\支持通配符 www001 www002 ..
new-[a:f]-node.example.com        \\支持字母匹配 new-a-node.example.com new-b-node.example.com ...
  
[server:children]   \\组可以包含其它组
web
db
[test]        
host01
host02

hosts 文件支持一些特定指令,所有支持的指令如下:

ansible_ssh_host:指定主机别名对应的真实 IP,如:251 ansible_ssh_host=183.60.41.251,随后连接该主机无须指定完整 IP,只需指定 251 就行
ansible_ssh_port:指定连接到这个主机的 ssh 端口,默认 22
ansible_ssh_user:连接到该主机的 ssh 用户
ansible_ssh_pass:连接到该主机的 ssh 密码(连-k 选项都省了),安全考虑还是建议使用私钥或在命令行指定-k 选项输入
ansible_sudo_pass:sudo 密码
ansible_sudo_exe(v1.8+的新特性):sudo 命令路径
ansible_connection:连接类型,可以是 local、ssh 或 paramiko,ansible1.2 之前默认为 paramiko
ansible_ssh_private_key_file:私钥文件路径
ansible_shell_type:目标系统的 shell 类型,默认为 sh,如果设置 csh/fish,那么命令需要遵循它们语法
ansible_python_interpreter:python 解释器路径,默认是/usr/bin/python,但是如要要连*BSD系统的话,就需要该指令修改 python 路径
ansible_*_interpreter:这里的"*"可以是 ruby 或 perl 或其他语言的解释器,作用和 ansible_python_interpreter 类似
例子:
  some_host ansible_ssh_port=2222 ansible_ssh_user=manager
  aws_host ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
  freebsd_host ansible_python_interpreter=/usr/local/bin/python
  ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3


主机清单示例

www.example.com # FQDN

[webservers] # 方括号[]中是组名
host1
host2:8888  # 指定连接主机得端口号
localhost ansible_connection=local # 定义连接类型
host3 http_port=80 maxRequestsPerChild=808 # 定义主机变量
host4 ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50 # 定义主机ssh连接端口和连接地址
www[1:50].example.com # 定义 1-50范围内的主机
www-[a:f].example.com # 定义a-f范围内内的主机

[dbservers]
www.example.com     ansible_python_interpreter=/usr/local/bin/python #定义python执行文件
192.168.159.3     ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3 # 定义ruby执行文件

[webservers:vars]  # 定义webservers组的变量
ntp_server= ntp.example.com
proxy=proxy.example.com


[server:children] # 定义server组的子成员
webservers
dbservers

[server:vars] # 定义server组的变量
zabbix_server:192.168.159.2

Inventory 参数的说明


主机连接:

参数 说明
ansible_connection 与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

ssh连接参数:

参数 说明
ansible_ssh_host 将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
ansible_ssh_port ssh端口号.如果不是默认的端口号,通过此变量设置.
ansible_ssh_user 默认的 ssh 用户名
ansible_ssh_pass ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
ansible_ssh_private_key_file ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
ansible_ssh_common_args 此设置附加到sftp,scp和ssh的缺省命令行
ansible_sftp_extra_args 此设置附加到默认sftp命令行。
ansible_scp_extra_args 此设置附加到默认scp命令行。
ansible_ssh_extra_args 此设置附加到默认ssh命令行。
ansible_ssh_pipelining 确定是否使用SSH管道。 这可以覆盖ansible.cfg中得设置。

远程主机环境参数:

参数 说明
ansible_shell_type 目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.
ansible_python_interpreter 目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如  *BSD, 或者 /usr/bin/python
ansible_*_interpreter 这里的"*"可以是ruby 或perl 或其他语言的解释器,作用和ansible_python_interpreter 类似
ansible_shell_executable 这将设置ansible控制器将在目标机器上使用的shell,覆盖ansible.cfg中的配置,默认为/bin/sh。



ansible 常用模块介绍

ansible使用帮助

[root@John ~]# ansible-doc  -l                 #查询ansible的所有模块
[root@John ~]# ansible-doc -s module_name      #查看模块的属性

交互式命令执行界面

Usage: ansible-console [options]

选项与ansible一致

ansible-doc


该指令用于查看模块信息,常用参数有两个-l-s

Usage: ansible [options]

选项

参数 说明
-h, --help 显示此帮助信息
-l, --list 列出可用的模块
-M MODULE_PATH, --module-path=MODULE_PATH 指定到模块库的路径
-s, --snippet 显示playbook制定模块的用法
-v, --verbose 详细模式(-vvv表示更多,-vvvv表示启用连接调试)
--version 显示程序版本号


例子: 查询service 模块的信息

[root@John /]# ansible-doc -s service
less 436
Copyright (C) 1984-2009 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
- name: Manage services.
  action: service
      arguments              # Additional arguments provided on the command line
      enabled                # Whether the service should start on boot. *At least one of state and enabled are required.*
      name=                  # Name of the service.
      pattern                # If the service does not respond to the status command, name a substring to look for as would
                               be found in the output of the `ps' command as a stand-in for a
                               status result.  If the string is found, the service will be
                               assumed to be running.
      runlevel               # For OpenRC init scripts (ex: Gentoo) only.  The runlevel that this service belongs to.
      sleep                  # If the service is being `restarted' then sleep this many seconds between the stop and start
                               command. This helps to workaround badly behaving init scripts
                               that exit immediately after signaling a process to stop.
      state                  # `started'/`stopped' are idempotent actions that will not run commands unless necessary.
                               `restarted' will always bounce the service.  `reloaded' will
                               always reload. *At least one of state and enabled are
                               required.*
ansible-doc -s service- name: Manage services.
  action: service
      state=              现在是什么状态               
      name=               启动的服务名称
      runlevel=           指定在什么级别下启动
      pattern=            指定模式    
      enabled=             开机是否启动 
例:设置web服务开机自动启动
[root@control ~]# ansible all -m service -a "state=started name=httpd enabled=yes"                               

service: 指定运行状态
    enable=:是否开机自动启动,取值为true或false
    name=: 服务名称
    state=:状态,取值有started,stoped,restarted;
    # ansible test -a  "service network status"
    # ansible test -a "chkconfig --list httpd"
# 确保某服务已开启,没开则开
ansible test -m service -a "name=mysql state=started"
ansible test -m service -a "name=mysql state=restarted"
ansible test -m service -a "name=mysql state=stopped"


ansible语法

ansible  -m  -a 

command模块

默认模块 ,用于在各个被管理节点运行指定的命令(不支持管道和变量)
相关选项如下:

creates:一个文件名,当该文件存在,则该命令不执行

free_form:要执行的Linux指令

chdir:在执行指令之前,先切换到该目录

removes:一个文件名,当该文件不存在,则该选项不执行

executable:切换shell来执行指令,该执行路径必须是一个绝对路径
[root@John /]# ansible test -m command -a "hostname"
192.168.159.2 | SUCCESS | rc=0 >>
John

192.168.159.3 | SUCCESS | rc=0 >>
John

shell模块

command模块功能相同,但比command的模块功能强大(支持管道和变量)
[root@John /]# ansible all -m shell -a "cat /etc/passwd| grep root" 
192.168.159.2 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

192.168.159.3 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

user模块

用户模块,用于在各管理节点管理用户所使用

创建一个名字为DBA的用户,uid是505 ,家目录是/home,shell是不让用户登录

[root@John /]# ansible test -m user -a 'name=DBA uid=505 home=/home/ shell=/sbin/nologin'
192.168.159.3 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 505, 
    "home": "/home/", 
    "move_home": false, 
    "name": "DBA", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "uid": 505
}
192.168.159.2 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 505, 
    "home": "/home/", 
    "move_home": false, 
    "name": "DBA", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "uid": 505
}

删除一个用户

[root@John /]# ansible test -m user  -a 'name=DBA uid=506  state=absent'
192.168.159.2 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "DBA", 
    "remove": false, 
    "state": "absent"
}
192.168.159.3 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "DBA", 
    "remove": false, 
    "state": "absent"
}

setup模块

## 收集ansible的facts信息
# ansiblestorm_cluster -m setup
## 用来测试远程主机的运行状态
[root@John /]# ansible test -m ping
192.168.159.3 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.159.2 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

file模块

设定文件属性

force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no

group:定义文件/目录的属组

mode:定义文件/目录的权限

owner:定义文件/目录的属主

path:必选项,定义文件/目录的路径

recurse:递归设置文件的属性,只对目录有效

src:被链接的源文件路径,只应用于state=link的情况

dest:被链接到的路径,只应用于state=link的情况

state:

      directory:如果目录不存在,就创建目录

      file:即使文件不存在,也不会被创建

      link:创建软链接

      hard:创建硬链接

      touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间

      absent:删除目录、文件或者取消链接文件

示例:

## 远程文件符号链接创建

# ansible test -m file -a "src=/etc/resolv.conf dest=/tmp/resolv.confstate=link"

## 远程文件信息查看

# ansible test -m command -a "ls –al /tmp/resolv.conf"

## 远程文件符号链接删除

# ansible test -m file -a "path=/tmp/resolv.conf state=absent"

## 远程文件信息查看

# ansible test -m command -a "ls -al /tmp/resolv.conf"

copy模块

复制文件

backup:在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no

content:用于替代“src”,可以直接设定指定文件的值

dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录

directory_mode:递归设定目录的权限,默认为系统默认权限

force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖.
如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes

others:所有的file模块里的选项都可以在这里使用

src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。
如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用“/”来结尾,则只复制目录里的内容.
如果没有使用“/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync。

实例:

## 将本地文件“/etc/ansible/ansible.cfg”复制到远程服务器

# ansible test -m copy -a "src=/etc/ansible/ansible.cfgdest=/tmp/ansible.cfg owner=root group=root mode=0644"
# ansible test -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=640'
# ansible test -m copy -a "content='Hello Ansible' dest=/tmp/test.ansible"

script模块

自动复制脚本到远程节点,并运行

测试脚本
[root@John ~]# cat ansible_test.sh #!/bin/bash echo "hello world " >> /tmp/ansible_sh.log

运行脚本
[root@John ~]# ansible all -m script -a 'ansible_test.sh'

cron模块

计划定时任务,用于在各管理节点管理计划任务

[root@note1 ~]# ansible all -m cron -a "name=time minute='*/2' job='/usr/sbin/ntpdate

template模块

根据官方的翻译是:template使用了Jinjia2格式作为文件模板,进行文档内变量的替换的模块。他的每次使用都会被ansible标记为changed状态。
在定义模板之后可以实现各节点对应的变量来取代,表达式自身会根据当前节点
所赋值做运算,之后生成的值则赋予这个参数,用于生成不同配置的配置文件,
所以模板主要实现配置不同场景文本文件。而且这样使用模板语言来定义,模板
语言中可以根据定义替换成特定主机的某些值。

yum模块

用于管理节点安装软件所使用
ansible-doc -s yum action: yum
      state=       指定是安装(`present', `latest'), 还是卸载 remove (`absent') 
      disablerepo= 如果有多个yum源可能禁用一个
      name=        要安装的包名(如果只写包名,就安装最新的包,如果想指定安装什么片本的就包名+版本号)
      enablerepo=  要启用的repo
      list=        列表(跟playbook相关)
      disable_gpg_check=  是否开启gpg_check
      conf_file=    可以用其它服务器上的配置文件,而不使用本地的配置文件
例:所有的主机都安装上corosync.
[root@John ~]# ansible all -m yum -a "state=present name=corosync"
[root@John ~]# ansible all -m yum -a 'name=ntp state=present'
卸载的软件只需要将 name=ntp state=absent
安装特定版本 name=nginx-1.6.2 state=present
指定某个源仓库安装软件包name=htop enablerepo=epel state=present
更新软件到最新版 name=nginx state=latest


实例:

执行shell
获取web组里得eth0接口信息
ansible web -a "ifconfig eth0"
执行ifconfig eth0 命令,ansible模块 默认是command,它不会通过shell进行处理,
所以像$ HOME和像“<”,“>”,“|”,“;” 和“&”将不工作(如果您需要这些功能,请使用shell模块)。
以shell解释器执行脚本
ansible web -m shell -a "ifconfig eth0|grep addr"
以raw模块执行脚本
ansible web -m raw -a "ifconfig eth0|grep addr
将本地脚本传送到远程节点上运行
ansible web -m script -a ip.sh
传输文件
拷贝本地的/etc/hosts 文件到web组所有主机的/tmp/hosts(空目录除外)
ansible web -m copy -a "src=/etc/hosts dest=/tmp/hosts"
拷贝本地的ntp文件到目的地址,设置其用户及权限,如果目标地址存在相同的文件,则备份源文件。
ansible web -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes force=yes"
file 模块允许更改文件的用户及权限
ansible web -m file -a "dest=/tmp/a.txt mode=600 owner=user group=user"
使用file 模块创建目录,类似mkdir -p
ansible web -m file -a "dest=/tmp/test mode=755 owner=user group=user state=directory"
使用file 模块删除文件或者目录
ansible web -m file -a "dest=/tmp/test state=absent"
创建软连接,并设置所属用户和用户组
ansible web -m file -a  "src=/file/to/link/to dest=/path/to/symlink owner=user group=user state=link"
touch 一个文件并添加用户读写权限,用户组去除写执行权限,其他组减去读写执行权限
ansible web -m file -a  "path=/etc/foo.conf state=touch mode='u+rw,g-wx,o-rwx'"
管理软件包
apt、yum 模块分表用于管理Ubuntu 系列和RedHat 系列系统软件包
更新仓库缓存,并安装"foo"
ansible web -m apt -a "name=foo update_cache=yes"
删除 "foo"
ansible web -m apt -a "name=foo state=absent"
安装  "foo"
ansible web -m apt -a "name=foo state=present"
安装  1.0版本的 "foo"
ansible web -m apt -a "name=foo=1.00 state=present"
安装最新得"foo"
ansible web -m apt -a "name=foo state=latest"
注释:Ansible 支持很多操作系统的软件包管理,使用时-m 指定相应的软件包管理工具模块,如果没有这样的模块,可以自己定义类似的模块或者使用command 模块来安装软件包
安装 最新的 Apache
ansible web -m yum -a  "name=httpd state=latest"
删除apache
ansible web -m yum -a  "name=httpd state=absent"
从testing 仓库中安装最后一个版本得apache
ansible web -m yum -a  "name=httpd enablerepo=testing state=present"
更新所有的包
ansible web -m yum -a  "name=* state=latest"
安装远程的rpm包
ansible web -m yum -a  "name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"
安装  'Development tools' 包组
ansible web -m yum -a  "name='@Development tools' state=present"
用户和用户组
添加用户 'user'并设置其 uid 和主要的组'admin'
ansible web -m user -a "name=user  comment='I am user ' uid=1040 group=admin"
添加用户 'user'并设置其登陆shell,并将其假如admins和developers组
ansible web -m user -a "name=user shell=/bin/bash groups=admins,developers append=yes"
删除用户 'user '
ansible web -m user -a "name=user state=absent remove=yes"
创建 user用户得   2048-bit SSH key,并存放在 ~user/.ssh/id_rsa
ansible web -m user -a "name=user generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa"
设置用户过期日期
ansible web -m user -a "name=user shell=/bin/zsh groups=nobdy expires=1422403387"
创建test组,并设置git为1000
ansible web -m group -a "name=test gid=1000 state=present"
删除test组
ansible web -m group -a "name=test state=absent"
源码部署
Ansible 模块能够通知变更,当代码更新时,可以告诉Ansible 做一些特定的任务,比如从git 部署代码然后重启apache 服务等
ansible web-m git -a "repo=https://github.com/Icinga/icinga2.git dest=/tmp/myapp   version=HEAD"
服务管理
确保web组所有主机的httpd 是启动的
ansible web-m service -a "name=httpd state=started"
重启web组所有主机的httpd 服务
ansible web-m service -a "name=httpd state=restarted"
确保web组所有主机的httpd 是关闭的
ansible web-m service -a "name=httpd state=stopped"
后台运行
长时间运行的操作可以放到后台执行,ansible 会检查任务的状态;在主机上执行的同一个任
务会分配同一个job ID
后台执行命令3600s,-B 表示后台执行的时间
ansible all -B 3600 -a "/usr/bin/long_running_operation --do-stuff"
检查任务的状态
ansible all -m async_status -a "jid=123456789"
后台执行命令最大时间是1800s 即30 分钟,-P 每60s 检查下状态默认15s
ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"
定时任务
每天5点,2点得时候执行 ls -alh > /dev/null
ansible test -m cron -a "name='check dirs' minute='0' hour='5,2' job='ls -alh > /dev/null'"
搜集系统信息
搜集主机的所有系统信息
ansible all -m setup
搜集系统信息并以主机名为文件名分别保存在/tmp/facts 目录
ansible all -m setup --tree /tmp/facts
搜集和内存相关的信息
ansible all -m setup -a 'filter=ansible_*_mb'
搜集网卡信息
ansible all -m setup -a 'filter=ansible_eth[0-2]'

资源:

官方文档: http://docs.ansible.com/
中文文档: http://www.ansible.com.cn/ http://ansible-tran.readthedocs.io/en/latest/
Jinja2 中文文档: http://docs.jinkan.org/docs/jinja2/
yaml语法: http://www.yaml.org/
书籍: https://www.ansible.com/ebooks
ansible examples: https://github.com/ansible/ansible-examples
ansible-vim: https://github.com/pearofducks/ansible-vim