歡迎光臨
每天分享高質量文章

使用 Ansible 讓你的系統管理自動化 | Linux 中國

遠程管理工具有很多,SaltStack、Puppet、Chef,以及 Ansible 都是很流行的選擇。在本文中,我將重點放在 Ansible 上並會解釋它是如何幫到你的,不管你是有 5 台還是 1000 台虛擬機。
— Steve Ovens


本文導航
編譯自 | https://opensource.com/article/17/7/automate-sysadmin-ansible 
 作者 | Steve Ovens
 譯者 | DarkSun

精進你的系統管理能力和 Linux 技能,學習如何設置工具來簡化管理多台機器。

你是否想精進你的系統管理能力和 Linux 技能?也許你的本地局域網上跑了一些東西,而你又想讓生活更輕鬆一點–那該怎麼辦呢?在本文中,我會向你演示如何設置工具來簡化管理多台機器。

遠程管理工具有很多,SaltStack、Puppet、Chef,以及 Ansible 都是很流行的選擇。在本文中,我將重點放在 Ansible 上並會解釋它是如何幫到你的,不管你是有 5 台還是 1000 台虛擬機。

讓我們從多機(不管這些機器是虛擬的還是物理的)的基本管理開始。我假設你知道要做什麼,有基礎的 Linux 管理技能(至少要有能找出執行每個任務具體步驟的能力)。我會向你演示如何使用這一工具,而是否使用它由你自己決定。

什麼是 Ansible?

Ansible 的網站上將之解釋為 “一個超級簡單的 IT 自動化引擎,可以自動進行雲供給、配置管理、應用部署、服務內部編排,以及其他很多 IT 需求。” 通過在一個集中的位置定義好服務器集合,Ansible 可以在多個服務器上執行相同的任務。

如果你對 Bash 的 for 迴圈很熟悉,你會發現 Ansible 操作跟這很類似。區別在於 Ansible 是幕等的idempotent。通俗來說就是 Ansible 一般只有在確實會發生改變時才執行所請求的動作。比如,假設你執行一個 Bash 的 for 迴圈來為多個機器創建用戶,像這樣子:

  1. for server in serverA serverB serverC; do ssh ${server} "useradd myuser"; done

這會在 serverA、serverB,以及 serverC 上創建 myuser 用戶;然而不管這個用戶是否存在,每次運行這個 for 迴圈時都會執行 useradd 命令。一個幕等的系統會首先檢查用戶是否存在,只有在不存在的情況下才會去創建它。當然,這個例子很簡單,但是幕等工具的好處將會隨著時間的推移變得越發明顯。

Ansible 是如何工作的?

Ansible 會將 Ansible playbooks 轉換成通過 SSH 運行的命令,這在管理類 UNIX 環境時有很多優勢:

☉ 絕大多數類 UNIX 機器預設都開了 SSH。
☉ 依賴 SSH 意味著遠程主機不需要有代理。
☉ 大多數情況下都無需安裝額外的軟體,Ansible 需要 2.6 或更新版本的 Python。而絕大多數 Linux 發行版預設都安裝了這一版本(或者更新版本)的 Python。
☉ Ansible 無需主節點。他可以在任何安裝有 Ansible 並能通過 SSH 訪問的主機上運行。
☉ 雖然可以在 cron 中運行 Ansible,但預設情況下,Ansible 只會在你明確要求的情況下運行。

配置 SSH 密鑰認證

使用 Ansible 的一種常用方法是配置無需密碼的 SSH 密鑰登錄以方便管理。(可以使用 Ansible Vault 來為密碼等敏感信息提供保護,但這不在本文的討論範圍之內)。現在只需要使用下麵命令來生成一個 SSH 密鑰,如示例 1 所示。

  1. [09:44 user ~]$ ssh-keygen

  2. Generating public/private rsa key pair

  3. Enter file in which to save the key (/home/user/.ssh/id_rsa):

  4. Created directory '/home/user/.ssh'

  5. Enter passphrase (empty for no passphrase):

  6. Enter same passphrase again:

  7. Your identification has been saved in /home/user/.ssh/id_rsa

  8. Your public key has been saved in /home/user/.ssh/id_rsa.pub

  9. The key fingerprint is:

  10. SHA256:TpMyzf4qGqXmx3aqZijVv7vO9zGnVXsh6dPbXAZ+LUQ user@user-fedora

  11. The key's randomart image is:

  12. +---[RSA 2048]----+

  13. |                 |

  14. |                 |

  15. |              E  |

  16. |       o .   .。|

  17. |   .  + S    o+。|

  18. |  . .o * .  .+ooo|

  19. | . .+o  o o oo+。*|

  20. |。.ooo* o。*  .*+|

  21. | . o+*BO.o+    .o|

  22. +----[SHA256]-----+

示例 1 :生成一個 SSH 密鑰

