去年年底,我的团队宣布了 LinchPin,这是一个使用 Ansible 的混合云编排工具。配置云资源从未如此简单快捷。借助 Ansible 的强大功能和对简易性的关注,LinchPin 让用户可以轻松使用许多云资源。在本文中,我将介绍 LinchPin,并回顾该项目在过去 10 个月中的发展历程。
在 LinchPin 刚推出时,使用 ansible-playbook 命令运行 LinchPin 很复杂。虽然仍然可以这样做,但 LinchPin 现在有了一个新的前端命令行用户界面 (CLI),它用 Click 编写,使 LinchPin 比以前更简单。
为了不逊色于 CLI,LinchPin 现在还拥有一个 Python API,可用于管理资源,例如 Amazon EC2 和 OpenStack 实例、网络、存储、安全组等等。当您尝试 LinchPin 的 Python API 时,API 文档可能会有所帮助。
Playbook 作为库
由于 LinchPin 的核心部分是 Ansible playbook,因此角色、模块、过滤器以及与调用 Ansible 模块相关的任何其他内容都已移至 LinchPin 库中。这意味着,虽然仍然可以直接调用 playbook,但这并不是管理资源的首选机制。linchpin 可执行文件已成为命令行的事实前端。
命令行深入分析
让我们深入了解 linchpin 命令
$ linchpin
Usage: linchpin [OPTIONS] COMMAND [ARGS]...
linchpin: hybrid cloud orchestration
Options:
-c, --config PATH Path to config file
-w, --workspace PATH Use the specified workspace if the familiar Jenkins
$WORKSPACE environment variable is not set
-v, --verbose Enable verbose output
--version Prints the version and exits
--creds-path PATH Use the specified credentials path if WORKSPACE
environment variable is not set
-h, --help Show this message and exit.
Commands:
init Initializes a linchpin project.
up Provisions nodes from the given target(s) in...
destroy Destroys nodes from the given target(s) in...
立即可以看到的是一个简单的描述,以及可以传递给命令的选项和参数。本文档的重点将放在此帮助底部附近的三个命令上。
配置
过去,有一个 linchpin_config.yml 文件。此文件已不再存在,已被名为 linchpin.conf 的 ini 样式配置文件取代。虽然可以修改此文件或将其放置在其他位置,但将其放置在库路径中可以轻松查找配置。在大多数情况下,linchpin.conf 文件不需要修改。
工作区
工作区是定义的文件系统路径,允许以逻辑方式对资源进行分组。工作区可以被视为特定环境、一组服务或其他逻辑分组的单个点。它也可以是所有托管资源的一个大型存储箱。
工作区可以在命令行中使用 --workspace (-w) 选项指定,后跟工作区路径。也可以使用环境变量指定(例如,bash 中的 $WORKSPACE)。默认工作区是当前目录。
初始化 (init)
运行 linchpin init 将生成所需的目录结构,以及示例 PinFile、topology 和 layout 文件
$ export WORKSPACE=/tmp/workspace
$ linchpin init
PinFile and file structure created at /tmp/workspace
$ cd /tmp/workspace/
$ tree
.
├── credentials
├── hooks
├── inventories
├── layouts
│ └── example-layout.yml
├── PinFile
├── resources
└── topologies
└── example-topology.yml
此时,可以执行 linchpin up 并配置单个 libvirt 虚拟机,网络名为 linchpin-centos71。将生成清单并将其放置在 inventories/libvirt.inventory 中。这可以通过读取 topologies/example-topology.yml 并从中提取 topology_name 值来获知。
配置 (linchpin up)
一旦 PinFile、topology 和可选的 layout 文件就位,就可以进行配置。
我们使用 dummy 工具,因为它配置起来更简单;它不需要任何额外的东西(身份验证、网络等)。dummy 提供程序创建一个临时文件,表示已配置的主机。如果临时文件没有任何数据,则说明主机尚未配置,或者最近已被销毁。
dummy 提供程序的树结构很简单
$ tree
.
├── hooks
├── inventories
├── layouts
│ └── dummy-layout.yml
├── PinFile
├── resources
└── topologies
└── dummy-cluster.yml
PinFile 也很简单;它指定要用于 dummy1 目标的 topology 和可选的 layout
---
dummy1:
topology: dummy-cluster.yml
layout: dummy-layout.yml
dummy-cluster.yml topology 文件是对配置三个 (3) dummy_node 类型资源的引用
---
topology_name: "dummy_cluster" # topology name
resource_groups:
-
resource_group_name: "dummy"
resource_group_type: "dummy"
resource_definitions:
-
name: "web"
type: "dummy_node"
count: 3
执行命令 linchpin up 应根据 topology_name(在本例中为 dummy_cluster)生成 resources 和 inventory 文件
$ linchpin up
target: dummy1, action: up
$ ls {resources,inventories}/dummy*
inventories/dummy_cluster.inventory resources/dummy_cluster.output
要使用 dummy 集群验证资源,请检查 /tmp/dummy.hosts
$ cat /tmp/dummy.hosts
web-0.example.net
web-1.example.net
web-2.example.net
Dummy 模块为模拟(或 dummy)配置提供了一个基本工具。请查看 LinchPin 示例中有关 OpenStack、AWS EC2、Google Cloud 等的详细信息。
清单生成
作为上述 PinFile 的一部分,可以指定 layout。如果指定了此文件并且该文件位于正确的位置,则将为已配置的资源自动生成 Ansible 静态清单文件
---
inventory_layout:
vars:
hostname: __IP__
hosts:
example-node:
count: 3
host_groups:
- example
当 linchpin up 执行完成时,resources 文件会提供有用的详细信息。具体而言,IP 地址或主机名将被插入到静态清单中
[example]
web-2.example.net hostname=web-2.example.net
web-1.example.net hostname=web-1.example.net
web-0.example.net hostname=web-0.example.net
[all]
web-2.example.net hostname=web-2.example.net
web-1.example.net hostname=web-1.example.net
web-0.example.net hostname=web-0.example.net
拆除 (linchpin destroy)
LinchPin 还可以执行资源的拆除。拆除操作通常期望资源已被配置;但是,由于 Ansible 是幂等的,linchpin destroy 只会检查以确保资源已启动。只有当资源已启动时,才会发生拆除。
命令 linchpin destroy 将使用 resources 和/或 topology 文件来确定正确的拆除程序。
dummy Ansible 角色不使用 resources,拆除期间仅使用 topology
$ linchpin destroy
target: dummy1, action: destroy
$ cat /tmp/dummy.hosts
-- EMPTY FILE --
拆除功能在临时资源(如网络、存储等)方面略有限制。网络资源可能与多个云实例一起使用。这样,执行 linchpin destroy 不会拆除某些资源。这取决于每个提供程序的实现。请参阅每个 提供程序的特定实现。
LinchPin Python API
在 linchpin 命令行工具中实现的许多功能都是使用 Python API 编写的。API 虽然不完整,但已成为 LinchPin 工具的重要组成部分。
API 由三个包组成
- linchpin
- linchpin.cli
- linchpin.api
命令行工具在基本 linchpin 包中进行管理;它导入 linchpin.cli 模块和类,这是 linchpin.api 的子类。这样做的目的是允许使用 linchpin.api 实现 LinchPin 的其他可能实现,例如计划中的 RESTful API。
有关更多信息,请参阅 Read the Docs 上的 Python API 库文档。
钩子
LinchPin 1.0 未来版本中的重大改进之一是钩子。钩子的目标是在 linchpin 执行期间的某些特定状态下,允许使用外部资源进行其他配置。当前的状态如下:
- preup:在配置 topology 资源之前执行
- postup:在配置 topology 资源并生成可选清单后执行
- predestroy:在拆除 topology 资源之前执行
- postdestroy:在拆除 topology 资源之后执行
在每种情况下,这些钩子都允许外部脚本运行。存在多种类型的钩子,包括称为操作管理器的自定义钩子。以下是内置操作管理器的列表:
- shell:允许内联 shell 命令或可执行 shell 脚本
- python:执行 Python 脚本
- ansible:执行 Ansible playbook,允许传递表示为 Python 字典的 vars_file 和 extra_vars
- nodejs:执行 Node.js 脚本
- ruby:执行 Ruby 脚本
钩子绑定到特定目标,并且必须为每个使用的目标重新声明。将来,钩子将能够是全局的,然后可以在每个目标的 hooks 部分中更简单地命名。
使用钩子
描述钩子很简单,但理解它们的功能可能并不那么简单。此功能的存在是为了为用户提供灵活的功能,以处理 LinchPin 开发人员可能未考虑到的事情。例如,此概念可能会带来一种简单的方法来 ping 一组系统,然后再运行另一个钩子。
更仔细地查看工作区,您可能会注意到 hooks 目录。让我们看看这个目录内部以了解结构
$ tree hooks/
hooks/
├── ansible
│ ├── ping
│ │ └── dummy_ping.yaml
└── shell
└── database
├── init_db.sh
└── setup_db.sh
在每种情况下,都可以在 PinFile 中使用钩子,如下所示
---
dummy1:
topology: dummy-cluster.yml
layout: dummy-layout.yml
hooks:
postup:
- name: ping
type: ansible
actions:
- dummy_ping.yaml
- name: database
type: shell
actions:
- setup_db.sh
- init_db.sh
基本概念是需要完成三个 postup 操作。钩子按自上而下的顺序执行。因此,Ansible ping 任务将首先运行,然后是两个 shell 任务,setup_db.sh,然后是 init_db.sh。假设钩子执行成功,将对系统进行 ping 操作,然后将设置并初始化数据库。
身份验证驱动程序
在 LinchPin 的初始设计中,开发人员决定在 Ansible playbook 中管理身份验证;但是,转向更以 API 和命令行驱动的工具意味着身份验证应该在 playbook 现在所在的库之外,并且仍然根据需要传递身份验证值。
配置
让用户使用所用驱动程序提供的身份验证方法完成了此任务。例如,如果 topology 调用 OpenStack,则标准方法是使用 yaml 文件或类似的 OS_ 前缀环境变量。clouds.yaml 文件由一个配置文件组成,其中包含 auth 部分
clouds:
default:
auth:
auth_url: http://stack.example.com:5000/v2.0/
project_name: factory2
username: factory-user
password: password-is-not-a-good-password
更多详细信息请参见 OpenStack 文档。
此 clouds.yaml(或任何其他身份验证文件)位于 default_credentials_path(例如,~/.config/linchpin)中,并在 topology 中引用
---
topology_name: openstack-test
resource_groups:
-
resource_group_name: linchpin
resource_group_type: openstack
resource_definitions:
- name: resource
type: os_server
flavor: m1.small
image: rhel-7.2-server-x86_64-released
count: 1
keypair: test-key
networks:
- test-net2
fip_pool: 10.0.72.0/24
credentials:
filename: clouds.yaml
profile: default
可以通过修改 linchpin.conf 来更改 default_credentials_path。
topology 在底部包含一个新的 credentials 部分。使用 openstack、ec2 和 gcloud 模块,可以类似地指定凭据。然后,身份验证驱动程序将在给定的文件名 clouds.yaml 中查找,并搜索名为 default 的配置文件。
假设找到并加载了身份验证,配置将继续正常进行。
简易性
尽管 LinchPin 在 topology、清单布局、钩子和身份验证管理方面可能很复杂,但最终目标是简易性。通过使用命令行界面进行简化,以及改进 1.0 版本后开发人员体验的目标,LinchPin 继续展示复杂配置可以通过简易性进行管理。
社区发展
在过去一年中,LinchPin 的社区不断壮大,以至于我们现在拥有一个邮件列表、一个 IRC 频道 (#linchpin on chat.freenode.net),甚至使用 GitHub 以开放方式管理我们的冲刺。
社区成员数量已大幅增长——从 2 个核心开发人员到过去一年中的约 10 位贡献者。越来越多的人继续参与该项目。如果您对 LinchPin 感兴趣,请给我们留言、在 GitHub 上提交 issue、加入 IRC 或给我们发送电子邮件。
本文基于 Clint Savage 在 OpenWest 上的演讲,LinchPin 介绍:使用 Ansible 的混合云配置。OpenWest 将于 2017 年 7 月 12 日至 15 日在犹他州盐湖城举行。
评论已关闭。