Ansible 詳細筆記
一、Ansible 基礎概述
1.1 定義與定位
Ansible 是由 Red Hat 主導開發的開源自動化運維工具,基于 Python 語言實現,專注于簡化 IT 基礎設施的配置管理、應用部署、任務編排等操作。它采用無代理架構,通過 SSH 協議與被控節點通信,避免了傳統代理模式下的部署和維護成本。
1.2 核心優勢
-
輕量易用:無需在被控節點安裝客戶端,僅需控制節點部署 Ansible 即可。
-
冪等性保障:相同操作多次執行結果一致,避免重復操作導致的系統異常。
-
模塊化擴展:內置數千個模塊,覆蓋系統管理、云服務、網絡設備等場景,同時支持自定義模塊。
-
聲明式配置:通過 YAML 格式的 Playbook 描述目標狀態,而非具體操作步驟,降低學習和維護成本。
-
跨平臺兼容:支持 Linux、Windows、macOS 等操作系統,以及 AWS、Azure、GCP 等云平臺。
二、核心組件深度解析
2.1 控制節點(Control Node)
-
作用:運行 Ansible 命令和 Playbook,負責發起和管理自動化任務。
-
要求:需安裝 Python 3.8+ 及 Ansible 軟件包,可通過 SSH 連接被控節點。
-
注意:一個環境中可部署多個控制節點,但需確保 Inventory 和 Playbook 同步。
2.2 被控節點(Managed Node)
-
作用:被 Ansible 管理的目標設備,包括服務器、網絡設備、虛擬機等。
-
要求:
-
開啟 SSH 服務(Linux/Unix)或 WinRM 服務(Windows)。
-
安裝 Python 2.7 或 3.5+(部分模塊需特定版本支持)。
-
控制節點與被控節點之間網絡可達,且控制節點擁有登錄權限(密碼或密鑰認證)。
2.3 Inventory(主機清單)
-
定義:用于存儲被控節點的信息,支持靜態文件和動態生成兩種方式。
-
靜態 Inventory 格式:
# 簡單主機列表
# 直接列出單個主機,Ansible將使用默認SSH端口(22)連接
webserver1.example.com# 帶自定義端口的主機表示方式
# 格式:主機名:端口號,這里指定使用2222端口進行SSH連接
webserver2.example.com:2222 # 自定義SSH端口# 主機組定義
# [組名] 表示定義一個主機組
[webservers]
# 將以下主機加入webservers組
webserver1.example.com
webserver2.example.com[dbservers]
# 將以下主機加入dbservers組
dbserver1.example.com
dbserver2.example.com# 嵌套組
# :children 表示這是一個組的組(組包含其他組)
[all_servers:children]
# 將webservers組加入all_servers組
webservers
# 將dbservers組加入all_servers組
# 此時all_servers組包含了webservers和dbservers組中的所有主機
dbservers# 變量定義
# :vars 表示為該組定義變量,這些變量會應用到組內所有主機
[webservers:vars]
# 定義HTTP端口變量,可在Playbook中通過{{ http_port }}引用
http_port=80
# 定義最大請求數變量
max_requests=1000
- 動態 Inventory:通過腳本(如 Python、Shell)從云平臺(AWS EC2、VMware)或 CMDB 中動態獲取主機信息,適合大規模動態環境。
2.4 Module(模塊)
-
分類:
-
核心模塊(Core Modules):由 Ansible 官方維護,覆蓋常見操作(如 copy、service、yum)。
-
擴展模塊(Extras Modules):由社區貢獻,需通過 ansible-galaxy 安裝。
-
自定義模塊:通過 Python 或其他語言編寫,滿足特定業務需求。
-
執行邏輯:模塊以獨立腳本形式在被控節點上臨時運行,執行完成后自動清理,無需常駐內存。
2.5 Playbook(劇本)
-
結構:由一個或多個 Play 組成,每個 Play 包含目標主機、變量、任務等信息。
-
YAML 語法規則:
-
縮進使用空格(推薦 2 個空格),不支持 Tab。
-
列表項以 - 開頭。
-
鍵值對用 key: value 表示,值為字符串時可加引號(特殊字符需加引號)。
-
示例:
- name: 部署 Nginx 服務hosts: webserversbecome: yes # 切換為root權限vars:nginx_version: 1.21.6tasks:- name: 安裝 Nginxyum:name: "nginx-{{ nginx_version }}"state: present- name: 配置 Nginx 服務template:src: ./nginx.conf.j2dest: /etc/nginx/nginx.confnotify: 重啟 Nginx 服務 # 配置文件變化時觸發Handlerhandlers:- name: 重啟 Nginx 服務service:name: nginxstate: restarted
2.6 Role(角色)
-
作用:將 Playbook、變量、模板、文件等按功能模塊化,實現代碼復用和標準化。
-
目錄結構:
roles/
└── nginx/├── defaults/ # 默認變量(優先級低)│ └── main.yml├── vars/ # 角色變量(優先級高)│ └── main.yml├── tasks/ # 任務列表│ └── main.yml├── handlers/ # 處理器│ └── main.yml├── templates/ # 模板文件(.j2后綴)│ └── nginx.conf.j2└── files/ # 靜態文件└── index.html
- 使用方式:在 Playbook 中通過 roles 關鍵字引用角色。
三、工作流程詳解
- 準備階段:
-
控制節點編寫 Inventory,定義被控節點信息。
-
編寫 Playbook 或準備臨時命令,明確需要執行的任務。
- 執行階段:
-
控制節點解析 Playbook 或命令,確定目標主機和模塊。
-
通過 SSH/WinRM 連接被控節點,傳輸模塊和參數。
-
被控節點執行模塊,將結果(成功 / 失敗、輸出信息)返回給控制節點。
- 結果處理:
-
控制節點匯總所有被控節點的執行結果,以人類可讀的格式展示。
-
若配置了 handlers 且任務觸發了變化,執行相應的 handler 操作(如重啟服務)。
四、安裝與配置
4.1 控制節點安裝(CentOS 7)
# 安裝 EPEL 源
yum install -y epel-release# 安裝 Ansible
yum install -y ansible# 驗證安裝
ansible --version
# 輸出示例:
# ansible [core 2.14.3]
# config file = /etc/ansible/ansible.cfg
# configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
# ansible python module location = /usr/lib/python3.6/site-packages/ansible
# ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
# executable location = /usr/bin/ansible
# python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
# jinja version = 3.1.2
# libyaml = True
4.2 被控節點配置
- Linux 節點:
# 安裝 Python
yum install -y python3# 配置 SSH 免密登錄(控制節點操作)
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
ssh-copy-id root@被控節點IP
-
Windows 節點:
-
啟用 WinRM 服務,配置 PowerShell 遠程管理。
-
控制節點安裝 pywinrm 模塊:pip install pywinrm。
4.3 核心配置文件(ansible.cfg)
主要配置項:
[defaults]
inventory = /etc/ansible/hosts # 默認Inventory路徑
remote_user = root # 默認遠程用戶名
become = yes # 自動切換為root權限
become_method = sudo # 提權方式
become_user = root # 目標用戶
timeout = 30 # SSH連接超時時間(秒)
host_key_checking = False # 禁用主機密鑰檢查(測試環境用)
五、常用模塊實戰
5.1 文件操作模塊
- copy:復制文件到被控節點
ansible webservers -m copy -a "src=/local/path/file dest=/remote/path/file mode=0644 owner=root group=root"
- file:管理文件 / 目錄屬性
# 創建目錄
ansible webservers -m file -a "path=/data/logs state=directory mode=0755"
# 刪除文件
ansible webservers -m file -a "path=/tmp/test.txt state=absent"
- template:基于 Jinja2 模板生成文件
# Playbook中使用
- name: 生成Nginx配置文件template:src: ./nginx.conf.j2dest: /etc/nginx/nginx.confmode: 0644
5.2 包管理模塊
- yum(RedHat 系)
# 安裝指定版本
ansible webservers -m yum -a "name=httpd-2.4.6 state=present"
# 卸載軟件
ansible webservers -m yum -a "name=httpd state=absent"
# 更新所有包
ansible webservers -m yum -a "name=* state=latest"
- apt(Debian 系)
ansible dbservers -m apt -a "name=mysql-server state=installed update_cache=yes"
5.3 服務管理模塊
- service
# 啟動服務并設置開機自啟
ansible webservers -m service -a "name=httpd state=started enabled=yes"
# 重啟服務
ansible webservers -m service -a "name=httpd state=restarted"
5.4 命令執行模塊
- command:不支持管道和環境變量
ansible all -m command -a "ls /home"
- shell:支持 bash 特性
ansible all -m shell -a "ps aux | grep nginx"
- script:在被控節點執行本地腳本
ansible webservers -m script -a "/local/path/script.sh arg1 arg2"
六、Playbook 高級特性
6.1 變量管理
-
變量來源:
-
Inventory 變量(主機 / 組變量)
-
Playbook 中 vars 關鍵字定義
-
命令行 -e 參數傳遞(優先級最高)
-
角色變量(defaults/vars)
-
變量引用:使用 {{ variable_name }} 語法,如 {{ http_port }}。
6.2 條件判斷(when)
tasks:- name: 僅在CentOS系統安裝httpdyum:name: httpdstate: presentwhen: ansible_os_family == "RedHat"
6.3 循環(loop)
tasks:- name: 創建多個目錄file:path: "{{ item }}"state: directorymode: 0755loop:- /data/logs- /data/backup- /data/tmp
6.4 處理器(handlers)
用于在任務發生變化時執行操作(如配置文件更新后重啟服務):
tasks:- name: 更新Nginx配置template:src: nginx.conf.j2dest: /etc/nginx/nginx.confnotify: 重啟Nginx # 觸發handlerhandlers:- name: 重啟Nginxservice:name: nginxstate: restarted
七、常用命令詳解
7.1 ansible
-
功能:執行臨時命令,適合快速測試。
-
常用參數:
-
-i:指定 Inventory 文件路徑。
-
-m:指定模塊名稱。
-
-a:模塊參數。
-
-u:遠程用戶名。
-
-b:提權執行(sudo)。
-
示例:
ansible webservers -i ./my_hosts -u admin -b -m yum -a "name=httpd state=present"
7.2 ansible-playbook
-
功能:執行 Playbook。
-
常用參數:
-
-C/–check:模擬執行,不實際修改系統。
-
-v:顯示詳細輸出(-vvv 最詳細)。
-
-e:傳遞額外變量。
-
-t:只執行指定標簽的任務。
-
示例:
ansible-playbook -C -e "env=test" deploy.yml
7.3 ansible-galaxy
-
功能:管理 Ansible 角色和集合。
-
常用命令:
# 安裝角色
ansible-galaxy install geerlingguy.nginx
# 列出已安裝角色
ansible-galaxy list
# 創建新角色
ansible-galaxy init myrole
八、高級應用場景
8.1 滾動更新(Rolling Updates)
通過 serial 關鍵字控制每次更新的主機數量,實現零 downtime 部署:
- name: 滾動更新Web服務hosts: webserversserial: 2 # 每次更新2臺主機tasks:- name: 停止服務service:name: httpdstate: stopped- name: 部署新版本copy:src: ./new_version/dest: /var/www/html/- name: 啟動服務service:name: httpdstate: started
8.2 集成云服務
以 AWS 為例,使用 amazon.aws 集合管理 EC2 實例:
- name: 創建EC2實例hosts: localhostgather_facts: nocollections:- amazon.awstasks:- name: 啟動實例ec2:aws_access_key: "{{ aws_access_key }}"aws_secret_key: "{{ aws_secret_key }}"region: us-east-1instance_type: t2.microimage: ami-0c55b159cbfafe1f0count: 1key_name: my_keyvpc_subnet_id: subnet-123456assign_public_ip: yesstate: running
九、最佳實踐與注意事項
- 目錄結構標準化:
project/
├── inventory/ # 主機清單(按環境分文件)
│ ├── dev.yml
│ └── prod.yml
├── playbooks/ # 主Playbook
│ ├── deploy.yml
│ └── backup.yml
├── roles/ # 角色目錄
│ ├── web/
│ └── db/
├── group_vars/ # 組變量
│ └── webservers.yml
├── host_vars/ # 主機變量
│ └── webserver1.yml
└── ansible.cfg # 項目級配置
- 變量加密:使用 ansible-vault 加密敏感信息(如密碼、API 密鑰):
# 創建加密文件
ansible-vault create secrets.yml
# 編輯加密文件
ansible-vault edit secrets.yml
# 執行Playbook時解密
ansible-playbook --ask-vault-pass deploy.yml
-
版本控制:將 Playbook、角色等代碼納入 Git 管理,實現變更追蹤和協作。
-
測試策略:
-
使用 --check 模擬執行,驗證邏輯正確性。
-
在測試環境完全驗證后再部署到生產環境。
-
采用 Molecule 等工具進行角色單元測試。
- 性能優化:
- 啟用 SSH 長連接(ControlPersist)