在示例 1 中,直接按下回車鍵來接受預設值。任何非特權用戶都能生成 SSH 密鑰,也能安裝到遠程系統中任何用戶的 SSH 的 authorized_keys 檔案中。生成密鑰後,還需要將之拷貝到遠程主機上去,運行下麵命令:

  1. ssh-copy-id root@servera

註意:運行 Ansible 本身無需 root 權限;然而如果你使用非 root 用戶,你需要為要執行的任務配置合適的 sudo 權限。

輸入 servera 的 root 密碼,這條命令會將你的 SSH 密鑰安裝到遠程主機上去。安裝好 SSH 密鑰後,再通過 SSH 登錄遠程主機就不再需要輸入 root 密碼了。

安裝 Ansible

只需要在示例 1 中生成 SSH 密鑰的那台主機上安裝 Ansible。若你使用的是 Fedora,輸入下麵命令:

  1. sudo dnf install ansible -y

若運行的是 CentOS,你需要為 EPEL 倉庫配置額外的包:

  1. sudo yum install epel-release -y

然後再使用 yum 來安裝 Ansible:

  1. sudo yum install ansible -y

對於基於 Ubuntu 的系統,可以從 PPA 上安裝 Ansible:

  1. sudo apt-get install software-properties-common -y

  2. sudo apt-add-repository ppa:ansible/ansible

  3. sudo apt-get update

  4. sudo apt-get install ansible -y

若你使用的是 macOS,那麼推薦通過 Python PIP 來安裝:

  1. sudo pip install ansible

對於其他發行版,請參見 Ansible 安裝文件 [1]

Ansible Inventory

Ansible 使用一個 INI 風格的檔案來追蹤要管理的服務器,這種檔案被稱之為庫存清單Inventory。預設情況下該檔案位於 /etc/ansible/hosts。本文中,我使用示例 2 中所示的 Ansible 庫存清單來對所需的主機進行操作(為了簡潔起見已經進行了裁剪):

  1. [arch]

  2. nextcloud

  3. prometheus

  4. desktop1

  5. desktop2

  6. vm-host15

  7. [fedora]

  8. netflix

  9. [centos]

  10. conan

  11. confluence

  12. 7-repo

  13. vm-server1

  14. gitlab

  15. [ubuntu]

  16. trusty-mirror

  17. nwn

  18. kids-tv

  19. media-centre

  20. nas

  21. [satellite]

  22. satellite

  23. [ocp]

  24. lb00

  25. ocp_dns

  26. master01

  27. app01

  28. infra01

示例 2 : Ansible 主機檔案

每個分組由中括號和組名標識(像這樣 [group1] ),是應用於一組服務器的任意組名。一臺服務器可以存在於多個組中,沒有任何問題。在這個案例中,我有根據操作系統進行的分組(archubuntucentosfedora),也有根據服務器功能進行的分組(ocpsatellite)。Ansible 主機檔案可以處理比這複雜的多的情況。詳細內容,請參閱 庫存清單文件[2]

運行命令

將你的 SSH 密鑰拷貝到庫存清單中所有服務器上後,你就可以開始使用 Ansible 了。Ansible 的一項基本功能就是運行特定命令。語法為:

  1. ansible -a "some command"

例如,假設你想升級所有的 CentOS 服務器,可以運行:

  1. ansible centos -a 'yum update -y'

註意:不是必須要根據服務器操作系統來進行分組的。我下麵會提到,Ansible Facts[3] 可以用來收集這一信息;然而,若使用 Facts 的話,則運行特定命令會變得很複雜,因此,如果你在管理異構環境的話,那麼為了方便起見,我推薦創建一些根據操作系統來劃分的組。

這會遍歷 centos 組中的所有服務器並安裝所有的更新。一個更加有用的命令應該是 Ansible 的 ping 模塊了,可以用來驗證服務器是否準備好接受命令了:

  1. ansible all -m ping

這會讓 Ansible 嘗試通過 SSH 登錄庫存清單中的所有服務器。在示例 3 中可以看到 ping命令的部分輸出結果。

  1. nwn | SUCCESS => {

  2.    "changed":false

  3.    "ping":"pong"

  4. }

  5. media-centre | SUCCESS => {

  6.    "changed":false

  7.    "ping":"pong"

  8. }

  9. nas | SUCCESS => {

  10.    "changed":false

  11.    "ping":"pong"

  12. }

  13. kids-tv | SUCCESS => {

  14.    "changed":false

  15.    "ping":"pong"

  16. }

  17. ...

示例 3 :Ansible ping 命令輸出

運行指定命令的能力有助於完成快速任務(LCTT 譯註:應該指的那種一次性任務),但是如果我想在以後也能以同樣的方式運行同樣的任務那該怎麼辦呢?Ansible playbooks[4] 就是用來做這個的。

複雜任務使用 Ansible playbooks

Ansible 劇本playbook 就是包含 Ansible 指令的 YAML 格式的檔案。我這裡不打算講解類似 Roles 和 Templates 這些比較高深的內容。有興趣的話,請閱讀 Ansible 文件[5]

