ansible教程-hands-on

分類 devops, ansible

Ansible 学习笔记

简介

  • 基于Python开发的自动化运维工具
  • 集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点
  • 基于模块工作,本身没有批量部署能力,批量部署由运行的模块实现
  • 提供自动化运维框架

作用

  • 批量系统配置
  • 批量程序部署
  • 批量运行命令

框架组成

  • Connection Plugins:负责和被监控端实现通信
  • Host Inventory:定义监控主机的配置文件
  • 模块
    • 核心模块
    • command模块
    • 自定义模块
  • 插件:完成记录日志邮件等功能
  • Playbook:剧本,非必需,可让节点一次性运行多个任务

架构图

Ansible架构图

架构字段解释

  • Ansible:核心程序
  • Host Inventory:主机清单(可定义主机组和主机)
  • 模块:实际执行任务的组件
  • Playbook:Yaml定义的剧本文件(类似shell脚本)
  • Connect Plugin:连接插件

工作原理

  1. 控制端通过inventory定义主机组
  2. 通过编写playbook或AD-HOC命令
  3. 使用SSH将模块推送到被控端
  4. 被控端执行任务(要求被控端有Python2环境)
  5. 任务完成后返回结果

命令执行过程

  1. 加载配置文件(/etc/ansible/ansible.cfg)
  2. 查找主机配置文件
  3. 加载对应模块文件
  4. 生成临时Python脚本并传输到远程主机
  5. 存储在远程主机的~/.ansible/tmp/目录
  6. 添加执行权限
  7. 执行并返回结果
  8. 删除临时文件

执行流程理解图

执行流程

特性

  • No Agents:无需在被控端安装客户端
  • No Server:无服务端架构
  • Modules in Any Languages:支持任意语言开发模块
  • YAML:使用YAML语言编写playbook
  • SSH by Default:默认基于SSH工作
  • Multi-tier Solution:支持多级指挥

配置文件

配置文件优先级(从高到低):

  1. 项目目录下的ansible.cfg
  2. 用户家目录下的.ansible.cfg
  3. 默认的/etc/ansible/ansible.cfg

主要配置项

1
2
3
4
5
6
7
8
9
10
11
#inventory = /etc/ansible/hosts      # 主机列表
#library = /usr/share/my_modules/ # 模块库目录
#remote_tmp = ~/.ansible/tmp # 远程临时目录
#local_tmp = ~/.ansible/tmp # 本地临时目录
#forks = 5 # 并发数
#sudo_user = root # 默认sudo用户
#ask_sudo_pass = True # 是否询问sudo密码
#ask_pass = True # 是否询问SSH密码
#remote_port = 22 # 远程端口
host_key_checking = False # 跳过主机指纹检查
log_path = /var/log/ansible.log # 日志路径

优点

  • 轻量级,客户端无需安装agent
  • 批量任务可写成脚本且无需分发
  • 基于Python,维护简单
  • 支持sudo

环境搭建

主机规划

主机 IP 角色
h1 192.168.50.60 master
h2 192.168.50.61 host1
h3 192.168.50.62 host2
h4 192.168.50.63 host3

SSH免密登录配置

1
2
ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
ssh-copy-id -i ~/.ssh/id_dsa.pub root@192.168.50.61

安装

1
yum install -y ansible

主机清单配置

1
2
3
4
5
6
7
[hosts]
192.168.50.61
192.168.50.62
192.168.50.63

[local]
127.0.0.1

测试

1
2
ansible webservers -m command -a 'uptime'
ansible all -m ping

常用模块

setup模块

查看远程主机基本信息

1
ansible webservers -m setup

fetch模块

从主机获取文件

1
ansible 192.168.50.61 -m fetch -a 'src=/root/t2 dest=/root'

file模块

设置文件属性

