运维部署自动化运维

读书笔记:Ansible自动化运维:技术与最佳实践

2018-06-23  本文已影响193人  周少言

观其大纲

第一章 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的基本架构,从上图可以了解到其由以下部分组成:

特性

 模块化:调用特定的模块,完成特定任务
 有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示例

  1. 创建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、字符串可以不用引号标注

三种数据结构

# YAML表示
age : 12
name : huang

# 对应的Json表示
{'age':12,'name':'huang'}

也可以将一个map写在一行:

# YAML表示
{age:12,name:huang}
# 对应的Json表示
{'age':12,'name':'huang'}
# YAML表示
- a
- b
- 12

# 对应Json表示
['a','b',12]

也可以写在一行:

# YAML表示
[a,b,c]

# 对应Json表示
[ 'a', 'b', 'c' ]

数据结构嵌套

map和list的元素可以是另一个map或者list或者是纯量。由此出现4种常见的数据嵌套:

# 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交互命令行

上一篇下一篇

猜你喜欢

热点阅读