在前一章節,我推薦你使用 ssh-copy-id 命令來傳遞你的 SSH 密鑰;然而,本文關註於如何以一種一致的、可重覆性的方式來完成任務。示例 4 演示了一種以冥等的方式,即使 SSH 密鑰已經存在於標的主機上也能保證正確性的實現方法。

  1. ---

  2. - hosts:all

  3.  gather_facts:false

  4.  vars:

  5.    ssh_key:'/root/playbooks/files/laptop_ssh_key'

  6.  tasks:

  7.    - name:copy ssh key

  8.      authorized_key:

  9.        key:"{{ lookup('file',ssh_key) }}"

  10.        user:root

示例 4:Ansible 劇本 “pushsshkeys.yaml”

- hosts: 行標識了這個劇本應該在那個主機組上執行。在這個例子中,它會檢查庫存清單里的所有主機。

gather_facts: 行指明 Ansible 是否去搜索每個主機的詳細信息。我稍後會做一次更詳細的檢查。現在為了節省時間,我們設置 gather_facts 為 false

vars: 部分,顧名思義,就是用來定義劇本中所用變數的。在示例 4 的這個簡短劇本中其實不是必要的,但是按慣例我們還是設置了一個變數。

最後由 tasks: 標註的這個部分,是存放主體指令的地方。每個任務都有一個 -name:。Ansbile 在運行劇本時會顯示這個名字。

authorized_key: 是劇本所使用 Ansible 模塊的名字。可以通過命令 ansible-doc -a 來查詢 Ansible 模塊的相關信息; 不過通過網絡瀏覽器查看 文件 [6] 可能更方便一些。authorized_key 模塊[7] 有很多很好的例子可以參考。要運行示例 4 中的劇本,只要運行 ansible-playbook 命令就行了:

  1. ansible-playbook push_ssh_keys.yaml

如果是第一次添加 SSH 密鑰,SSH 會提示你輸入 root 用戶的密碼。

現在 SSH 密鑰已經傳輸到服務器中去了,可以來做點有趣的事了。

使用 Ansible 收集信息

Ansible 能夠收集標的系統的各種信息。如果你的主機數量很多,那它會特別的耗時。按我的經驗,每台主機大概要花個 1 到 2 秒鐘,甚至更長時間;然而有時收集信息是有好處的。考慮下麵這個劇本,它會禁止 root 用戶通過密碼遠程登錄系統:

  1. ---

  2. - hosts:all

  3.  gather_facts:true

  4.  vars:

  5.  tasks:

  6.    - name:Enabling ssh-key only root access

  7.      lineinfile:

  8.        dest:/etc/ssh/sshd_config

  9.        regexp:'^PermitRootLogin'

  10.        line:'PermitRootLogin without-password'

  11.      notify:

  12.        - restart_sshd

  13.        - restart_ssh

  14.  handlers:

  15.    - name:restart_sshd

  16.      service:

  17.        name:sshd

  18.        state:restarted

  19.        enabled:true

  20.      when:ansible_distribution == 'RedHat'

  21.    - name:restart_ssh

  22.      service:

  23.        name:ssh

  24.        state:restarted

  25.        enabled:true

  26.      when:ansible_distribution == 'Debian'

示例 5:鎖定 root 的 SSH 訪問

在示例 5 中 sshd_config 檔案的修改是有條件[8] 的,只有在找到匹配的發行版的情況下才會執行。在這個案例中,基於 Red Hat 的發行版與基於 Debian 的發行版對 SSH 服務的命名是不一樣的,這也是使用條件陳述句的目的所在。雖然也有其他的方法可以達到相同的效果,但這個例子很好演示了 Ansible 信息的作用。若你想查看 Ansible 預設收集的所有信息,可以在本地運行 setup 模塊:

  1. ansible localhost -m setup |less

Ansible 收集的所有信息都能用來做判斷,就跟示例 4 中 vars: 部分所演示的一樣。所不同的是,Ansible 信息被看成是內置 變數,無需由系統管理員定義。

更近一步

現在可以開始探索 Ansible 並創建自己的基本了。Ansible 是一個富有深度、複雜性和靈活性的工具,只靠一篇文章不可能就把它講透。希望本文能夠激發你的興趣,鼓勵你去探索 Ansible 的功能。在下一篇文章中,我會再聊聊 Copysystemdserviceaptyumvirt,以及 user 模塊。我們可以在劇本中組合使用這些模塊,還可以創建一個簡單的 Git 服務器來儲存這些所有劇本。


via: https://opensource.com/article/17/7/automate-sysadmin-ansible

作者:Steve Ovens[10] 譯者:lujun9972 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

LCTT 譯者

DarkSun(lujun9972) ? ? ? ?
共計翻譯:75 篇
貢獻時間:74 天


推薦文章

< 左右滑動查看相關文章 >

點擊圖片、輸入文章 ID 或識別二維碼直達

赞(0)

分享創造快樂

© 2021 知識星球   网站地图