观其大纲
第一章 ansible架构及其特点
架构模式
特性
ansible与DevOps
第二章 ansible安装与配置
第三章 ansible组件介绍
Ansible inventory
Ansible AD-Hoc命令
Ansible playbook
Ansible facts
Ansible role
Ansible Galaxy
第四章 playbook详解
基本语法
变量与引用
循环
lookups
conditionals
Jinja2 filter
playbook内置变量
第五章 ansible最佳实践
优化ansible速度
目录结构
定义多环境
灰度发布与检测
统一管理
ansible-shell交互命令行
熟知概念
Ansible中文权威指南
Ansible是一个简单的自动化运维管理工具,基于Python语言实现,由Paramiko和PyYAML两个关键模块构建,可用于自动化部署应用、配置、编排task(持续交付、无宕机更新等)。主版本大概每2个月发布一次。
Ansible与Saltstack最大的区别是Ansible无需在被控主机部署任何客户端代理,默认直接通过SSH通道进行远程命令执行或下发配置:相同点是都具备功能强大、灵活的系统管理、状态配置,两者都提供丰富的模板及API,对云计算平台、大数据都有很好的支持。
python模块paramiko
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。
python模块
Yaml —— Yet Another Markup Language :一种标记语言
编程免不了要写配置文件,怎么写配置也是一门学问。
YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。
YAML在python语言中有PyYAML安装包。
第一章 ansible架构及其特点
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
架构模式
Ansible 与其他配置管理的对比
项目 | Puppet | SaltStack | Ansible |
---|---|---|---|
开发语言 | Ruby | Python | Python |
是否有客户端 | 有 | 有 | 无 |
是否支持二次开发 | 不支持 | 支持 | 支持 |
服务器与远程机器是否相互验证 | 是 | 是 | 是 |
服务器与远程机器的通信是否加密 | 是,标准的SSL协议 | 是,使用AES加密 | 是,使用OpenSSH |
平台支持 | AIX , BSD, HP-UX, Linux , Mac OSX , Solaris, Windows | BSD, Linux , Mac OS X , Solaris, Windows | AIX , BSD , HP-UX , Linux , Mac OS X , Solaris |
是否提供Web UI | 提供 | 提供 | 提供,但是是商业版本 |
配置文件格式 | Ruby 语法格式 | YAML | YAML |
命令行执行 | 不支持,大师可以通过配置模块实现 | 支持 | 支持 |
Ansible 是一个模型驱动的配置管理器,支持多节点发布、远程任务执行。默认使用 SSH 进行远程连接。无需在被管理节点上安装附加软件,可使用各种编程语言进行扩展。
Ansible基本架构
上图为ansible的基本架构,从上图可以了解到其由以下部分组成:
- 核心:ansible
- 核心模块(Core Modules):这些都是ansible自带的模块
- 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
- 插件(Plugins):完成模块功能的补充
- 剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
- 连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件
- 主机群(Host Inventory):定义ansible管理的主机
特性
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
第二章 ansible安装与配置
安装
Ansible默认不在标准仓库中,需要用到EPEL源。
yum -y install ansible
配置文件
配置文件或指令 | 描述 |
---|---|
/etc/ansible/ansible.cfg | 主配置文件,配置ansible工作特性 |
/etc/ansible/hosts | 主机清单 |
/etc/ansible/roles/ | 存放角色的目录 |
指令 | |
/usr/bin/ansible | 主程序,临时命令执行工具 |
/usr/bin/ansible-doc | 查看配置文档,模块功能查看工具 |
/usr/bin/ansible-galaxy | 下载/上传优秀代码或Roles模块的官网平台 |
/usr/bin/ansible-playbook | 定制自动化任务,编排剧本工具 |
/usr/bin/ansible-pull | 远程执行命令的工具 |
/usr/bin/ansible-vault | 文件加密工具 |
/usr/bin/ansible-console | 基于Console界面与用户交互的执行工具 |
每个命令可以加上 -h 获取帮助信息
第三章 ansible组件介绍
Ansible inventory
管理不同业务的不同机器,这些机器的信息都存放在Ansible的Inventory组件里面,默认是一个静态的INI格式文件/etc/ansible/hosts
主机(hosts)部分可以使用域名、主机名、IP地址表示
定义主机和主机组,举例如下
168.100.100.112 ansible_ssh_pass = '123456' //定义一个主机168.100.100.100 ,使用Inventory内置定义了的SSH登录密码
[docker] //定义了一个组叫docker
168.100.100.100[1:3] //定义docker组下面4台主机从168.100.100.100-168.100.100.103
[docker:vars]
ansible_ssh_pass='123456' //定义docker组使用Inventory内置定义了的SSH登录密码
[ansible:children]
docker //定义一个组叫ansible,这个组包含docker组
Ansible AD-Hoc命令
什么是ad-hoc 命令?
ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。这也是一个好的地方,在学习ansible playbooks时可以先了解另外一种ansible基本的快速用法,不一定非要写一个palybook文件。
不过,对于配置管理和应用部署这种工作,还是需要使用“/usr/bin/ansible-playbook”命令。
1.需要使用Ad-Hoc的场景
情景1:
节假日将至,我们需要关闭所有不必要的服务器,并对所有服务器进行节前健康检查。
情景2:
临时更新Apache&Nginx的配置文件,且需同时将其分发至所有需更新该配置的Web服务器
2. 需要使用ansible-playbook的场景
情景1:
新购置的服务器安装完系统后需做一系列固化的初始化工作,诸如:定制防火墙策略、添加NTP时间同步配置、添加EPEL源等。
情景2:
业务侧每周定期对生产环境发布更新程序代码。
基本语法
ansible <pattern_goes_here> -m <module_name> -a <arguments>
<pattern_goes_here> 指定host信息
<module_name> 指定模块
<arguments> 指定参数
常用示例
1、并行执行
# 重启 atlanta 组的机器,并发分支 10
ansible atlanta -a "/sbin/reboot" -f 10
2、Shell 命令
# 在 172.25.99.101 输出 hello
ansible 172.25.99.101 -m shell -a 'echo hello'
3、文件传输
# 将当前服务器的 /srv/foo/a.txt 文件传输到 webservers 组
ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
4、软件包管理
# 在 webservers 组安装最新版 acme
ansible webservers -m yum -a "name=acme state=latest"
5、Users 和 Groups 管理
# 创建用户 foo
ansible all -m user -a "name=foo password=<crypted password here>"
6、从源代码管理部署
ansible webservers -m git -a
"repo=https://foo.example.org/repo.git dest=/srv/myapp version=HEAD"
7、服务管理
# 确保在 webservers 组启动 httpd 服务
ansible webservers -m service -a "name=httpd state=started"
8、时间有限的后台操作
# 在后台异步执行 long_running_operation,超时时间为3600秒(-B),没有轮询(-P)
ansible all -B 3600 -P 0 -a "/usr/bin/long_running_operation --do-stuff
ansible常用模块
模块 | 功能 | 实例 |
---|---|---|
1、ping模块 | 检查指定节点机器是否还能连通,用法很简单,不涉及参数,主机如果在线,则回复pong | ansible 10.1.1.113 -m ping |
2、raw模块 | 执行原始的命令,而不是通过模块子系统。在任何情况下,使用shell或命令模块是合适的。给定原始的参数直接通过配置的远程shell运行。可返回标准输出、错误输出和返回代码。此模块没有变更处理程序支持。 这个模块不需要远程系统上的Python,就像脚本模块一样。此模块也支持Windows目标。 | - |
3、yum模块 | 这个模块是RedHat / CentOS作为远端节点的OS的时候,用的最多的。Yum是啥就不多说了,RedHat / CentOS包管理工具 选项state:状态(present,absent,latest),表示是安装还卸载 present:默认的,表示为安装 lastest: 安装为最新的版本 absent:表示删除 | ansible test -m yum -a ‘name=httpd state=latest’ |
4、apt模块 | 这个模块是ubuntu作为远端节点的OS的时候,用的最多的。Apt是啥就不多说了,Ubuntu/Debian的包管理工具。 | - |
5、pip模块 | 用于管理Python库依赖项,为了使用pip模块,必须提供参数name或者requirements | - |
6、synchronize模块 | 使用rsync同步文件,将主控方目录推送到指定节点的目录下 | - |
7、template模块 | 基于模板方式生成一个文件复制到远程主机(template使用Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。) | - |
8、copy模块 | 在远程主机执行复制操作文件。 | - |
9、user 模块与group模块 | user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。 | - |
10、service 模块 | 用于管理服务,记得针对Centos7就不要使用这个模块了。 | - |
11、get_url 模块 | 该模块主要用于从http、ftp、https服务器上下载文件(类似于wget) | - |
12、fetch模块 | 它用于从远程机器获取文件,并将其本地存储在由主机名组织的文件树中。 | - |
13、file模块 | file模块主要用于远程主机上的文件操作 | - |
14、unarchive模块 | 用于解压文件 | - |
15、command 模块和shell | 用于在各被管理节点运行指定的命令 ,shell和command的区别:shell模块可以特殊字符,而command是不支持 | - |
Ansible playbook
像很多其它配置文件管理方法一样,Ansible使用一种比较直白的方法来描述自己的任务配置文件。
Ansible 的任务配置文件被称之为“playbook”,我们可以称之为“剧本”。每一出剧本(playbook)中都包含一系列的任务,这每个任务在ansible中又被称为一出“戏剧”(play)。一个剧本(playbook)中包含多出戏剧(play),这很容易理解。
Ansible facts
facts组件是ansible用于采集被管理及其设备信息的一个功能,我们可以使用setup模块查及其所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
fact组件默认已经收集了很多的设备基础信息,这些信息可以在做配置管理的时候进行引用。fact信息直接当做playbook变量信息进行引用。通过定制facts以便收集我们想要的信息,同时可以通过facter和ohai来拓展facts信息。使用facter拓展facts信息。facter是pupper里面负责收集主机静态信息的组件,ansible的facts功能也一样。ansible的facts组件也会判断被控制机器上是否安装有facter和ruby-json包,如果存在的话,ansible的facts也会采集facter信息。使用ansible查看目标主机是否安装facter包。
Ansible role
Ansible之roles介绍
一、什么场景下会用roles?
假如我们现在有3个被管理主机,第一个要配置成httpd,第二个要配置成php服务器,第三个要配置成MySQL服务器。我们如何来定义playbook?
第一个play用到第一个主机上,用来构建httpd,第二个play用到第二个主机上,用来构建php,第三个play用到第三个主机上,用来构建MySQL。这些个play定义在playbook中比较麻烦,将来也不利于模块化调用,不利于多次调。比如说后来又加进来一个主机,这个第4个主机既是httpd服务器,又是php服务器,我们只能写第4个play,上面写上安装httpd和php。这样playbook中的代码就重复了。
二、roles示例
- 创建roles的必需目录
[root@node1 opt]# mkdir -pv ansible_playbooks/roles/{websrvs,dbsrvs}/
{tasks,files,templates,meta,handlers,vars}
tree ansible_playbooks/
每个role下面有个目录叫meta,在里面可以新建文件main.yml,在文件中可以设置该role和其它role之前的关联关系。
Ansible Galaxy
命令行工具
ansible-galaxy
命令与Ansible捆绑在一起,您可以使用它从Galaxy或直接从基于git的SCM安装角色。 您还可以使用它在Galaxy网站上创建新角色,删除角色或执行任务。
默认情况下,命令行工具使用服务器地址https://galaxy.ansible.com与Galaxy网站API通信。 由于Galaxy项目是一个开源项目,您可能会运行自己的内部Galaxy服务器,并希望覆盖默认的服务器地址。 您可以使用-server选项或通过在ansible.cfg文件中设置Galaxy服务器值来执行此操作。 有关在ansible.cfg中设置值的信息,请访问Galaxy设置 。
Installing Roles
使用ansible-galaxy
命令从Galaxy网站下载角色
第四章 playbook详解
基本语法
YAML所表示的YAML Ain’t Markup Language,YAML 是一种简洁的非标记语言。YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读。
基本规则
YAML有以下基本规则:
1、大小写敏感
2、使用缩进表示层级关系
3、禁止使用tab缩进,只能使用空格键
4、缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级。
5、使用#表示注释
6、字符串可以不用引号标注
三种数据结构
- 1、map,散列表
使用冒号(:)表示键值对,同一缩进的所有键值对属于一个map,示例:
# YAML表示
age : 12
name : huang
# 对应的Json表示
{'age':12,'name':'huang'}
也可以将一个map写在一行:
# YAML表示
{age:12,name:huang}
# 对应的Json表示
{'age':12,'name':'huang'}
- 2、list,数组
使用连字符(-)表示:
# YAML表示
- a
- b
- 12
# 对应Json表示
['a','b',12]
也可以写在一行:
# YAML表示
[a,b,c]
# 对应Json表示
[ 'a', 'b', 'c' ]
- 3、scalar,纯量
数据最小的单位,不可以再分割。
数据结构嵌套
map和list的元素可以是另一个map或者list或者是纯量。由此出现4种常见的数据嵌套:
- 1、map嵌套map
# YAML表示
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
# 对应Json表示
{ websites:
{ YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org' } }
2、map嵌套list
# YAML表示
languages:
- Ruby
- Perl
- Python
- c
# 对应Json表示
{ languages: [ 'Ruby', 'Perl', 'Python', 'c' ] }
3、list嵌套list
# YAML表示
-
- Ruby
- Perl
- Python
-
- c
- c++
- java
# 对应Json表示
[ [ 'Ruby', 'Perl', 'Python' ], [ 'c', 'c++', 'java' ] ]
除此以外,还可以如下表示该结构
# 方法2
- - Ruby
- Perl
- Python
- - c
- c++
- java
# 方法3
- [Ruby,Perl,Python]
- [c,c++,java]
4、list嵌套map
# YAML表示
-
id: 1
name: huang
-
id: 2
name: liao
# 对应Json表示
[ { id: 1, name: 'huang' }, { id: 2, name: 'liao' } ]
变量与引用
循环
lookups
conditionals
Jinja2 filter
playbook内置变量
第五章 ansible最佳实践
优化ansible速度
目录结构
定义多环境
灰度发布与检测
统一管理
ansible-shell交互命令行