一:ansible基礎知識
1.1 ansible的定義與工作原理簡述
ansible是一個自動化運維工具,用于執行自動化任務,包括像配置管理,應用部署,任務執行等等,本質上來說也是基礎設施及代碼工具,通過可讀性較強的代碼聲明基礎設施的期望狀態,再通過附帶的ansible模塊去執行。
什么是基礎設施?
基礎設施及代碼”里的**“基礎設施”,專指支撐應用運行的所有底層環境和依賴**,而不限于傳統意義上的機房、機柜、網線。它通常被拆成三層:
計算資源
物理機、虛擬機(KVM/VMware/Hyper-V)、容器運行時(Docker/containerd)、Kubernetes Node、Lambda/Function 等可運行代碼的實體。網絡與連通性
VPC、子網、路由表、安全組、負載均衡(ELB/SLB/NGINX Ingress)、VPN、DNS、CDN、Service Mesh 等讓流量能正確且安全地進出的組件。存儲與數據
塊存儲(EBS、云盤)、對象存儲(S3、OSS)、文件存儲(EFS、NAS)、數據庫(RDS、Aurora、MongoDB)、緩存(Redis、Memcached)、備份與快照。
一句話:
“基礎設施”= 讓應用能跑起來、能被訪問、能把數據存下來的所有“云+底層資源”;把這一切用代碼(Terraform、Ansible、Pulumi、K8s YAML、Helm Chart)聲明出來,就成了 IaC 中的“基礎設施”。
工作原理是什么?
加載配置
讀取ansible.cfg
、環境變量、命令行參數,決定 SSH/WinRM 選項、并發數(forks)、回調插件等。生成庫存(Inventory)
把靜態 INI、動態腳本(AWS、VMware、OpenStack、K8s CRD 等)或 Tower 數據庫里的主機信息解析成內存對象,附帶變量(host_vars、group_vars)。建立連接
控制節點按ansible_connection
字段決定用 SSH、local、docker、kubectl、winrm 等協議并發地與目標機握手;這一步只建一次連接,后續指令復用同一通道。任務編排與模塊傳輸
? 對每條 Play/Role,先按策略插件(linear、free、debug)切分批次。
? 把要執行的模塊(Python 文件或二進制)+ 參數打包成 ZIP,通過 SCP/SFTP 推到遠端臨時目錄(~/.ansible/tmp/...
)。
? 遠端用指定的解釋器(/usr/bin/python3
、/usr/bin/pwsh
等)一次性執行該模塊,返回 JSON 結果。
? 如果是冪等模塊,會先收集當前狀態做差異比較(例如yum list installed nginx
),再決定是否改動。結果收集與回調
控制節點把每臺主機的 JSON 回包解析成統一結構(changed、ok、failed、skipped),通過回調插件輸出到終端、日志、Slack、Prometheus 或 Tower 數據庫,并根據any_errors_fatal
或max_fail_percentage
決定是否中止整個 Playbook。
ansible的優勢是什么?
核心能力拆解
聲明式編排
Playbook 只描述“要變成什么樣”,而不是“怎么變”。例如“確保 nginx 已安裝并運行”,Ansible 會自己判斷是否需要安裝、啟動或重啟。冪等執行
同一 Playbook 反復運行,結果不變。第 1 次會改動系統,第 N 次直接返回 OK,天然適合 CI/CD 與回滾。無 agent 架構
控制節點通過 SSH(Linux/Unix)或 WinRM(Windows)連接,目標機無需預裝客戶端,降低入侵面和維護成本。模塊化插件體系
6000+ 個模塊(command、yum、template、kubernetes、vmware…)+ 回調插件、動態庫存、過濾器,幾乎覆蓋所有基礎設施和應用場景。可版本化、可審計
Playbook/Role 是純文本,天然進 Git;執行日志可 JSON 化輸出,方便審計與合規。跨平臺:可以操控linux,windows,unix,網絡設備等等。
什么是冪等執行,如何實現的?
冪等執行(idempotency)指:
無論操作執行 1 次還是 N 次,系統的最終狀態都保持一致,且不會產生額外副作用。
舉例:
第 1 次執行“確保 nginx 已安裝并啟動” → 系統安裝了 nginx 并啟動。
第 2 次執行同樣指令 → 檢測到 nginx 已安裝且進程已運行,直接返回 OK,不再重復安裝或重啟。
Ansible 實現冪等的核心機制
聲明式模塊
每個模塊內部先“查現狀”,再“算差異”,最后“只做必要改動”。yum:
模塊 → 先rpm -q nginx
;若已安裝則直接返回ok
。service:
模塊 → 先systemctl is-active nginx
;若已是active
,則跳過啟動。copy:
模塊 → 先比較 checksum;文件一致則跳過傳輸。
facts 緩存
運行setup
模塊把系統信息(包列表、服務狀態、文件屬性等)緩存到ansible_facts
,后續任務可直接引用,避免重復查詢。check mode / diff mode
ansible-playbook -C
:模擬運行,只返回“哪些任務會改變”,不真正執行。ansible-playbook -D
:在終端顯示文件 diff,提前確認變更。
條件判斷與 register
通過register
保存任務結果,再用when
或changed_when/failed_when
控制后續邏輯,避免重復操作。冪等性開關
個別模塊提供顯式參數:command:
/shell:
默認非冪等,但可配creates
/removes
文件標記。uri:
模塊可用status_code
判斷接口是否已創建資源。
一句話總結:
Ansible 的冪等性不是靠用戶寫“if not exist then …”,而是每個模塊內部自帶“查-比-改”三步邏輯,從而保證多次執行結果一致。
1.2 ansible的分類
? ansible是屬于redhat公司的核心產品,分為紅帽企業版和社區版,兩者差別就是在于模塊數量和功能完整度,社區版的軟件包是ansible-core只包含了運行ansible的必需幾個組件和內建模塊通過pip下載,而企業版通過rpm包下載,不僅包含了ansible-core,還包含了最新的組件ansible-navigator可以代替過去多個ansible命令,用于開發和測試ansible的playbook。
過去常用的ansible命令有哪些?
運行 playbook
ansible-playbook查看 playbook 中某個關鍵詞用法
ansible-doc 關鍵詞查看主機清單
ansible-inventory --list查看配置
ansible-config dump
現在的ansible-navigator怎么全部代替他們?
老命令 | ansible-navigator 等價用法 |
---|---|
ansible-playbook site.yml | ansible-navigator run site.yml |
ansible-doc 關鍵字 | ansible-navigator doc 關鍵字 |
ansible-inventory --list | ansible-navigator inventory --list |
ansible-config dump | ansible-navigator config dump |
ansible-core軟件包和ansible-navigator軟件包運行環境有什么這區別?
一句話區分
? ansible-core:直接在你本地 Python 環境里跑 ansible-playbook
。
? ansible-navigator:把 ansible-core 裝進一個容器鏡像里跑,你用 navigator 命令只是去啟動那個容器。
所以:
– 安裝 ansible-core 要先配 Python、pip 依賴;
– 安裝 ansible-navigator 只要裝好 podman/docker,它自動拉鏡像,里面已經打包好 ansible-core 和所有常用集合,版本隔離、依賴不污染宿主機。
為什么ansible一定需要一個運行環境?
Ansible 控制節點必須有一個“運行環境”,是因為 它才是真正干活的程序,而不是一個單純的“遙控器”。
簡單一句話:
控制節點需要 Python + Ansible 代碼 + 模塊庫,用來 把 YAML 翻譯成遠程機器上可執行的命令,并收集結果。
具體作用拆開說:
解釋 Playbook
YAML 里的任務、變量、模板全由控制節點的 Python 進程解析成內部數據結構。加載并執行模塊
每個任務對應一個.py
模塊,控制節點先把模塊代碼通過 SSH/WinRM 復制到目標機,再遠程執行;模塊返回 JSON 結果,控制節點再解析。變量與事實處理
控制節點運行setup
收集 facts,再把 host_vars、group_vars、Jinja2 模板在本地渲染好,再下發。并發與結果聚合
forks、策略插件、回調插件都在控制節點里跑,負責并發調度、輸出格式化、失敗重試等。依賴管理
模塊、集合、Jinja2 過濾器、額外 Python 庫(如 boto3、kubernetes)都裝在控制節點;目標機不需要這些依賴。
因此,控制節點必須有一個 包含 Python 解釋器 + ansible-core + 相關依賴 的運行環境;沒有它,YAML 只是純文本,無法變成可執行指令。
二:實施ansible的playbook
前提條件
實施playbook前需要集齊主機清單和ansible的配置。
2.1 主機清單
主機清單是用來管控ansible實施主機對象的文件,分為靜態主機清單文本文件和通過外部程序提供信息動態生成主機信息的動態主機清單。(以靜態主機清單為例)。
格式如下:由主機ip或域名與主機組構成。
直接列主機
192.168.1.10
web01.example.com
? ? ?2分組 + 主機 + 變量
[web]
web01 ansible_host=192.168.1.10 ansible_user=deploy
web02 ansible_host=192.168.1.11[db]
db01 ansible_host=192.168.2.5
db02 ansible_host=192.168.2.6 ansible_port=2222[web:vars] # 全組共用變量
http_port=80
直接寫在主機后面
web01 ansible_host=192.168.1.10 ansible_user=deploy
? ? ?2寫在組名 :vars
段里(組內共用)
[web:vars]
http_port=80
3寫在
all:vars
段里(全體共用)
[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa
保存后 Ansible 會自動讀取這些變量,優先級:主機變量 > 組變量 > all 變量。
? ?3嵌套/繼承組
[prod:children]
web
db
存在默認的兩個主機組
all:全體主機
ungrouped:沒有被列進主機組的主機
另外在主機清單里還可以通過[start:end]格式來簡化主機格式例如:
inventory查找的默認順序如下:(ansible執行的時候工作路徑是當前執行的工作路徑)
Ansible 查找主機清單的默認順序(從先到后):
命令行
-i
指定的文件或腳本。ANSIBLE_INVENTORY
環境變量指定的路徑。當前目錄下的
ansible.cfg
里inventory = ...
指定的路徑。用戶主目錄
~/.ansible.cfg
里inventory = ...
指定的路徑。系統級
/etc/ansible/ansible.cfg
里inventory = ...
指定的路徑。若以上都沒有,則回退到 /etc/ansible/hosts。
2.2 ansible的配置文件
ansible的配置文件一般基礎配置文件命名為ansible.cfg,管理ansible-navigator的配置文件命名為ansible-navigato.yml.
ansible.cfg包含兩個部分[defaults]和[privilege_escalation].
defaults 段
[defaults]
? inventory = ./hosts # 指定清單文件
? remote_user = deploy # 默認 SSH 用戶
? forks = 20 # 并發數
? host_key_checking = False # 首次連接免確認privilege_escalation 段
[privilege_escalation]
? become = True # 默認啟用提權
? become_method = sudo # 用 sudo
? become_user = root # 提權到 root
可以通過ansible-navigator config去查看ansible.cfg所有配置。
ansible-navigator.yml文件主要包含以下部分:
playbook-artifact 就是 把一次 playbook 運行的完整結果(每個 play、每個任務的狀態、stdout、返回值等)自動寫成一個 JSON 快照文件,作用:
事后回放:
用ansible-navigator replay xxx.json
隨時在終端里“重看”這次運行,不用原 playbook 和清單。共享/審計:
JSON 單文件即可發給同事或歸檔,滿足合規和變更追蹤需求。離線排查:
失敗現場被完整保留,方便脫離原始環境做調試。
一句話:playbook-artifact 是把運行結果“錄像”成 JSON,隨時回放、共享、審計。
ansible兩個配置文件的執行查找順序是什么?
先找 ansible.cfg → 再找 ansible-navigator.yml。
ansible-navigator 啟動時,先用 Ansible 自己的查找順序(當前目錄 → ~/.ansible.cfg → /etc/ansible/ansible.cfg)確定 ansible.cfg。
然后讀取同一目錄下的 ansible-navigator.yml(或
~/.ansible-navigator.yml
)。
后者僅對 navigator 生效,不會覆蓋 ansible.cfg 中已設置的參數,只是補充或改用容器執行環境。
2.2 ansible playbook的語法規則
一個完整的ansible playbook的示例如下:
---
- name: Ensure nginx is installed and runninghosts: webbecome: yesvars:http_port: 80tasks:- name: Install nginxyum:name: nginxstate: presentwhen: ansible_facts['os_family'] == 'RedHat'- name: Deploy index.htmltemplate:src: templates/index.html.j2dest: /usr/share/nginx/html/index.html- name: Ensure nginx is started and enabledservice:name: nginxstate: startedenabled: yes- name: Verify port is listeningwait_for:port: "{{ http_port }}"host: "{{ ansible_default_ipv4.address }}"
開頭為:---
注釋用#
在 Playbook 中,只有當 YAML 需要「列表項」時才必須寫 -
(破折號+空格)。
出現位置只有兩處:
頂層:每個 play 是列表成
--- - name: play1 # ← 這里hosts: web - name: play2 # ← 再一個 play
任務/角色/變量等列表:tasks、roles、pre_tasks、post_tasks、vars、loop、block、handlers?
tasks:- name: task1 # ← 任務列表- name: task2
其余場景(字典 key、模塊參數、變量賦值)絕不要 -
,直接鍵值對即可。
常用執行的參數如下:
類別 | 參數 | 作用說明 |
---|---|---|
清單/范圍 | -i <文件> | 指定主機清單 |
-l <模式> | 只跑匹配的主機或組 | |
語法檢查 | --syntax-check | 僅檢查 playbook 語法 |
空運行 | --check ?或?-C | 干跑,不真正改變系統 |
--diff | 空跑時顯示文件差異 | |
輸出詳細程度 | -v | 詳細輸出 |
-vv ?/?-vvv | 更詳細 / 最詳細 | |
并發 | -f N | 并發進程數(默認 5) |
提權 | --become | 自動使用 sudo/ become |
標簽 | -t <標簽> | 僅執行帶指定 tag 的任務 |