LinchPin:使用 Ansible 的简化云编排工具

LinchPin 于 2016 年底发布,现在拥有 Python API 和不断壮大的社区。
370 位读者喜欢这篇文章。
9 Lessons from 25 Years of Linux Kernel development

Internet Archive Book Images。由 Opensource.com 修改。CC BY-SA 4.0

去年年底,我的团队宣布了 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 将生成所需的目录结构,以及示例 PinFiletopologylayout 文件

$ 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)生成 resourcesinventory 文件

$ 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_fileextra_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 部分。使用 openstackec2gcloud 模块,可以类似地指定凭据。然后,身份验证驱动程序将在给定的文件名 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 日在犹他州盐湖城举行。

User profile image.
Clint Savage 在 Red Hat 担任 Project Atomic 的高级软件工程师。他的工作包括为 Fedora、CentOS 和 Red Hat Enterprise Linux (RHEL) 自动化 Atomic 服务器构建。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.