Ansible¶
Ansible 是一个用 Python 实现的, 基于 SSH 的服务器配置工具. 简单来说, 服务器配置就是一系列的 拷贝和下载文件, 运行命令. 而 Ansible 用 Inventory 来批量管理服务器, 用 Playbook 来编排你要执行的动作, 然后使用 ansible cli 来选择对哪些服务器, 按照什么样的顺序, 执行哪些定义好的动作. 这就是 Ansible 的主要功能.
Quick Links¶
入门:
Inventory Intro: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory
Playbook User Guide: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html
常用手册:
Command Line Reference: https://docs.ansible.com/ansible/latest/user_guide/command_line_tools.html
Ansible Built-in Collecton Index: https://docs.ansible.com/ansible/latest/collections/index.html
Ansible 的重要概念¶
Inventory¶
一个 .ini 或是 .yml 文件, 定义了你想要管理的服务器, 当然是要给定 DNS name 或是 IP 地址来指定服务器. 这里服务器可以按照层级进行分组, 以便于你用命令指定你要将 Playbook 在哪些机器上执行. 而这里的 DNS name 或 IP 地址可以是用形如 www[01:50].example.com
的模式来一次指定多台. 也可以用 dynamic inventory 来用一段程序来定义一个逻辑上的 多台服务器. 例如 用 Tag 来选择 AWS EC2.
详细内容请参考:
How to build your inventory: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
Dynamic inventory: https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html
Dynamic inventory plugin for aws_ec2_inventory: https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html
Plugin¶
Collection¶
Collection 实际上就是第三方的 Plugin, 相当于编程语言的第三方库. 例如 Python 的 Library. Ansible 用来托管 Collection 的平台叫做 ansible galaxy https://galaxy.ansible.com/home. 你可以在上面 查找, 下载, 发布 你的 Collection.
Playbook¶
Playbook 定义了你在服务器上执行的操作. 其中有两个子定义 Task 和 Play. Tast 就是一些具体的操作, 例如运行 shell script, 运行 command, 拷贝文件 等. 是比较小的逻辑单元. Play 则是按顺序包含了许多 Task, 是一个比较大的逻辑单元. 而一个 Playbook 里包含了许多 Play.
Ansible 实战 - Inventory¶
参考资料:
Intro Inventory: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory
Inventory file 支持 .yml 和 .ini 两种格式. 显然 .ini 已经过时了, 我们不去学习他.
我们来看一个最简单的例子:
all: # a group name
hosts:
mail.example.com:
children:
webservers: # a group name
hosts:
foo.example.com:
bar.example.com:
dbservers: # a group name
hosts:
one.example.com:
two.example.com:
three.example.com:
Inventory 管理服务器是通过 Group (组) 来实现的. 简单来说一个 Group 包含了 一到多 台机器. 一台机器可以被多个 Group 所包含. 而 Group 内可以定义 Variables 变量, 例如 ansible 内置的变量 ansible_user
用来指定远程用户名, ansible_ssh_private_key_file
用来指定 SSH 的密钥文件. 也可以自行定义变量, 例如 http_port
.
当你在运行 playbook 的时候, 你需要在 playbook 的 yml 文件中指定 group. 被指定的 group 中的 hosts 会被 playbook 更改.
有两个默认的隐藏 Group, all, ungrouped. 所有的 host, 无论是否定义了 group name, 都会被包含在 all 这个 group 中. 而 ungrouped 则是哪些没有定义在 group name 下, 直接以 ip 地址的形式定义的所有 host.
而 group 之间又有 children 的概念. 所有的 group 会自动包含他们的 children 中定义的 hosts. 所有的 children group 也同样是 group, 可以在 playbook 中被指定. 在定义的时候请注意避免循环, 不能两个 group 互为对方的 children. 结合前面介绍的 Variables, 值得注意的是, 如果 children 和 parent 中都定义了同一个 variable, 那么以 children 的为准. 这就跟编程语言中的继承关系一样.
下面我们来看一个更复杂的例子, 在该例子中, 我们的分组逻辑是按照 what, where, when 来分组的. 而在 prod, test 组中我们就使用了 children 来避免重复定义 host.
all: # default Group name, will include all hosts appears in this file
hosts:
mail.example.com:
amazonEcommerce: # amazonEcommerce 是一个 group name, 由用户指定
children: # children 是一个 ansible 内置的 declaritive, 表示下面的 key 都被视为一个 group
# What - An application, stack or microservice (for example, database servers, web servers, and so on).
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:
# Where - A datacenter or region, to talk to local DNS, storage, and so on (for example, east, west).
east:
hosts:
foo.example.com:
one.example.com:
two.example.com:
west:
hosts:
bar.example.com:
three.example.com:
# When - The development stage, to avoid testing on production resources (for example, prod, test).
prod:
children:
east:
test:
children:
west:
Ansible 实战 - Playbook¶
Pre installed plugin: https://docs.ansible.com/ansible/latest/collections/index.html
Ansible Playbook 是 Ansible 的核心, 定义了配置服务器的各种操作.
我们来看一个例子:
# content of playbook.yml
# this is a PLAY
- name: action1
hosts: all
# this is a TASK
tasks:
- name: create a test.txt file
shell: |
echo "hello" > ~/test.txt
上面这个例子的功能是在 AWS 的一台 EC2 上, 创建一个内容为 hello
的 $HOME/test.txt
文件. 从语法上拉看, playbook 是一种 declaration language (声明式语言), 每一个 YAML 的 Key 都是由 ansible 实现的, 具有特殊的含义. 而用户主要负责填写 Value 来控制 playbook 的行为.
从结构上来看, 一个 playbook 包含了很多个 ``PLAY``, 一个 ``PLAY`` 包含了很多个 ``TASK``, 而每个 ``TASK`` 就是对服务器进行一些具体的操作, 功能的逻辑上通常不会很复杂, 不过具体的实现可以是一个简单的 单条命令, 也可以是一个非常复杂的 bash script. TASK
是 Playbook 的最小操作单位, 例如运行一些命令. 而 PLAY
则是一个比较大的逻辑概念, 比如安装, 初始化, 配置某个软件.
下面这条命令即可将 playbook 中定义的操作, 在远程机器上执行:
ansible-playbook playbook.yml -i host.yml
这里我们还提供了两个例子. 第一个是使用了 自定义的 group name; 第二个是是用来在 Children 中定义的 group name; 他们都可以在 playbook 中被引用.
ansible-playbook playbook-example-1.yml -i ./host-example-1.yml
ansible-playbook playbook-example-2.yml -i ./host-example-2.yml
Ansible 实战 - Collection¶
多数的 Collection
Ansible 实战 - CLI¶
理解 ansible 命令行如何工作¶
由于 Ansible 本质上是一个 Python 命令行程序. 通常 DevOps 工程师电脑上的 ansible 是系统级的 ansible. 也就是工程师用 package manager, 例如 Redhat 和 CentOS 上的 yum install ansible
, Ubuntu 上的 apt-get install ansible
, MacOS 上的 brew install ansible
.
而我们知道 Linux 系统上的工具对于不同的 User 是区分开来的. 例如以 Root 安装的工具其他 User 通常能使用, 例如 git. 而以其他 User 安装的工具 Root 通常不能使用, 这事为了避免用户安装的可执行文件对系统造成损害. 所以当你再打 ansible
命令时, 你要知道你实际上在用的哪个 ansible
. 你可以用 which ansible
来查询.
如果你熟悉 Python 里的 Virtualenv 的话, 你会知道你同样可以用 pip install ansible
来安装 ansible
而这个 ansible
要在同样的 Python 环境中才能使用. 例如你进入了 virtualenv 再 pip install ansible
那么你在 virtualenv 之外是无法使用的.
ansible-config
¶
ansible.cfg
File
ansible.cfg
文件控制了 ansible 的许多行为, 比如 SSH 的行为, 在哪里寻找特定文件等. 而当你执行 ansible cli 时, 你用到的是哪一个 ansible.cfg
文件呢? Ansible 默认会按照下面的顺序寻找 ansible.cfg
文件, 如果找到了, 就不去后面的位置找了. 顺序是这样的:
ANSIBLE_CONFIG
(environment variable if set)ansible.cfg
(in the current directory)~/.ansible.cfg
(in the home directory)/etc/ansible/ansible.cfg
ansible-config
是一个命令行工具, 允许你:
ansible-config list
列出所有可用的选项.ansible-config view
显示当前被使用的ansible.cfg
文件内容ansible-config dump
将你当前的 config, dump 成为新的ansible.cfg
文件, 或是与已经存在的ansible.cfg
文件中的选项合并, 如果已经存在某个 KEY, 则覆盖之.
相关文档:
Configuring Ansible: https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html
Ansible Configure Settings: https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings
ansible-config
CLI: https://docs.ansible.com/ansible/latest/cli/ansible-config.html#ansible-config