Ansible 是一个开源的基于 OpenSSH 的自动化配置管理工具。可以用它来配置系统、部署软件和编排更高级的 IT 任务,比如持续部署或零停机更新。Ansible 的主要目标是简单和易用,并且它还高度关注安全性和可靠性。基于这样的目标,Ansible 适用于开发人员、系统管理员、发布工程师、IT 经理,以及介于两者之间的所有人。Ansible 适合管理几乎所有的环境,从拥有少数实例的小型环境到有数千个实例的企业环境。

使用 Ansible 无须在被管理的机器上安装代理,所以不存在如何升级远程守护进程的问题,也不存在由于卸载了守护进程而无法管理系统的问题。

Ansible 的主要功能

管理员可以通过 Ansible 在成百上千台计算机上同时执行指令(任务)。
对于管理员来说,经常需要执行下面的任务:

  • 维护现存的比较复杂的服务器时,手动登录的方式很容易遗漏一些操作,或者是执行一些未预期的操作。
  • 手动初始化新的服务器耗时耗力!

对于这两种情况,如果完全通过 shell 脚本实现。脚本会过于复杂,极难维护。当然我们也可以使用同类的工具,比如 Puppet and Chef。这两个工具的特点是:需要学习新的知识栈(其实 Ansible 也是有学习成本的)。

相比 Puppet 和 Chef 使用 Ansible 可以延续之前使用 shell 脚本的工作习惯和方式,因而其学习成本会低一些。下面是 Ansible 的一些优势:

  • 可以逐行的执行 shell 命令。
  • 不需要另外的客户端工具(linux 一般会自带 ssh 工具)。
  • 相同的配置只被执行一次(多次执行同一配置不会出问题)。

Ansible 的工作方式

使用 Ansible 无须在被管理的客户端电脑上安装代理之类的组件。它通过普通的 SSH 进行通信,以便从远程计算机检索信息、发出命令和复制文件。这是 Ansible 简化服务器管理的一种方式。任何公开 SSH 端口的服务器都可以通过 Ansible 进行配置和管理。

Ansible 采用模块化的设计,所以非常容易扩展到各种特定的使用场景。模块可以用任何语言编写,并使用标准 JSON 进行通信。Ansible 的配置文件是用 YAML 格式编写的,因为它使用起来非常简单,并且与主流的标记语言很相似。除了通过命令行工具 Ansible 还可以通过配置脚本(Playbooks)与客户端交互。

安装 Ansible

本文介绍在 Ubuntu 16.04 环境中安装并使用 Ansible。由于 Ubuntu 官方库提供的版本比较老,所以我们从第三方的库安装,这样就能安装到比较新的版本:

$ sudo apt-add-repository -y ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install -y ansible

安装完成后检查一下版本:

$ ansible --version

2.7.1 是笔者在写本文时的最新版本。

配置客户端主机的 SSH 秘钥

对于自动化来说,最后是通过秘钥进行认证,这样就不会把用户的密码以明文的方式写在脚本里。下面的命令把安装了 ansible 的主机上当前用户的 SSH 公钥安装到了被管理的客户端 192.168.21.145 和 192.168.21.148 上:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub nick@192.168.21.145
$ ssh-copy-id -i ~/.ssh/id_rsa.pub nick@192.168.21.148

说明:这两台被管理的客户端主机运行的也都是 Ubuntu 16.04。

然后尝试通过下面的命令以不输密码的方式连接到远程主机中:

$ ssh nick@192.168.21.145
$ ssh nick@192.168.21.148

如果能够成功登陆,说明 SSH 的配置已经 OK 了。

配置用户执行 sudo 时不需要密码
在我们执行的自动化操作中,有很大一部分是需要 root 权限的,比如执行更新、安装软件等等。这样的操作会因为在以 sudo 方式执行是提升用户输入密码而失败,比如下面的命令:

$ ansible testservers -b -u nick -a "apt update"

-b 选项默认把用户 nick 提升为 root 权限,但是需要输入用户 nick 的密码,所以自动化执行的命令失败了。当然我们可以同时添加 -K 选项,这是 ansible 会停下来与用户交互,等待用户输入密码:

但这真的不是我想要的结果,我需要的是脚本能够自动化的不需要交互的完成任务!

这个问题的解决方法是把用户设置为执行 sudo 命令时不需要输入密码,让我们在客户机 192.168.21.148 上执行下面的命令:

$ sudo visudo

为用户 nick 添加下面的行:

nick    ALL=(ALL)     NOPASSWD: ALL

该行内容配置用户 nick 在执行 sudo 命令时不需要输入密码,保存后让我们再次执行下面的命令:

$ ansible testservers -b -u nick -a "apt update"

这次终于可以执行 root 权限的命令了!

清单(inventory)

清单是 ansible 的一个配置文件,在清单中我们可以指定被管理的客户端机器。Ansible 默认的清单文件为 /etc/ansible/hosts,当然我们也可以通过 -i 选项指定其它的清单文件,比如下面的例子:

$ ansible myservers -i /etc/ansible/myhosts -b -u nick -a "apt update"

在清单文件中,我们可以指定 ansible 命令操作的主机对象。对于单个的主机,可以在清单中写主机域名,也可以直接写 IP 地址:

如果要同时对对个主机进行操作,可以把它们定义在一个组中:

在执行 ansible 命令时,指定清单中定义的主机名称或者组名就可以了。比如我们在 /etc/ansible/hosts 文件中定义了一个名称为 testservers 的组,它包含了两个主机:

然后通过下面的命令分别在这两台主机上执行 df -h 命令:

$ ansible testservers -u nick -a "df -h"

从输出的结果可以看出 df -h 命令在两台目标主机上都执行了。

模块

Ansible 把类似的操作封装到模块中,这样就可以通过插件的方式对 Ansible 进行扩展了。每个模块都能接收参数,几乎所有的模块都接受键值对(key=value)参数,这些参数通过空格进行分隔。也有一些模块不接收参数,只需在命令行输入相关的命令就能调用。如果要执行单个命令,可以使用 command 模块:

$ ansible testservers -m command -u nick -a "df -h"
$ ansible webservers -m command -a "/sbin/reboot -t now"

因为 command 是 ansible 执行命令是使用的默认模块,所以我们可以在命令行中省略它:

$ ansible testservers -u nick -a "df -h"
$ ansible testservers -b -u nick -a "/sbin/reboot -t now"

这样的写法本质上和前面的写法是一样的。

如果要执行其它模块中的命令就需要通过 -m 选项显式的指定模块的名称,比如执行 service 模块中的命令:

$ ansible testservers -m service -a "name=httpd state=started"

如果要把文件从本机拷贝到客户端主机上去,就需要使用 copy 模块:

$ ansible testservers -m copy -u nick  -a "src=./app.js dest=./myapp/app.js"

Ansible 默认内置了很多好用的模块,你可以从其官方文档中的模块部分了解更多模块相关的内容。

playbook

如果 Ansible 的功能仅仅是能够执行当个的命令和脚本就显得太弱了。Ansible 的 laybook 功能支持把命令以 yaml 的格式写在配置文件中,然后一次性执行配置文件中的所有命令(这一点类似于 chef 中的 cookbook)。比如我们可以把前面演示的 df -h 命令以配置文件的方式写在 playbook 中:

---
- hosts: testservers
become: true
become_user: root
tasks:
- name: check disk
command: df -h

把上面的代码保存在文件 playbook.yml 中,当然你可以根据自己的喜好命名这个文件。其中 hosts 表示对哪些主机进行操作,become 就是我们在命令行上用过的 -b 选项,这里我们通过 become_user: root 显式的指定把当前用户的权限提升为 root 用户权限来执行命令。下面的 tasks 则是对任务的定义,name 是独一无二的一个任务名(如果有多个同名的 task,只执行第一个),接着是 task 中的命令,这里我们还是简单的执行 df -h 命令。然后执行下面的命令,注意这次执行的是 ansible-playbook 命令,并且需要指定编辑好的 playbook 的文件名称作为参数:

$ ansible-playbook -u nick playbook.yml

这样一个简单的 playbook 就可以正常工作了,当然实际的生产环境中你可能会把 playbook 编写的非常复杂!

跳过首次 ssh 连接时的确认提示

这是一个在自动化的过程中经常碰到的问题,所以有必要提一下。如果你不是通过 ssh-copy-id 命令把公钥添加到目标机器上的(多数的环境都不是这么做的),在首次执行 ansible 命令时需要用户确认连接的安全性:

这是非常悲催的,因为我们要实现的目标是自动化的执行命令,而不需要进行交互式的操作。
这个问题的解决方案是配置 ansible,跳过这一步的检查。具体的做法是在配置文件 /etc/ansible/ansible.cfg 中找到行 host_key_checking = False,并去掉行头的注释字符:

然后再执行 ansible 命令就不会提示用户进行交互式验证了。

总结

Ansible 是一个强大的自动化工具,并以其简介的用法,对开发者(系统运维工程师)友好的特点在自动化的流程中占据了一席之地。在这个 devops 已经成为主流的时代,如果能够熟练的使用 ansible ,相信必定会让你的 devops 实践如虎添翼。

