作者 | Steve Ovens
譯者 | DarkSun
精進你的系統管理能力和 Linux 技能,學習如何設定工具來簡化管理多臺機器。
你是否想精進你的系統管理能力和 Linux 技能?也許你的本地區域網上跑了一些東西,而你又想讓生活更輕鬆一點–那該怎麼辦呢?在本文中,我會向你演示如何設定工具來簡化管理多臺機器。
遠端管理工具有很多,SaltStack、Puppet、Chef,以及 Ansible 都是很流行的選擇。在本文中,我將重點放在 Ansible 上並會解釋它是如何幫到你的,不管你是有 5 臺還是 1000 臺虛擬機器。
讓我們從多機(不管這些機器是虛擬的還是物理的)的基本管理開始。我假設你知道要做什麼,有基礎的 Linux 管理技能(至少要有能找出執行每個任務具體步驟的能力)。我會向你演示如何使用這一工具,而是否使用它由你自己決定。
什麼是 Ansible?
Ansible 的網站上將之解釋為 “一個超級簡單的 IT 自動化引擎,可以自動進行雲供給、配置管理、應用部署、服務內部編排,以及其他很多 IT 需求。” 透過在一個集中的位置定義好伺服器集合,Ansible 可以在多個伺服器上執行相同的任務。
如果你對 Bash 的 for
迴圈很熟悉,你會發現 Ansible 操作跟這很類似。區別在於 Ansible 是幕等的。通俗來說就是 Ansible 一般只有在確實會發生改變時才執行所請求的動作。比如,假設你執行一個 Bash 的 for 迴圈來為多個機器建立使用者,像這樣子:
for server in serverA serverB serverC; do ssh ${server} "useradd myuser"; done
這會在 serverA、serverB,以及 serverC 上建立 myuser 使用者;然而不管這個使用者是否存在,每次執行這個 for 迴圈時都會執行 useradd
命令。一個幕等的系統會首先檢查使用者是否存在,只有在不存在的情況下才會去建立它。當然,這個例子很簡單,但是幕等工具的好處將會隨著時間的推移變得越發明顯。
Ansible 是如何工作的?
Ansible 會將 Ansible playbooks 轉換成透過 SSH 執行的命令,這在管理類 UNIX 環境時有很多優勢:
配置 SSH 金鑰認證
使用 Ansible 的一種常用方法是配置無需密碼的 SSH 金鑰登入以方便管理。(可以使用 Ansible Vault 來為密碼等敏感資訊提供保護,但這不在本文的討論範圍之內)。現在只需要使用下麵命令來生成一個 SSH 金鑰,如示例 1 所示。
[09:44 user ~]$ ssh-keygen
Generating public/private rsa key pair。
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh'。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa。
Your public key has been saved in /home/user/.ssh/id_rsa.pub。
The key fingerprint is:
SHA256:TpMyzf4qGqXmx3aqZijVv7vO9zGnVXsh6dPbXAZ+LUQ user@user-fedora
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| E |
| o . .。|
| . + S o+。|
| . .o * . .+ooo|
| . .+o o o oo+。*|
|。.ooo* o。* .*+|
| . o+*BO.o+ .o|
+----[SHA256]-----+
示例 1 :生成一個 SSH 金鑰
在示例 1 中,直接按下回車鍵來接受預設值。任何非特權使用者都能生成 SSH 金鑰,也能安裝到遠端系統中任何使用者的 SSH 的 authorized_keys
檔案中。生成金鑰後,還需要將之複製到遠端主機上去,執行下麵命令:
ssh-copy-id root@servera
註意:執行 Ansible 本身無需 root 許可權;然而如果你使用非 root 使用者,你需要為要執行的任務配置合適的 sudo 許可權。
輸入 servera 的 root 密碼,這條命令會將你的 SSH 金鑰安裝到遠端主機上去。安裝好 SSH 金鑰後,再透過 SSH 登入遠端主機就不再需要輸入 root 密碼了。
安裝 Ansible
只需要在示例 1 中生成 SSH 金鑰的那臺主機上安裝 Ansible。若你使用的是 Fedora,輸入下麵命令:
sudo dnf install ansible -y
若執行的是 CentOS,你需要為 EPEL 倉庫配置額外的包:
sudo yum install epel-release -y
然後再使用 yum 來安裝 Ansible:
sudo yum install ansible -y
對於基於 Ubuntu 的系統,可以從 PPA 上安裝 Ansible:
sudo apt-get install software-properties-common -y
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible -y
若你使用的是 macOS,那麼推薦透過 Python PIP 來安裝:
sudo pip install ansible
對於其他發行版,請參見 Ansible 安裝檔案 [1]。
Ansible Inventory
Ansible 使用一個 INI 風格的檔案來追蹤要管理的伺服器,這種檔案被稱之為庫存清單。預設情況下該檔案位於 /etc/ansible/hosts
。本文中,我使用示例 2 中所示的 Ansible 庫存清單來對所需的主機進行操作(為了簡潔起見已經進行了裁剪):
[arch]
nextcloud
prometheus
desktop1
desktop2
vm-host15
[fedora]
netflix
[centos]
conan
confluence
7-repo
vm-server1
gitlab
[ubuntu]
trusty-mirror
nwn
kids-tv
media-centre
nas
[satellite]
satellite
[ocp]
lb00
ocp_dns
master01
app01
infra01
示例 2 : Ansible 主機檔案
每個分組由中括號和組名標識(像這樣 [group1]
),是應用於一組伺服器的任意組名。一臺伺服器可以存在於多個組中,沒有任何問題。在這個案例中,我有根據作業系統進行的分組(arch
、ubuntu
、centos
、fedora
),也有根據伺服器功能進行的分組(ocp
、satellite
)。Ansible 主機檔案可以處理比這複雜的多的情況。詳細內容,請參閱 庫存清單檔案[2]。
執行命令
將你的 SSH 金鑰複製到庫存清單中所有伺服器上後,你就可以開始使用 Ansible 了。Ansible 的一項基本功能就是執行特定命令。語法為:
ansible -a "some command"
例如,假設你想升級所有的 CentOS 伺服器,可以執行:
ansible centos -a 'yum update -y'
註意:不是必須要根據伺服器作業系統來進行分組的。我下麵會提到,Ansible Facts[3] 可以用來收集這一資訊;然而,若使用 Facts 的話,則執行特定命令會變得很複雜,因此,如果你在管理異構環境的話,那麼為了方便起見,我推薦建立一些根據作業系統來劃分的組。
這會遍歷 centos
組中的所有伺服器並安裝所有的更新。一個更加有用的命令應該是 Ansible 的 ping
模組了,可以用來驗證伺服器是否準備好接受命令了:
ansible all -m ping
這會讓 Ansible 嘗試透過 SSH 登入庫存清單中的所有伺服器。在示例 3 中可以看到 ping
命令的部分輸出結果。
nwn | SUCCESS => {
"changed":false,
"ping":"pong"
}
media-centre | SUCCESS => {
"changed":false,
"ping":"pong"
}
nas | SUCCESS => {
"changed":false,
"ping":"pong"
}
kids-tv | SUCCESS => {
"changed":false,
"ping":"pong"
}
...
示例 3 :Ansible ping 命令輸出
執行指定命令的能力有助於完成快速任務(LCTT 譯註:應該指的那種一次性任務),但是如果我想在以後也能以同樣的方式運行同樣的任務那該怎麼辦呢?Ansible playbooks[4] 就是用來做這個的。
複雜任務使用 Ansible playbooks
Ansible 劇本 就是包含 Ansible 指令的 YAML 格式的檔案。我這裡不打算講解類似 Roles 和 Templates 這些比較高深的內容。有興趣的話,請閱讀 Ansible 檔案[5]。
在前一章節,我推薦你使用 ssh-copy-id
命令來傳遞你的 SSH 金鑰;然而,本文關註於如何以一種一致的、可重覆性的方式來完成任務。示例 4 演示了一種以冥等的方式,即使 SSH 金鑰已經存在於標的主機上也能保證正確性的實現方法。
---
- hosts:all
gather_facts:false
vars:
ssh_key:'/root/playbooks/files/laptop_ssh_key'
tasks:
- name:copy ssh key
authorized_key:
key:"{{ lookup('file',ssh_key) }}"
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
命令就行了:
ansible-playbook push_ssh_keys.yaml
如果是第一次新增 SSH 金鑰,SSH 會提示你輸入 root 使用者的密碼。
現在 SSH 金鑰已經傳輸到伺服器中去了,可以來做點有趣的事了。
使用 Ansible 收集資訊
Ansible 能夠收集標的系統的各種資訊。如果你的主機數量很多,那它會特別的耗時。按我的經驗,每臺主機大概要花個 1 到 2 秒鐘,甚至更長時間;然而有時收集資訊是有好處的。考慮下麵這個劇本,它會禁止 root 使用者透過密碼遠端登入系統:
---
- hosts:all
gather_facts:true
vars:
tasks:
- name:Enabling ssh-key only root access
lineinfile:
dest:/etc/ssh/sshd_config
regexp:'^PermitRootLogin'
line:'PermitRootLogin without-password'
notify:
- restart_sshd
- restart_ssh
handlers:
- name:restart_sshd
service:
name:sshd
state:restarted
enabled:true
when:ansible_distribution == 'RedHat'
- name:restart_ssh
service:
name:ssh
state:restarted
enabled:true
when:ansible_distribution == 'Debian'
示例 5:鎖定 root 的 SSH 訪問
在示例 5 中 sshd_config
檔案的修改是有條件[8] 的,只有在找到匹配的發行版的情況下才會執行。在這個案例中,基於 Red Hat 的發行版與基於 Debian 的發行版對 SSH 服務的命名是不一樣的,這也是使用條件陳述句的目的所在。雖然也有其他的方法可以達到相同的效果,但這個例子很好演示了 Ansible 資訊的作用。若你想檢視 Ansible 預設收集的所有資訊,可以在本地執行 setup
模組:
ansible localhost -m setup |less
Ansible 收集的所有資訊都能用來做判斷,就跟示例 4 中 vars:
部分所演示的一樣。所不同的是,Ansible 資訊被看成是內建 變數,無需由系統管理員定義。
更近一步
現在可以開始探索 Ansible 並建立自己的基本了。Ansible 是一個富有深度、複雜性和靈活性的工具,只靠一篇文章不可能就把它講透。希望本文能夠激發你的興趣,鼓勵你去探索 Ansible 的功能。在下一篇文章中,我會再聊聊 Copy
、systemd
、service
、apt
、yum
、virt
,以及 user
模組。我們可以在劇本中組合使用這些模組,還可以建立一個簡單的 Git 伺服器來儲存這些所有劇本。
via: https://opensource.com/article/17/7/automate-sysadmin-ansible
作者:Steve Ovens[10] 譯者:lujun9972 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出