作者 | Clint Savage
譯者 | qhwdw
2016 年末開始的 LinchPin,現在已經擁有一個 Python API 和一個成長中的社群。
去年,我的團隊公佈了[1] LinchPin[2],這是一個使用 Ansible 的混合雲編配工具。配給雲資源從來沒有這麼容易便捷過。藉助 Ansible 強力支援,LinchPin 專註於簡化,使雲資源讓使用者可以觸手可及。在這篇文章中,我將介紹 LinchPin,並且去看看過去的 10 個月該專案是如何逐漸成熟。
(LCTT 譯註:關於 orchestration 應該翻譯成慣例的“編排”還是“編配”,有個 @wffger 提出的建議[3] ,歡迎大家參與討論。)
LinchPin 剛出現的時候,使用 ansible-playbook
命令去執行 LinchPin ,雖然可以完成,但是還是很複雜的,LinchPin 現在有一個前端命令列使用者介面(CLI),它是用 Click[4]寫的,而且它使 LinchPin 比以前更簡化。
沒有止步於 CLI,LinchPin 現在還有一個 Python[5] API,它可以用於管理資源,比如,Amazon EC2 和 OpenStack 實體、網路、儲存、安全組等等。這個 API 檔案[6] 可以在你想去嘗試 LinchPin 的 Python API 時幫助你。
Playbook 是一個庫
因為 LinchPin 的核心是 Ansible playbook[7],其角色、模組、過濾器,以及任何被稱為 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
的檔案。但現在這個檔案沒有了,替換它的是一個 ini 形式的配置檔案,稱為 linchpin.conf
。雖然這個檔案可以被修改或放到別的地方,它可以放置在配置檔案容易找到的庫路徑中。在多數情況下,linchpin.conf
檔案是不需要去修改的。
工作空間
工作空間是一個定義好的檔案系統路徑,它是一個邏輯上的資源組。一個工作空間可以認為是一個特定環境、服務組、或其它邏輯組的一個單點。它也可以是一個所有可管理資源的大的儲存容器。
工作空間可以在命令列上使用 --workspace
(-w
) 選項去指定,隨後是工作空間路徑。它也可以使用環境變數指定(比如,bash 中的 $WORKSPACE
)。預設工作空間是當前目錄。
初始化 (linchpin 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、拓撲、和一個可選的佈局,就可以配給了。
我們使用 dummy (模擬)工具,因為用它來配給非常簡單;它不需要任何額外的東西(認證、網路、等等)。dummy 配給程式會建立一個臨時檔案,它表示所配給的主機。如果臨時檔案沒有任何資料,說明主機沒有被配給,或者它已經被銷毀了。
dummy 配給程式的目錄樹大致如下:
$ tree
.
├── hooks
├── inventories
├── layouts
│ └── dummy-layout.yml
├── PinFile
├── resources
└── topologies
└── dummy-cluster.yml
PinFile 也很簡單;它指定了它的拓撲,並且為 dummy1
標的提供一個可選的佈局:
---
dummy1:
topology: dummy-cluster.yml
layout: dummy-layout.yml
dummy-cluster.yml
拓撲檔案是一個取用,指向到配給的三個 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 模組為假定的(或模擬的)配給提供了一個基本工具。關於在 OpenStack、AWS EC2、Google Cloud 上和 LinchPin 的更多詳細情況,可以去看示例[8]。
庫存生成
作為上面提到的 PinFile 的一部分,可以指定一個 layout
。如果這個檔案被指定,並且放在一個正確的位置上,就會為配給的資源自動生成一個用於 Ansible 的靜態庫存檔案:
---
inventory_layout:
vars:
hostname: __IP__
hosts:
example-node:
count: 3
host_groups:
- example
當 linchpin up
執行完成,資源檔案將提供一個很有用的詳細資訊。特別是,插入到靜態庫存的 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
也將使用資源和/或拓撲檔案去決定合適的解除安裝過程。
Ansible dummy
角色不使用資源,解除安裝期間僅有拓撲:
$ linchpin destroy
target: dummy1, action: destroy
$ cat /tmp/dummy.hosts
-- EMPTY FILE --
針對暫時的資源,解除安裝功能有一些限制,像網路、儲存、等等。網路資源可以被用於多個雲實體。在這種情況下,執行一個 linchpin destroy
某些資源就不能解除安裝。這取決於每個供應商的實現。檢視每個供應商[9]的具體實現。
LinchPin 的 Python API
在 linchpin
命令列中實現的功能大多數都是用 Python API 寫的。這個 API,雖然不完整,但它已經成為 LinchPin 工具的至關重要的元件。
這個 API 由下麵的三個包組成:
linchpin
linchpin.cli
linchpin.api
該命令列工具是基於 linchpin
包來管理的。它匯入了 linchpin.cli
模組和類,該類是 linchpin.api
的子類。這樣做的目的是為了允許使用 linchpin.api
來做其它的 LinchPin 實現,比如像計劃中的 RESTful API。
更多資訊,去檢視 Python API library documentation on Read the Docs[6]。
Hook
LinchPin 1.0 的其中一個大的變化是轉向 hook。hook 的標的是在 linchpin
執行期間的特定狀態下,允許配置使用更多外部資源。目前的狀態有:
preup
: 在配給拓撲資源之前執行postup
: 在配給拓撲資源之後執行,並且生成可選的庫存predestroy
: 解除安裝拓撲資源之前執行postdestroy
: 解除安裝拓撲資源之後執行在每種狀態下,這些 hooks 允許執行外部指令碼。存在幾種型別的 hook,包括一個定製的叫做 Action Managers。這是一個內建的 Action Manager 的串列:
shell
: 允許任何的行內的 shell 命令,或者一個可執行的 shell 指令碼python
: 執行一個 Python 指令碼ansible
: 執行一個 Ansible playbook,允許傳遞一個 vars_file
和 extra_vars
作為 Python 字典nodejs
: 執行一個 Node.js 指令碼ruby
: 執行一個 Ruby 指令碼hook 被系結到一個特定的標的,並且每個標的使用時必須重新宣告。將來,hook 將可能是全域性的,然後它們在每個標的的 hooks
節下命名會更簡單。
使用 hook
hook 描述起來非常簡單,但理解它們強大的功能卻並不簡單。這個特性的存在是為了給使用者靈活提供那些 LinchPin 開發者所沒有考慮到的功能。這個概念可能會帶來 ping 一套系統的簡單方式,舉個實體,比如在執行另一個 hook 之前。
更仔細地去研究 工作空間 ,你可能會註意到 hooks
目錄,讓我們看一下這個目錄的結構:
$ tree hooks/
hooks/
├── ansible
│ ├── ping
│ │ └── dummy_ping.yaml
└── shell
└── database
├── init_db.sh
└── setup_db.sh
在任何情況下,hook 都可以用在 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 動作要完成。Hook 是從上到下執行的,因此,Ansible ping
任務將首先執行,緊接著是兩個 shell 任務, setup_db.sh
和 init_db.sh
。假設 hook 執行成功。將發生一個系統的 ping,然後,一個資料庫被安裝和初始化。
認證的驅動程式
在 LinchPin 的最初設計中,開發者決定在 Ansible playbooks 中管理認證;然而,逐漸有更多的 API 和命令列驅動的工具後,意味著認證將被置於 playbooks 庫之外,並且還可以根據需要去傳遞認證值。
配置
讓使用者使用驅動程式提供的認證方法去完成這個任務。舉個實體,如果對於 OpenStack 呼叫的拓撲,標準方法是使用一個 yaml 檔案,或者類似於 OS_
字首的環境變數。clouds.yaml
檔案是一個 profile 檔案的組成部分,它有一個 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 documentation[10]。
這個 clouds.yaml
或者任何其它認證檔案位於 default_credentials_path
(比如,~/.config/linchpin
)中,併在拓撲中取用:
---
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
default_credentials_path
可以透過修改 linchpin.conf
改變。
拓撲在底部包含一個新的 credentials
節。使用 openstack
、ec2
、和 gcloud
模組,也可以去指定類似的憑據。認證驅動程式將檢視給定的名為 clouds.yaml
的檔案,並搜尋名為 default
的 配置。
假設認證被找到並被載入,配給將正常繼續。
簡化
雖然 LinchPin 可以完成複雜的拓撲、庫存佈局、hooks、和認證管理,但是,終極標的是簡化。透過使用一個命令列介面的簡化,除了提升已經完成的 1.0 版的開發者體驗外,LinchPin 將持續去展示覆雜的配置可以很簡單地去管理。
社群的成長
在過去的一年中,LinchPin 的社群現在已經有了 郵件串列[11]和一個 IRC 頻道(#linchpin on chat.freenode.net,而且在 GitHub[12] 中我們很努力地管理它。
在過去的一年裡,社群成員已經從 2 位核心開發者增加到大約 10 位貢獻者。更多的人持續參與到專案中。如果你對 LinchPin 感興趣,可以給我們寫信、在 GitHub 上提問,加入 IRC,或者給我們發郵件。
這篇文章是基於 Clint Savage 在 OpenWest 上的演講 Introducing LinchPin: Hybrid cloud provisioning using Ansible[13] 整理的。OpenWest[14] 將在 2017 年 7 月 12-15 日在鹽城湖市舉行。
作者簡介:
Clint Savage - 工作於 Red Hat 是一位負責原子專案(Project Atomic)的高階軟體工程師。他的工作是為 Fedora、CentOS、和 Red Hat Enterprise Linux(RHEL)提供自動原子伺服器構建。
via: https://opensource.com/article/17/6/linchpin
作者:Clint Savage[16] 譯者:qhwdw 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出