参考:
Ansible Doc
Ansible中文权威指南
How to Install and Configure Ansible on Ubuntu 16.04

Ansible 简介的更多相关文章

  1. 批量搞机(一):ansible简介、ansible安装

    一.ansible简介 Ansible是2013年推出的一款IT自动化和DevOps软件,目前由Redhat已签署Ansible收购协议.其是基于Python研发,糅合了很多老运维工具的优点实现了批量 ...

  2. ansible简介安装配置

    ansible简介 ansible是一款,自动化运维管理工具.顾名思义是用于批量去管理及安装服务及批量管理主机. ansible与saltstack对比 ansible优点:配置简单,部署容易除主管理 ...

  3. Ansible简介及常用模块

    一.基础介绍 1.简介 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置. ...

  4. Ansible - 简介和应用自动化基础实践

    installAnsible简介和应用自动化基础实践 一.引入: 1.1  如官方定义,Ansible is The simplest way to automate apps and IT infr ...

  5. 001. Ansible简介

    一 简介 Ansible是一款极其简单的自动化运维工具, 基于Python开发, 集合了众多运维工具(puppet, cfengine, chef, func, fabric)的优点. 实现了批量系统 ...

  6. Ansible简介

    概述 Ansible是一种自动化运维管理工具,无需安装客户端,通过SSH协议与节点通信. 架构 由上图可以看出Ansible由5个部分组成 Ansible:核心 Inventory:定义管理主机的清单 ...

  7. 1. Ansible 简介

    目录 1. Ansible 是什么? 2. Ansible 特性 3. 控制主机需求 4. 被管理节点需求 1. Ansible 是什么? Ansible 是一个配置管理系统(configuratio ...

  8. ansible简介,简单实用

    Ansible ansilbe是实现自动化运维的工具,基于python开发,实现批量系统配置,批量程序部署,批量运行命令等功能. ansible是基于模块工作的,自身是没有批量部署的能力.真正具有批量 ...

  9. 1、Ansible简介及简单安装、使用

    参考Ansible权威指南:https://ansible-tran.readthedocs.io/en/latest/index.html 以下内容学习自马哥教育 Ansible: 运维工作:系统安 ...

随机推荐

  1. WPF:完美自定义MeaagseBox 2.0

    很久前做个一个MessageBox,原文链接:http://www.cnblogs.com/DoNetCoder/p/3843658.html. 不过对比MessageBox还有一些瑕疵.这些天有时间 ...

  2. leetcode-217存在重复元素

    leetcode-217存在重复元素 题意 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: ...

  3. (转载)彻底的理解:WebService到底是什么?

    最近老是有人跟我提web service接口,怎么,怎么滴,我觉得很扎耳朵,web service是一种将服务器的服务封装起来的技术,表现为对外提供接口,所以,web service不是一种接口 !! ...

  4. Scala隐式转换

    package big.data.analyse.scala import java.io.File import scala.io.Source /** * 隐式转换 * Created by zh ...

  5. Linux 无线网卡配置

    无线网卡常见的配置选项 某TL-WR842N路由器无线配置选项含义: 无线名称 路由器的无线(Wi-Fi)名称.无线密码 无线加密使用WPA2-PSK/WPA-PSK加密方式.AES加密算法,无线密码 ...

  6. cookie 和session 的区别(转)

    二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪录下来.当下次你再光临同一个网站,WEB 服务器会先看看有 ...

  7. [20190320]测试相同语句遇到导致cursor pin S的情况.txt

    [20190320]测试相同语句遇到导致cursor pin S的情况.txt --//前面测试链接:http://blog.itpub.net/267265/viewspace-2636342/-- ...

  8. C#核心基础--类的声明

    C#核心基础--类的声明 类是使用关键字 class 声明的,如下面的示例所示: 访问修饰符 class 类名 { //类成员: // Methods, properties, fields, eve ...

  9. 用cmd命令行编译JAVA程序时出现“找不到或无法加载主类”

    今天复习Java基础知识时,使用cmd命令窗口进行编译Java文件发现了如下问题: 网上有很多的解决方法,和问题出现的讨论,以下方法是解决我出现这个问题方式. 解决方式: 重点是圈住的部分. 下面是我 ...

  10. Linux用户抢占和内核抢占详解(概念, 实现和触发时机)--Linux进程的管理与调度(二十)

    1 非抢占式和可抢占式内核 为了简化问题,我使用嵌入式实时系统uC/OS作为例子 首先要指出的是,uC/OS只有内核态,没有用户态,这和Linux不一样 多任务系统中, 内核负责管理各个任务, 或者说 ...