选项:

  • force: 强制创建软链接(yes|no)
  • group: 文件属组
  • mode: 文件权限
  • owner: 文件属主
  • path: 文件路径(必选)
  • recurse: 递归设置属性(仅目录)
  • src: 源文件路径(仅state=link时)
  • dest: 链接目标路径(仅state=link时)
  • state:
    • directory: 创建目录
    • file: 不创建文件
    • link: 创建软链接
    • hard: 创建硬链接
    • touch: 创建空文件或更新修改时间
    • absent: 删除文件/目录

示例:

1
2
# 创建符号链接
ansible hosts -m file -a "src=/etc/resolv.conf dest=/root/resolv.conf state=link"

copy模块

复制文件到远程主机

选项:

  • backup: 覆盖前备份(yes|no)
  • content: 直接设置文件内容(替代src)
  • dest: 目标绝对路径(必选)
  • directory_mode: 递归设置目录权限
  • force: 强制覆盖(yes|no)
  • src: 本地源文件路径

示例:

1
ansible hosts -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0755"

command模块

在远程主机执行命令

选项:

  • creates: 文件存在时不执行
  • free_form: Linux命令
  • chdir: 执行前切换目录
  • removes: 文件不存在时不执行
  • executable: 指定shell路径

示例:

1
2
ansible webservers -m command -a "ls -al /tmp"
ansible webservers -m command -a 'useradd abc'

shell模块

支持管道操作的命令执行

示例:

1
2
3
4
5
# 执行远程脚本
ansible hosts -m shell -a "/root/test.sh"

# 批量添加用户密码
ansible hosts -m shell -a 'useradd abc && echo 123 |passwd --stdin abc'

cron模块

管理计划任务

选项:

  • minute/hour/day/month/weekday: 时间设置
  • job: 任务命令
  • name: 任务名称
  • user: 执行用户
  • state: present(添加)|absent(删除)

示例:

1
2
3
4
5
# 创建任务
ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 192.168.50.60 &>/dev/null' name='sync time'"

# 删除任务
ansible all -m cron -a "name='sync time' state=absent"

hostname模块

管理主机名

示例:

1
2
# 修改主机名
ansible 192.168.50.63 -m hostname -a "name=t4"

yum模块

软件包管理

示例:

1
2
3
4
5
# 安装tree
ansible all -m yum -a "name=tree"

# 卸载
ansible all -m yum -a 'name=tree state=absent'

service模块

服务管理

示例:

1
2
# 启动ntpdate服务
ansible all -m service -a "name=ntpdate state=started enabled=true"

group模块

用户组管理

示例:

1
2
# 添加系统组
ansible all -m group -a "name=gansible system=true"

user模块

用户管理

选项:

  • name: 用户名
  • state: present(新增)|absent(删除)
  • force: 删除时是否删除家目录
  • system: 是否系统用户
  • uid: 指定UID
  • shell: 指定shell
  • home: 指定家目录

示例:

1
2
# 添加系统用户
ansible all -m user -a "name=ccc system=true"

YAML语法

  • 数据序列化格式
  • 基本结构:
    1
    2
    3
    4
    key: value
    - item1
    - item2
    - item3
    例如: {name: jerry, age: 21}

Playbook

核心元素

  • Tasks: 任务列表
  • Variables: 变量
  • Templates: 模板文件
  • Handlers: 条件触发任务
  • Roles: 角色

基础组件

  • Hosts: 目标主机
  • remote_user: 执行用户
  • sudo_user: sudo用户
  • tasks: 任务列表

运行Playbook

1
2
3
4
5
6
7
8
# 语法检查
ansible-playbook --syntax-check playbook.yaml

# 测试运行
ansible-playbook -C playbook.yaml

# 实际运行
ansible-playbook playbook.yaml

示例

1. 添加用户和组

1
2
3
4
5
6
7
- hosts: all
remote_user: root
tasks:
- name: add a group
group: name=test system=test
- name: add a user
user: name=test group=test system=true

2. 配置HTTP服务

