如何使用Ansible安裝軟件
使用 Ansible 劇本自動(dòng)安裝和更新設(shè)備上的軟件。
Ansible 是系統(tǒng)管理員和開(kāi)發(fā)人員用來(lái)保持計(jì)算機(jī)系統(tǒng)處于最佳狀態(tài)的一種流行的自動(dòng)化工具。與可擴(kuò)展框架一樣,Ansible 本身功能有限,它真正的功能體現(xiàn)在許多模塊中。在某種程度上,Ansible 模塊就是 Linux 系統(tǒng)的命令。它們針對(duì)特定問(wèn)題提供解決方案,而維護(hù)計(jì)算機(jī)時(shí)的一項(xiàng)常見(jiàn)任務(wù)是使所有計(jì)算機(jī)的更新和一致。
我曾經(jīng)使用軟件包的文本列表來(lái)保持系統(tǒng)或多或少的同步:我會(huì)列出筆記本電腦上安裝的軟件包,然后將其與臺(tái)式機(jī)或另一臺(tái)服務(wù)器之間進(jìn)行交叉參考,手動(dòng)彌補(bǔ)差異。當(dāng)然,在 Linux 機(jī)器上安裝和維護(hù)應(yīng)用程序是 Ansible 的一項(xiàng)基本功能,這意味著你可以在自己關(guān)心的計(jì)算機(jī)上列出所需的內(nèi)容。
尋找正確的 Ansible 模塊
Ansible 模塊的數(shù)量非常龐大,如何找到能完成你任務(wù)的模塊?在 Linux 中,你可以在應(yīng)用程序菜單或 /usr/bin
中查找要運(yùn)行的應(yīng)用程序。使用 Ansible 時(shí),你可以參考 Ansible 模塊索引。
這個(gè)索引按照類別列出。稍加搜索,你就很可能找到所需的模塊。對(duì)于包管理,Packaging 模塊幾乎適用于所有帶包管理器的系統(tǒng)。
動(dòng)手寫(xiě)一個(gè) Ansible 劇本
首先,選擇本地計(jì)算機(jī)上的包管理器。例如,如果你打算在運(yùn)行 Fedora 的筆記本電腦上編寫(xiě) Ansible 指令(在 Ansible 中稱為“劇本”),那么從 dnf
模塊開(kāi)始。如果你在 Elementary OS 上編寫(xiě),使用 apt
模塊,以此類推。這樣你就可以開(kāi)始進(jìn)行測(cè)試和驗(yàn)證,并可以在以后擴(kuò)展到其它計(jì)算機(jī)。
第一步是創(chuàng)建一個(gè)代表你的劇本的目錄。這不是絕對(duì)必要的,但這是一個(gè)好習(xí)慣。Ansible 只需要一個(gè)配置文件就可以運(yùn)行在 YAML 中,但是如果你以后想要擴(kuò)展劇本,你就可以通過(guò)改變目錄和文件的方式來(lái)控制 Ansible?,F(xiàn)在,只需創(chuàng)建一個(gè)名為 install_packages
或類似的目錄:
$ mkdir ~/install_packages
你可以根據(jù)自己的喜好來(lái)命名 Ansible 的劇本,但通常將其命名為 site.yml
:
$ touch ~/install_packages/site.yml
在你最喜歡的文本編輯器中打開(kāi) site.yml
,添加以下內(nèi)容:
---
- hosts: localhost
tasks:
- name: install packages
become: true
become_user: root
dnf:
state: present
name:
- tcsh
- htop
你必須調(diào)整使用的模塊名稱以匹配你使用的發(fā)行版。在此示例中,我使用 dnf
是因?yàn)槲以?Fedora Linux 上編寫(xiě)劇本。
就像 Linux 終端中的命令一樣,知道 如何 來(lái)調(diào)用 Ansible 模塊就已經(jīng)成功了一半。這個(gè)示例劇本遵循標(biāo)準(zhǔn)劇本格式:
hosts
是一臺(tái)或多臺(tái)計(jì)算機(jī)。在本示例中,目標(biāo)計(jì)算機(jī)是localhost
,即你當(dāng)前正在使用的計(jì)算機(jī)(而不是你希望 Ansible 連接的遠(yuǎn)程系統(tǒng))。tasks
是你要在主機(jī)上執(zhí)行的任務(wù)列表。name
是任務(wù)的人性化名稱。在這種情況下,我使用install packages
,因?yàn)檫@就是該任務(wù)正在做的事情。become
允許 Ansible 更改運(yùn)行此任務(wù)的用戶。become_user
允許 Ansible 成為root
用戶來(lái)運(yùn)行此任務(wù)。這是必須的,因?yàn)橹挥?root 用戶才能使用dnf
安裝應(yīng)用程序。dnf
是模塊名稱,你可以在 Ansible 網(wǎng)站上的模塊索引中找到。
dnf
下的節(jié)點(diǎn)是 dnf
模塊專用的。這是模塊文檔的關(guān)鍵所在。就像 Linux 命令的手冊(cè)頁(yè)一樣,模塊文檔會(huì)告訴你可用的選項(xiàng)和所需的參數(shù)。
Ansible 文檔
安裝軟件包是一個(gè)相對(duì)簡(jiǎn)單的任務(wù),僅需要兩個(gè)元素。state
選項(xiàng)指示 Ansible 檢查系統(tǒng)上是否存在 軟件包,而 name
選項(xiàng)列出要查找的軟件包。Ansible 會(huì)針對(duì)機(jī)器的 狀態(tài) 進(jìn)行調(diào)整,因此模塊指令始終意味著更改。假如 Ansible 掃描了系統(tǒng)狀態(tài),發(fā)現(xiàn)劇本里描述的系統(tǒng)(在本例中,tcsh
和 htop
存在)與實(shí)際狀態(tài)存在沖突,那么 Ansible 的任務(wù)是進(jìn)行必要的更改來(lái)使系統(tǒng)與劇本匹配。Ansible 可以通過(guò) dnf
(或 apt
或者其它任何包管理器)模塊進(jìn)行更改。
每個(gè)模塊可能都有一組不同的選項(xiàng),所以在編寫(xiě)劇本時(shí),要經(jīng)常參考模塊文檔。除非你對(duì)模塊非常熟悉,否則這是期望模塊完成工作的唯一合理方法。
驗(yàn)證 YAML
劇本是用 YAML 編寫(xiě)的。因?yàn)?YAML 遵循嚴(yán)格的語(yǔ)法,所以安裝 yamllint
來(lái)檢查劇本是很有幫助的。更妙的是,有一個(gè)專門針對(duì) Ansible 的檢查工具稱為 ansible-lint
,它專門為劇本而生。在繼續(xù)之前,安裝它。
在 Fedora 或 CentOs 上:
$ sudo dnf ins tall yamllint python3-ansible-lint
在 Debian、Elementary 或 Ubuntu 上,同樣的:
$ sudo apt install yamllint ansible-lint
使用 ansible-link
來(lái)驗(yàn)證你的劇本。如果你無(wú)法使用 ansible-lint
,你可以使用 yamllint
。
$ ansible-lint ~/install_packages/site.yml
成功則不返回任何內(nèi)容,但如果文件中有錯(cuò)誤,則必須先修復(fù)它們,然后再繼續(xù)。復(fù)制和粘貼過(guò)程中的常見(jiàn)錯(cuò)誤包括在最后一行的末尾省略換行符、使用制表符而不是空格來(lái)縮進(jìn)。在文本編輯器中修復(fù)它們,重新運(yùn)行 ansible-llint
,重復(fù)這個(gè)過(guò)程,直到 ansible-lint
或 yamllint
沒(méi)有返回為止。
使用 Ansible 安裝一個(gè)應(yīng)用
現(xiàn)在你有了一個(gè)可驗(yàn)證的有效劇本,你終于可以在本地計(jì)算機(jī)上運(yùn)行它了,因?yàn)槟闩銮芍涝搫”径x的任務(wù)需要 root 權(quán)限,所以在調(diào)用 Ansible 時(shí)必須使用 --ask-become-pass
選項(xiàng),因此系統(tǒng)會(huì)提示你輸入管理員密碼。
開(kāi)始安裝:
$ ansible-playbook --ask-become-pass ~/install_packages/site.yml
BECOME password:
PLAY [localhost] ******************************
TASK [Gathering Facts] ******************************
ok: [localhost]
TASK [install packages] ******************************
ok: [localhost]
PLAY RECAP ******************************
localhost: ok=0 changed=2 unreachable=0 failed=0 [...]
這些命令被執(zhí)行后,目標(biāo)系統(tǒng)將處于與劇本中描述的相同的狀態(tài)。
在遠(yuǎn)程系統(tǒng)上安裝應(yīng)用程序
通過(guò)這么多操作來(lái)替換一個(gè)簡(jiǎn)單的命令可能會(huì)適得其反,但是 Ansible 的優(yōu)勢(shì)是它可以在你的所有系統(tǒng)中實(shí)現(xiàn)自動(dòng)化。你可以使用條件語(yǔ)句使 Ansible 在不同的系統(tǒng)上使用特定的模塊,但是現(xiàn)在,假定所有計(jì)算機(jī)都使用相同的包管理器。
要連接到遠(yuǎn)程系統(tǒng),你必須在 /etc/ansible/hosts
文件中定義遠(yuǎn)程系統(tǒng),該文件與 Ansible 是一起安裝的,所以它已經(jīng)存在了,但它可能是空的,除了一些解釋性注釋之外。使用 sudo
在你喜歡的文本編輯器中打開(kāi)它。
你可以通過(guò)其 IP 地址或主機(jī)名(只要主機(jī)名可以解析)定義主機(jī)。例如,如果你已經(jīng)在 /etc/hosts
中定義了 liavara
并可以成功 ping
通,那么你可以在 /etc/ansible/hosts
中將 liavara
設(shè)置為主機(jī)。或者,如果你正在運(yùn)行一個(gè)域名服務(wù)器或 Avahi 服務(wù)器并且可以 ping
通 liavara
,那么你就可以在 /etc/ansible/hosts
中定義它。否則,你必須使用它的 IP 地址。
你還必須成功地建立與目標(biāo)主機(jī)的安全 shell(SSH)連接。最簡(jiǎn)單的方法是使用 ssh-copy-id
命令,但是如果你以前從未與主機(jī)建立 SSH 連接,閱讀我關(guān)于如何創(chuàng)建自動(dòng) SSH 連接的文章。
一旦你在 /etc/ansible/hosts
文件中輸入了主機(jī)名或 IP 地址后,你就可以在劇本中更改 hosts
定義:
---
- hosts: all
tasks:
- name: install packages
become: true
become_user: root
dnf:
state: present
name:
- tcsh
- htop
再次運(yùn)行 ansible-playbook
:
$ ansible-playbook --ask-become-pass ~/install_packages/site.yml
這次,劇本會(huì)在你的遠(yuǎn)程系統(tǒng)上運(yùn)行。
如果你添加更多主機(jī),則有許多方法可以過(guò)濾哪個(gè)主機(jī)執(zhí)行哪個(gè)任務(wù)。例如,你可以創(chuàng)建主機(jī)組(服務(wù)器的 webserves
,臺(tái)式機(jī)的 workstations
等)。
適用于混合環(huán)境的 Ansible
到目前為止,我們一直假定 Ansible 配置的所有主機(jī)都運(yùn)行相同的操作系統(tǒng)(都是是使用 dnf
命令進(jìn)行程序包管理的操作系統(tǒng))。那么,如果你要管理不同發(fā)行版的主機(jī),例如 Ubuntu(使用 apt
)或 Arch(使用 pacman
),或者其它的操作系統(tǒng)時(shí),該怎么辦?
只要目標(biāo)操作系統(tǒng)具有程序包管理器(MacOs 有 Homebrew,Windows 有 Chocolatey),Ansible 就能派上用場(chǎng)。
這就是 Ansible 優(yōu)勢(shì)最明顯的地方。在 shell 腳本中,你必須檢查目標(biāo)主機(jī)上有哪些可用的包管理器,即使使用純 Python,也必須檢查操作系統(tǒng)。Ansible 不僅內(nèi)置了這些功能,而且還具有在劇本中使用命令結(jié)果的機(jī)制。你可以使用 action
關(guān)鍵字來(lái)執(zhí)行由 Ansible 事實(shí)收集子系統(tǒng)提供的變量定義的任務(wù),而不是使用 dnf
模塊。
---
- hosts: all
tasks:
- name: install packages
become: true
become_user: root
action: >
{{ ansible_pkg_mgr }} name=htop,transmission state=present update_cache=yes
action
關(guān)鍵字會(huì)加載目標(biāo)插件。在本例中,它使用了 ansible_pkg_mgr
變量,該變量由 Ansible 在初始 收集信息 期間填充。你不需要告訴 Ansible 收集有關(guān)其運(yùn)行操作系統(tǒng)的事實(shí),所以很容易忽略這一點(diǎn),但是當(dāng)你運(yùn)行一個(gè)劇本時(shí),你會(huì)在默認(rèn)輸出中看到它:
TASK [Gathering Facts] *****************************************
ok: [localhost]
action
插件使用來(lái)自這個(gè)探針的信息,使用相關(guān)的包管理器命令填充 ansible_pkg_mgr
,以安裝在 name
參數(shù)之后列出的程序包。使用 8 行代碼,你可以克服在其它腳本選項(xiàng)中很少允許的復(fù)雜跨平臺(tái)難題。
使用 Ansible
現(xiàn)在是 21 世紀(jì),我們都希望我們的計(jì)算機(jī)設(shè)備能夠互聯(lián)并且相對(duì)一致。無(wú)論你維護(hù)的是兩臺(tái)還是 200 臺(tái)計(jì)算機(jī),你都不必一次又一次地執(zhí)行相同的維護(hù)任務(wù)。使用 Ansible 來(lái)同步生活中的計(jì)算機(jī)設(shè)備,看看 Ansible 還能為你做些什么。