自動化運維-ansible中對于大項目的管理
一、引用主機清單
在Playbook中引用主機時,hosts
字段指定的目標必須與Ansible主機清單中定義的標識符完全匹配。如果清單中配置的是主機名,則在Playbook中使用IP地址或其他別名將無法匹配,導致任務被跳過
錯誤示例:
inventory
中配置
playbook
中配置
發現報錯,直接跳過該任務
主機清單引用方式大全:
方式 | 示例 | 說明 |
---|---|---|
單臺主機 | hosts: node1 | 指定清單中的具體主機名 |
hosts: node1.example.com | 使用FQDN(前提是清單里如此定義) | |
hosts: 172.16.30.10 | 使用IP地址(前提是清單里如此定義) | |
所有主機 | hosts: all | 定位到清單中的所有主機 |
hosts: '*' | 通配符,同樣代表所有主機 | |
主機組 | hosts: net | 定位到net 組中的所有主機 |
模式匹配 | hosts: '*.example.com' | 匹配所有以.example.com 結尾的主機 |
hosts: '172.16.30.*' | 匹配172.16.30.0/24 網段的所有主機 | |
hosts: 'web*' | 匹配所有名稱以web 開頭的主機 | |
hosts: node[ 1-5 ] | 匹配node1 , node2 , …, node5 | |
hosts: node[ a-d ] | 匹配nodea , nodeb , nodec , noded | |
集合操作 | hosts: net:webserver | 并集:屬于net 組或webserver 組的主機 |
hosts: net:&webserver | 交集:同時屬于net 組和webserver 組的主機 | |
hosts: net:!node1 | 差集:屬于net 組但排除node1 主機 |
二、配置并行執行
1. 使用 forks
控制并發連接數
Ansible默認同時只能處理5臺主機(由ansible.cfg
中的forks
參數控制)
流程如下:
- 一個Play中如果有10臺主機,
forks=5
- Ansible會先在前5臺主機上執行完所有任務
- 然后再在剩下的5臺主機上執行所有任務
對不同的受控主機:
- Linux受控主機:任務主要在受控端運行,控制節點負載較輕,可適當增加
forks
值以加速執行 - 網絡設備:模塊多在控制節點運行,負載較高,不宜設置過高的
forks
值
2. 使用 serial
進行并行執行
默認情況下,一個Play中所有主機必須全部完成一個任務,才會進入下一個任務。如果中間某臺主機任務失敗,整個Play會中止,導致已成功主機的Handlers也無法觸發
執行流程:
- 在最先的2臺主機(設定 serial=2)上執行Play,安裝httpd,成功后觸發handler重啟服務
- 這2臺處理完畢后,再在接下來的2臺主機上執行相同的Play
- 依此類推,直到所有批次完成
- 即使某一批次失敗,也只影響該批次,已成功的批次已正常執行了Handler
serial
也可以指定百分比(如 serial: "20%"
) 或列表(如 serial: [1, 5, 10]
,表示第一批1臺,第二批5臺,剩余全部10臺一批)
示例:
[student@master ansible] vim b.yml
# playbook內容如下
---
- name: test2hosts: node1,node2,node3,node4serial: 2tasks:- name: test21debug:msg: wil
三、包含與導入
為了提升Playbook的模塊化和可重用性,可以將任務或整個Playbook分解到不同文件中
1. 導入(import_*
) - 靜態預處理
在解析Playbook時,Ansible會將導入的文件內容直接復制到當前位置。適用于邏輯簡單、結構固定的場景
- import_playbook: 導入另一個Playbook文件
- import_tasks: 導入任務文件
示例:
配置
playbook
,repo.yml
[student@master ansible] vim repo.yml
# playbook內容如下
---
- name: repohosts: alltasks:- name: baseosyum_repository:name: baseosdescription: rhel9-baseosbaseurl: http://ansible.example.com/rhel9/BaseOSenabled: yesgpgcheck: no- name: appstreamyum_repository:name: appstreamdescription: rhel9-appstreambaseurl: http://ansible.example.com/rhel9/AppStreamenabled: yesgpgcheck: no
配置
tasks
,http.yml
[student@master ansible] vim http.yml
# tasks內容如下
---- name: install httpyum: name: httpdstate: installed
配置
playbook
,install1.yml
[student@master ansible] vim install1.yml
# playbook內容如下
---
- name: import-repoimport_playbook: repo.yml
- name: install hhosts: node1tasks:- import_tasks: http.yml- name: start httpdservice:name: httpdstate: startedenabled: yes
2. 包含(include_*
) - 動態執行
在Play運行期間遇到include_*
語句時,才會處理導入的文件內容。更靈活,支持與循環結合使用
- include_tasks: 動態包含任務文件
示例:
配置
tasks
,vsftp.yml
[student@master ansible] vim vsftp.yml
# tasks內容如下
---- name: install vsftpdyum: name: vsftpdstate: installed
配置
playbook
,install2.yml
[student@master ansible] vim install2.yml
# playbook內容如下
---
- name: install ftphosts: node1tasks:- include_tasks: vsftp.yml- name: start vsftpdservice:name: vsftpdstate: startedenabled: yes
導入 vs. 包含 關鍵區別
特性 | 導入 (import_* ) | 包含 (include_* ) |
---|---|---|
處理時機 | 解析時(靜態) | 運行時(動態) |
循環 | 不支持 | 支持與loop 一起使用 |
條件觸發 | 對所有導入任務應用單個when 條件 | 可為包含的每個任務應用不同條件 |
變量 | 導入時變量必須已定義 | 運行時變量可用,更靈活 |
最佳實踐: 優先使用導入,除非你需要循環包含或依賴于運行時變量的動態功能。