1
2
3
4
5
6
7
8
9
- hosts: hosts
remote_user: root
tasks:
- name: install http
yum: name=httpd state=latest
- name: install conf
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf.bak
- name: start
service: name=httpd state=reloaded enabled=true

更多模块

  • synchronize: 使用rsync同步文件
  • raw: 直接执行命令(类似shell)

模块帮助

# 列出所有模块
ansible-doc -l

# 查看模块帮助
ansible-doc -s MOD_NAME

留言與分享

ansible教程-概念

分類 devops, ansible

Ansible 概念

这些概念适用于 Ansible 的所有用途。在使用 Ansible 或阅读文档之前,您应该了解它们。

  • [控制节点]

  • [被管理节点]

  • [清单]

  • [剧本]

    • [剧集]

      • [角色]

      • [任务]

      • [处理器]

  • [模块]

  • [插件]

  • [集合]

[控制节点]

运行 Ansible CLI 工具(ansible-playbookansibleansible-vault 等)的机器。您可以使用任何满足软件要求的计算机作为控制节点——笔记本电脑、共享桌面和服务器都可以运行 Ansible。您也可以在称为执行环境的容器中运行 Ansible。

可以使用多个控制节点,但 Ansible 本身并不协调它们之间的工作,有关此类功能,请参见AAP

[被管理节点]

也称为“主机”,这些是您旨在用 Ansible 管理的目标设备(服务器、网络设备或任何计算机)。

除非您使用ansible-pull,否则通常不会在被管理节点上安装 Ansible,但这很少见,也不是推荐的设置。

[清单]

由一个或多个“清单源”提供的被管理节点列表。您的清单可以指定每个节点的特定信息,例如 IP 地址。它还用于分配组,这既允许在剧集中选择节点,也允许批量分配变量。

要了解有关清单的更多信息,请参阅使用清单部分。有时,清单源文件也称为“主机文件”。

[剧本]

它们包含剧集(这是 Ansible 执行的基本单元)。这既是“执行概念”,也是我们用来描述ansible-playbook操作的文件的方式。

剧本是用 YAML 编写的,易于阅读、编写、共享和理解。要了解有关剧本的更多信息,请参阅Ansible 剧本

[剧集]

Ansible 执行的主要上下文,此剧本对象将被管理节点(主机)映射到任务。剧集包含变量、角色和已排序的任务列表,并且可以重复运行。它基本上由对映射的主机和任务的隐式循环组成,并定义如何迭代它们。

[角色]

可在剧集内部使用的可重用 Ansible 内容(任务、处理器、变量、插件、模板和文件)的有限分发。

要使用任何角色资源,必须将角色本身导入剧集。

[任务]

应用于被管理主机的“操作”的定义。您可以使用ansibleansible-console(两者都会创建一个虚拟剧集)一次执行单个任务。

[处理器]

任务的一种特殊形式,仅在之前的任务发出通知并且导致“已更改”状态时才执行。

[模块]

Ansible 复制到并在每个被管理节点上执行(如有需要)的代码或二进制文件,以完成每个任务中定义的操作。

每个模块都有其特定的用途,从管理特定类型数据库上的用户到管理特定类型网络设备上的 VLAN 接口。

您可以使用任务调用单个模块,也可以在剧本中调用多个不同的模块。Ansible 模块分组在集合中。要了解 Ansible 包含多少集合,请参阅集合索引

[插件]

扩展 Ansible 核心功能的代码片段。插件可以控制您如何连接到被管理节点(连接插件)、操作数据(过滤器插件),甚至控制在控制台中显示的内容(回调插件)。

有关详细信息,请参阅使用插件

[集合]

Ansible 内容的分发格式,可以包含剧本、角色、模块和插件。您可以通过Ansible Galaxy安装和使用集合。

要了解有关集合的更多信息,请参阅使用 Ansible 集合

集合资源可以彼此独立且离散地使用。

留言與分享

ansible教程-入门篇

分類 devops, ansible

Ansible 简介

