Ansible 清單
靜態主機清單
主機清單支持多種格式,例如ini、yaml、腳本等。
本次課程使用 ini 格式。
?#創建主機清單[lyk@controller ~ 13:36:01]# vim inventory#vim添加controllernode1node2node3node4?#測試連接單個服務器[lyk@controller ~ 14:08:18]$ ansible node1 ?-i ./inventory -m command -a id?#對所有服務器執行命令[lyk@controller ~ 13:42:33]# ansible all -i inventory -a idnode4 | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)node2 | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)node3 | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)node1 | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)controller | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)?-作用:給 "通訊錄" 里所有服務器發命令,讓它們報告自己的身份-結果解讀:每臺服務器回復了自己的用戶 ID(這里都是 root)?#只對特定服務器 node1 執行命令[lyk@controller ~ 13:43:30]# ansible node1 -i inventory -a idnode1 | CHANGED | rc=0 >>uid=0(root) gid=0(root) 組=0(root)?#執行黃色,表示安裝軟件包[lyk@controller ~ 13:52:23]$ ansible all -i ./inventory -m yum -a 'name=vsftpd state=present' -b#再次執行變綠,表示已下載過[lyk@controller ~ 13:52:23]$ ansible all -i ./inventory -m yum -a 'name=vsftpd state=present' -b?#卸載軟件包,absent[lyk@controller ~ 13:58:12]$ ansible all -i ./inventory -m yum -a 'name=vsftpd state=absent' -b?#其他四臺執行也能看到[lyk@controller ~ 14:04:11]$ yum list vsftpd?#查看主機列表[lyk@controller ~ 14:08:18]$ ansible -i ./inventory --list-host all??[lyk@controller ~ 14:08:05]$ ansible -i ./inventory --list-host node3?
分組管理服務器
?#創建服務器分組[lyk@controller ~ 14:10:08]$ vim inventory#vim添加[controllers]controller[nodes]node1node2node3node4?[lyk@controller ~ 14:11:34]$ ansible -i ./inventory --list-hosts controllershosts (1):controller[lyk@controller ~ 14:12:00]$ ansible -i ./inventory --list-hosts nodeshosts (4):node1node2node3node4???[lyk@controller ~ 14:12:09]$ vim inventory#vim添加=====================================================================[controllers]controller?[nodes]node1node2node3node4?[nj]node1node2?[bj]node3node4?[webs]node1node2?[dbs]node3node4=====================================================================#查看不同分組[lyk@controller ~ 14:14:29]$ ansible -i ./inventory --list-hosts njhosts (2):node1node2[lyk@controller ~ 14:14:45]$ ansible -i ./inventory --list-hosts bjhosts (2):node3node4[lyk@controller ~ 14:14:50]$ ansible -i ./inventory --list-hosts webshosts (2):node1node2[lyk@controller ~ 14:14:54]$ ansible -i ./inventory --list-hosts dbshosts (2):node3node4???#vim**在[controllers]上添加的,算其他10.1.8.234?[controllers]#查看其他分組[lyk@controller ~ 14:21:47]$ ansible -i ./inventory --list-hosts ungroupedhosts (1):10.1.8.234???#創建組嵌套(部門包含子部門)。vim 主機組嵌套 nj和bj都放在dc組,就可以顯示所有主機了[dc:children]njbj?[lyk@controller ~ 14:21:16]$ ansible -i ./inventory --list-hosts dchosts (4):node1node2node3node4??#重新編輯vim[lyk@controller ~ 14:27:09]$ vim inventory app1.example.com?[webservers]web1.example.comweb2.example.com192.168.3.7?[dbservers]db1.example.comdb2.example.com192.0.2.42?[eastdc]web1.example.comdb1.example.com?[westdc]web2.example.comdb2.example.com?[dc:children]eastdcwestdc?#圖形化展示服務器結構[lyk@controller ~ 14:28:48]$ ansible-inventory -i inventory --graph@all:|--@dbservers:| |--192.0.2.42| |--db1.example.com| |--db2.example.com|--@dc:| |--@eastdc:| | |--db1.example.com| | |--web1.example.com| |--@westdc:| | |--db2.example.com| | |--web2.example.com|--@ungrouped:| |--app1.example.com|--@webservers:| |--192.168.3.7| |--web1.example.com| |--web2.example.com???
管理 ANSIBLE 配置文件
配置文件位置和優先級
-
優先級排序
-
環境變量 ANSIBLE_CONFIG
-
./ansible.cfg,當前位置中的 ansible.cfg,當前位置一般是項目目錄。
-
~/.ansible.cfg
-
/etc/ansible/ansible.cfg
?#初始狀態:ansible --version[lyk@controller web 14:58:11]$ ansible --versionansible 2.9.27config file = /etc/ansible/ansible.cfg?#創建用戶家目錄配置文件:touch ~/.ansible.cfg[lyk@controller web 14:59:48]$ touch ~/.ansible.cfg[lyk@controller web 15:00:16]$ ansible --version |grep 'config file'config file = /home/lyk/.ansible.cfg?#在當前工作目錄創建配置文件:touch ansible.cfg[lyk@controller web 15:02:52]$ touch ansible.cfg[lyk@controller web 15:03:03]$ ansible --version |grep 'config file'config file = /home/lyk/web/ansible.cfg?#通過環境變量指定配置文件:export ANSIBLE_CONFIG=/opt/ansible.cfg[lyk@controller web 15:03:06]$ export ANSIBLE_CONFIG=/opt/ansible.cfg[lyk@controller web 15:03:53]$ sudo touch /opt/ansible.cfg[lyk@controller web 15:03:58]$ ansible --version |grep 'config file'config file = /opt/ansible.cfg?-變化:這是最高優先級!不管其他地方有沒有配置,Ansible 都只用你指定的這個。就像你明確說 "我就要用工具箱里的那把剪刀",其他地方的都不算數
?總結:Ansible 配置文件的優先級(從高到低)就像 “尋找東西的優先級”:?環境變量ANSIBLE_CONFIG指定的路徑(最優先,手動指定的 “目標位置”)當前工作目錄的ansible.cfg(次之,“手邊的文件”)用戶家目錄的~/.ansible.cfg(再次之,“個人抽屜里的文件”)系統級的/etc/ansible/ansible.cfg(默認,“公共倉庫的文件”)[]
指定 "主機名單"——Ansible 該管理哪些機器?
-
核心目標:Ansible 需要一個 "主機清單"(inventory)來知道要管理哪些機器,就像老師需要花名冊才知道要叫哪些學生
?#配置 inventory 路徑:vim ansible.cfg[lyk@controller web 15:14:54]$ vim ansible.cfg #web的ansible.cfg[defaults]inventory = ./inventory # 告訴Ansible:主機清單在當前目錄的inventory文件里?[lyk@controller ~ 15:10:22]$ mv inventory web/ # 把主機清單移到web目錄[lyk@controller ~ 15:12:19]$ cd web[lyk@controller web 15:16:31]$ cat ansible.cfg [defaults]inventory = ./inventory?#只能在web下查看, 驗證主機清單:ansible all --list-hosts[lyk@controller web 15:16:46]$ ansible all --list-hostshosts (7):app1.example.comweb1.example.comweb2.example.com192.168.3.7db1.example.comdb2.example.com192.0.2.42?
修改 inventory 內容 —— 自定義要管理的主機
?[lyk@controller web 15:25:18]$ vim inventory ? # 編輯主機清單[controllers]controller?[node]node[1:4]?[lyk@controller web 15:25:34]$ vim ansible.cfg [defaults]inventory = ./inventory?[lyk@controller web 15:26:10]$ ansible all -a id?[lyk@controller web 15:26:56]$ ansible all -a id -b?
SSH 登錄設置 ——Ansible 如何連接到主機?
?#密鑰移走,使免密登錄失效[lyk@controller web 15:27:56]$ mv /home/lyk/.ssh/id_rsa /home/lyk/.ssh/id_rsa.bak#沒有密鑰,需要輸密碼了[lyk@controller web 15:32:10]$ ssh node1 hostnamelyk@node1's password: ?#不給登錄,連接失敗**ansible**默認不主動要密碼[lyk@controller web 15:32:40]$ ansible node1 -a hostnamenode1 | UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", "unreachable": true??# 允許密碼登錄:vim ansible.cfg添加ask_pass = True,開啟密碼驗證[lyk@controller web 15:39:10]$ vim ansible.cfg #添加可輸入密碼登錄[defaults]inventory = ./inventoryask_pass = True # 告訴Ansible:連接時主動要SSH密碼?#允許密碼登錄[lyk@controller web 15:37:46]$ ansible node1 -a hostnameSSH password: ?
?#移動回來恢復密鑰登錄[lyk@controller web 15:40:09]$ mv /home/lyk/.ssh/id_rsa.bak /home/lyk/.ssh/id_rsa#把允許密碼登錄注釋掉[lyk@controller web 15:39:43]$ vim ansible.cfg [defaults]inventory = ./inventory#ask_pass = True ? ? ? ? ? **ask_pass = True # 注釋后,Ansible不再主動要密碼**?#驗證:直接登錄回來不用密碼[lyk@controller web 15:40:34]$ ssh node1 hostnamenode1.lyk.cloud#驗證[lyk@controller web 15:42:14]$ ansible node1 -a hostnamenode1 | CHANGED | rc=0 >>node1.lyk.cloud
提權配置 —— 讓 Ansible 有安裝軟件的權限
?#沒有提權安裝不了[lyk@controller web 15:51:08]$ ansible node1 -m yum -a 'name=httpd state=present'?[lyk@controller web 15:58:07]$ vim ansible.cfg #vim配置自動提權:vim ansible.cfg添加[privilege_escalation][privilege_escalation]become=True#become_method=sudo#become_user=root#become_ask_pass=False #提權不需密碼但是注釋掉依然能免密#已經設置過了[lyk@controller web 16:00:38]$ sudo vim /etc/sudoers.d/lyk# lyk ALL=(ALL) NOPASSWD:ALL#無需密碼??#安裝成功[lyk@controller web 16:00:38]$ ansible node1 -m yum -a 'name=httpd state=present'?
?總結:這些命令的核心邏輯配置文件優先級:控制 Ansible 用哪個規則干活,項目中常用當前目錄的ansible.cfg。inventory:告訴 Ansible 要管理哪些主機,按組劃分更方便。SSH 登錄:默認用密鑰免密,密鑰失效時開ask_pass輸密碼。提權:通過become=True讓 Ansible 臨時獲取 root 權限,才能執行高權限操作。
ansible-config
ansible-config view
-
查看當前ansible配合文件內容
?#問 Ansible 現在用的是哪個配置文件[lyk@controller web 16:14:17]$ ansible --version|grep fileconfig file = /home/lyk/web/ansible.cfg#查看當前生效的配置文件的實際內容[lyk@controller web 16:18:54]$ ansible-config view[defaults]inventory = ./inventory#ask_pass = Trueremote_user = lyk#module_name = command[privilege_escalation]become=Truebecome_method=sudobecome_user=rootbecome_ask_pass=False?
ansible-config dump
-
顯示所有生效的配置,包括默認值和自定義設置
?[lyk@controller web 16:20:04]$ ansible-config dump
ansible-config list
-
列出所有可用的配置參數及其說明
?#提供幫助文檔[lyk@controller web 16:21:28]$ ansible-config list
localhost 連接
-
Ansible會隱式設置localhost,并使用local連接類型連接localhost
?#列出當前配置中 "all" 組包含的所有主機[lyk@controller web 16:21:28]$ ansible all --list-hostshosts (5):controllernode1node2node3node4?#查看localhost這臺主機的信息[lyk@controller web 16:23:47]$ ansible --list-hosts localhosthosts (1):localhost?
AD HOC 命令
命令作用:
-
快速執行單個Ansible任務,而不需要將它保存下來供以后再次運行。它們是簡單的在線操作,無需編寫playbook即可運行。
-
快速測試和更改很有用。例如,您可以使用臨時命令確保一組服務器上的/ etc/hosts文件中存在某一特定的行。您可以使用另一個臨時命令在許多不同的計算機上高效重啟一項服務,或者確保特定的軟件包為最新版本。
Ansible 部分模塊
-
文件模塊
-
copy: 將控制主機上的文件復制到受管節點,類似于scp
-
file: 設置文件的權限和其他屬性
-
lineinfile: 確保特定行是否在文件中
-
synchronize: 使用 rsync 將控制主機上的文件同步到受管節點
-
-
軟件包模塊
-
package: 自動檢測操作系統軟件包管理器
-
yum: 使用 YUM 軟件包管理器管理軟件包
-
apt: 使用 APT 軟件包管理器管理軟件包
-
gem: 管理 Rubygem
-
pip: 從 PyPI 管理 Python 軟件包
-
-
系統模塊
-
ansible.posix.firewalld : 使用firewalld管理任意端口和服務
-
reboot: 重新啟動計算機
-
service: 管理服務
-
user、group: 管理用戶和組帳戶
-
-
NetTools模塊
-
get_url: 通過HTTP、HTTPS或FTP下載文件
-
nmcli: 管理網絡
-
uri: 與 Web 服務交互
-
環境準備
1. ansible.cfg
配置(操作說明書)
?[lyk@controller ~ 17:02:40]$ cd web[lyk@controller web 17:02:43]$ cat ansible.cfg =================================================================[defaults]inventory = ./inventory # 指定“地址簿”位置:當前目錄的inventory文件#ask_pass = True # 注釋掉了,意思是不自動詢問SSH密碼(因為已經配置免密)remote_user = lyk # 默認用lyk用戶登錄受管節點#module_name = command ? # 注釋掉了,默認模塊不指定為command?[privilege_escalation]become=True # 自動切換到特權用戶(類似sudo)become_method=sudo # 用sudo方式切換become_user=root # 切換到root用戶become_ask_pass=False # 切換時不詢問密碼(前提是lyk用戶sudo免密)=================================================================?
?-作用:這是 Ansible 的 “默認規則”,告訴它:?去哪里找要管理的主機(inventory = ./inventory);用什么用戶登錄(remote_user = lyk);要不要自動獲取 root 權限(become=True,相當于每次命令都帶sudo)。
2. inventory
配置(地址簿)
?[lyk@controller web 17:03:05]$ cat inventory =================================================================[controllers] # 分組:控制節點組controller # 組內主機:controller?[node] # 分組:節點組node[1:4] # 組內主機:node1、node2、node3、node4(用通配符簡寫)=================================================================
3.ansible-doc
:模塊的 “使用手冊查詢工具”
?# 查看模塊清單及說明[lyk@controller ~ 17:06:36]$ ansible-doc -l?# 查看模塊清單及位置[lyk@controller ~ 17:06:55]$ ansible-doc -F?# 查看特定模塊說明文檔[lyk@controller ~ 17:07:31]$ ansible-doc user
4.command
模塊:“基礎命令執行器”(最常用,但功能有限)
-
command 模塊允許管理員在受管節點的命令行中運行任意命令。要運行的命令通過-a選項指定為該模塊的參數
-
command
模塊是 Ansible 里最基礎的 “命令運行工具”,直接在受管節點執行命令,但有個限制:不經過 shell 解釋器,所以不支持 shell 的 “高級功能”(如環境變量、管道|
、重定向>
等)
?# 在node1上執行hostname命令(查看主機名)[lyk@controller web 17:10:13]$ ansible node1 -m command -a 'hostname'node1 | CHANGED | rc=0 >>node1.lyk.cloud?## 加-o選項:精簡輸出(一行顯示結果,適合批量查看)[lyk@controller web 17:10:16]$ ansible node1 -m command -a 'hostname' -onode1 | CHANGED | rc=0 | (stdout) node1.lyk.cloud
?參數解析:?ansible node1:對 “地址簿” 中的 node1 主機操作;-m command:使用 command 模塊;-a 'hostname':模塊參數是要執行的命令(這里是hostname);-o:精簡輸出格式。
5.shell 模塊“帶 shell 解釋器的命令執行器”(支持更多功能)
-
shell
模塊和command
類似,但它會通過受管節點的/bin/sh
(shell 解釋器)執行命令,所以支持所有 shell 特性(如環境變量、管道、重定向、shell 內置命令等)
?# 用command模塊執行set命令(失敗)[lyk@controller web 17:11:21]$ ansible node1 -m command -a setnode1 | FAILED | rc=2 >>[Errno 2] 沒有那個文件或目錄?## 用shell模塊執行set命令(成功)[lyk@controller web 17:12:05]$ ansible node1 -m shell -a set
注意:command和shell模塊要求被管理主機安裝Python。
核心區別:
?command:“直接跑命令,不找 shell 幫忙”,適合簡單命令(如hostname、ls);shell:“讓 shell 幫忙跑命令”,適合需要 shell 特性的場景(如echo $PATH、ls | grep txt)
6.raw 模塊“萬能但粗糙的命令執行器”(不依賴 Python)
-
raw 模塊,可以直接在遠端主機shell中執行命令,遠端主機不需要安裝Python(特別是針對網絡設備)。在大部分場景中,不推薦使用command、shell、raw模塊執行命令,因為這些模塊不具有冪等性
-
raw
模塊是個 “特例”:它直接在受管節點執行命令,不需要受管節點安裝 Python(這是和command
/shell
最大的區別)
?# 用raw模塊在node1的/tmp目錄寫一個hello.txt文件[lyk@controller web 17:12:05]$ ansible node1 -m raw -a 'echo "hello ansible" > /tmp/hello.txt'node1 | CHANGED | rc=0 >>Shared connection to node1 closed.?# 用command模塊驗證文件內容(此時已安裝Python,所以能執行)[lyk@controller web 17:13:27]$ ansible node1 -a 'cat /tmp/hello.txt'node1 | CHANGED | rc=0 >>hello ansible?# 用shell模塊也能實現同樣的寫入(但依賴Python)[lyk@controller web 17:13:42]$ ansible node1 -m shell -a 'echo "hello ansible" > /tmp/hello.txt'node1 | CHANGED | rc=0 >>
核心區別:
?-依賴 Python?command/shell需要,raw不需要(適合網絡設備、新系統等沒裝 Python 的場景);-冪等性?三者都差(冪等性:重復執行結果一致),比如echo "a" > file每次執行都會覆蓋文件,而專用模塊(如copy)會檢查是否需要修改,更安全;-用法:raw是 “萬不得已才用”,比如初始化系統時裝 Python 前。
總結:三個模塊的 “選擇指南”
模塊 | 是否依賴 Python | 支持 shell 特性(管道 / 變量等) | 適用場景 | 缺點 | |
---|---|---|---|---|---|
command | 是 | 否 | 簡單命令(如hostname 、ls ) | 不支持 shell 高級功能 | |
shell | 是 | 是 | 需要 shell 特性的命令(如set 、`ls | grep`) | 依賴 Python |
raw | 否 | 是(通過系統默認 shell) | 無 Python 的設備(如網絡設備)、初始化 |