Ansible 提供开源自动化,可降低复杂性并在任何地方运行。使用 Ansible 可以自动执行几乎任何任务。以下是 Ansible 的一些常见用例

  • 消除重复并简化工作流程

  • 管理和维护系统配置

  • 持续部署复杂的软件

  • 执行零停机滚动更新

Ansible 使用简单的、人类可读的脚本(称为剧本)来自动化您的任务。您在剧本中声明本地或远程系统的期望状态。Ansible 确保系统保持在该状态。

作为自动化技术,Ansible 围绕以下原则设计

无代理架构

通过避免在 IT 基础设施上安装额外软件来降低维护开销。

简单性

自动化剧本使用简单的 YAML 语法,代码就像文档一样易于阅读。Ansible 也是分散式的,使用 SSH 和现有的操作系统凭据来访问远程机器。

可扩展性和灵活性

通过模块化设计轻松快速地扩展您自动化的系统,该设计支持各种操作系统、云平台和网络设备。

幂等性和可预测性

当系统处于您的剧本描述的状态时,即使多次运行剧本,Ansible 也不会更改任何内容。

使用 Ansible 开始自动化

通过创建自动化项目、构建清单和创建“Hello World”剧本开始使用 Ansible。

  1. 安装 Ansible。

    1
    pip install ansible
  2. 在您的文件系统上创建一个项目文件夹。

    1
    mkdir ansible_quickstart && cd ansible_quickstart

    使用单一目录结构可以更轻松地添加到源代码管理,以及重用和共享自动化内容。

构建清单

清单将受管节点组织在集中式文件中,这些文件为 Ansible 提供系统信息和网络位置。使用清单文件,Ansible 可以使用单个命令管理大量主机。

要完成以下步骤,您需要至少一个主机系统的 IP 地址或完全限定域名 (FQDN)。出于演示目的,主机可以在容器或虚拟机中本地运行。您还必须确保您的公共 SSH 密钥已添加到每个主机上的 authorized_keys 文件中。

继续 Ansible 入门并按如下步骤构建清单

  1. 在您在 上一步中创建的 ansible_quickstart 目录中创建一个名为 inventory.ini 的文件。

  2. inventory.ini 文件添加一个新的 [myhosts] 组,并指定每个主机系统的 IP 地址或完全限定域名 (FQDN)。

    1
    2
    3
    4
    [myhosts]
    192.0.2.50
    192.0.2.51
    192.0.2.52
  3. 验证您的清单。

    1
    ansible-inventory -i inventory.ini --list
  4. Ping 清单中的 myhosts 组。

    1
    ansible myhosts -m ping -i inventory.ini

    注意

    如果控制节点和受管节点上的用户名不同,请使用 ansible 命令传递 -u 选项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    192.0.2.50 | SUCCESS => {
    "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
    }
    192.0.2.51 | SUCCESS => {
    "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
    }
    192.0.2.52 | SUCCESS => {
    "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
    }

INI 或 YAML 格式的清单

您可以使用 INI 文件或 YAML 创建清单。在大多数情况下,例如上一步中的示例,对于少量受管节点,INI 文件简单易读。

随着受管节点数量的增加,使用 YAML 格式创建清单变得更合理。例如,以下是 inventory.ini 的等效项,它声明受管节点的唯一名称并使用 ansible_host 字段

1
2
3
4
5
6
7
8
myhosts:
hosts:
my_host_01:
ansible_host: 192.0.2.50
my_host_02:
ansible_host: 192.0.2.51
my_host_03:
ansible_host: 192.0.2.52

构建清单的技巧

  • 确保组名有意义且唯一。组名也区分大小写。

  • 避免在组名中使用空格、连字符和前导数字(使用 floor_19,而不是 19th_floor)。

  • 根据主机的**什么**、**哪里**和**何时**逻辑地将主机分组到您的清单中。

    什么

    根据拓扑结构对主机分组,例如:db、web、leaf、spine。

    哪里

    按地理位置对主机分组,例如:数据中心、区域、楼层、建筑物。

    何时

    按阶段对主机分组,例如:开发、测试、过渡、生产。

使用元组

使用以下语法创建一个元组来组织清单中的多个组

以下清单说明了数据中心的结构基础。此示例清单包含一个 network 元组,其中包括所有网络设备,以及一个 datacenter 元组,其中包括 network 组和所有 Web 服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
leafs:
hosts:
leaf01:
ansible_host: 192.0.2.100
leaf02:
ansible_host: 192.0.2.110

spines:
hosts:
spine01:
ansible_host: 192.0.2.120
spine02:
ansible_host: 192.0.2.130

network:
children:
leafs:
spines:

webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
webserver02:
ansible_host: 192.0.2.150

datacenter:
children:
network:
webservers:

创建变量

变量设置受管节点的值,例如 IP 地址、FQDN、操作系统和 SSH 用户,因此您无需在运行 Ansible 命令时传递它们。

变量可以应用于特定主机。

1
2
3
4
5
6
7
8
webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
http_port: 80
webserver02:
ansible_host: 192.0.2.150
http_port: 443

变量也可以应用于组中的所有主机。

1
2
3
4
5
6
7
8
9
10
webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
http_port: 80
webserver02:
ansible_host: 192.0.2.150
http_port: 443
vars:
ansible_user: my_server_user

创建剧本

剧本是 Ansible 用于部署和配置受管节点的自动化蓝图,采用 YAML 格式。

剧本

一系列定义 Ansible 执行操作顺序的剧目,自上而下,以实现总体目标。

剧目

一个有序的任务列表,映射到清单中的受管节点。

任务

对单个模块的引用,定义 Ansible 执行的操作。

模块

Ansible 在受管节点上运行的代码或二进制单元。Ansible 模块按集合分组,每个模块都有一个完全限定的集合名称 (FQCN)

完成以下步骤以创建用于 ping 主机并打印“Hello world”消息的剧本

  1. 在您之前创建的 ansible_quickstart 目录中创建一个名为 playbook.yaml 的文件,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - name: My first play
    hosts: myhosts
    tasks:
    - name: Ping my hosts
    ansible.builtin.ping:

    - name: Print message
    ansible.builtin.debug:
    msg: Hello world
  2. 运行您的剧本。

    1
    ansible-playbook -i inventory.ini playbook.yaml

Ansible 返回以下输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PLAY [My first play] ****************************************************************************

TASK [Gathering Facts] **************************************************************************
ok: [192.0.2.50]
ok: [192.0.2.51]
ok: [192.0.2.52]

TASK [Ping my hosts] ****************************************************************************
ok: [192.0.2.50]
ok: [192.0.2.51]
ok: [192.0.2.52]

TASK [Print message] ****************************************************************************
ok: [192.0.2.50] => {
"msg": "Hello world"
}
ok: [192.0.2.51] => {
"msg": "Hello world"
}
ok: [192.0.2.52] => {
"msg": "Hello world"
}

PLAY RECAP **************************************************************************************
192.0.2.50: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.0.2.51: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.0.2.52: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

在此输出中,您可以看到

  • 您为剧目和每个任务指定的名称。您应始终使用易于验证和排查剧本问题的描述性名称。

  • “收集事实”任务隐式运行。默认情况下,Ansible 会收集有关您的清单的信息,以便在剧本中使用。

  • 每个任务的状态。每个任务的状态为 ok,表示它已成功运行。

  • 剧目摘要,总结了每个主机上所有任务的结果。在此示例中,共有三个任务,因此 ok=3 表示每个任务都已成功运行。

恭喜,您已开始使用 Ansible!

留言與分享

  • 第 1 頁 共 1 頁
作者的圖片

Kein Chan

這是獨立全棧工程師Kein Chan的技術博客
分享一些技術教程,命令備忘(cheat-sheet)等


全棧工程師
資深技術顧問
數據科學家
Hit廣島觀光大使


Tokyo/Macau