- 一、什麼是Ansible
- 1、簡介
- 2、架構
- 3、工作流程
- 二、部署Ansible批次管理
- 1、涉及主機
- 2、安裝部署Ansible
- 2.1、yum安裝
- 2.2、其他方式
- 3、設定免密登入
- 3.1、控制節點設定hosts解析
- 3.2、生成金鑰對
- 3.3、將公鑰傳送給受管節點
- 3.4、測試免密登入
- 4、定義主機清單
- 4.1、ansible常見的配置檔案
- 4.2、備份主機清單檔案
- 4.3、修改主機清單,設定分組
- 三、Ansible引數說明及執行狀態
- 1、引數說明
- 2、Ansible的執行狀態
- 四、Ansible常用模組
- 1、ping模組
- 2、command模組
- 2.1、選項及描述
- 2.2、結合chdir和removes、creates列出指定目錄下內容
- 2.3、檢視磁碟空間
- 3、shell模組
- 3.1、選項及引數
- 3.2、檢查遠端主機的系統版本
- 3.3、檢視遠端主機防火牆狀態
- 3.4、建立、檢視指定目錄
- 4、user模組
- 4.1、選項及描述
- 4.2、新增系統使用者,指定uid、家目錄及註釋
- 4.3、檢視新建立的使用者
- 4.4、刪除新建立的使用者
- 5、group模組
- 5.1、選項及描述
- 5.2、建立或更新組
- 5.3、刪除組
- 6、copy模組
- 6.1、選項及描述
- 6.2、給定內容生成檔案,並修改許可權資訊
- 6.3、修改檔案內容,選擇覆蓋備份
- 7、fetch模組
- 7.1、選項及描述
- 7.2、從遠端主機抓取檔案
- 7.3、限制抓取檔案的大小、新增檔案存在檢測
- 8、file模組
- 8.1、選項及描述
- 8.2、在指定路徑下建立目錄
- 8.3、建立軟連結檔案
- 8.4、建立硬連結檔案
- 8.5、刪除檔案
- 9、yum模組
- 9.1、選項及描述
- 9.2、安裝httpd服務
- 9.3、更新所有的軟體包
- 10、cron模組
- 10.1、選項及描述
- 10.2、新增計劃任務
- 10.3、刪除指定計劃任務
- 11、service模組
- 11.1、選項及描述
- 11.2、遠端開啟/關閉防火牆
- 12、script模組
- 12.1、選項及描述
- 12.2、編輯並部署指令碼
- 1、控制節點本地編輯指令碼並新增執行許可權
- 2、透過script模組部署到遠端主機執行
- 13、setup模組
- 13.1、選項及描述
- 13.2、檢視記憶體資訊
- 透過free -m命令檢視記憶體大小是否一致
- 13.3、儲存資訊
- 14、synchronize模組
- 14.1、選項及描述
- 14.2、將源目錄同步至目標目錄(增量同步)
- 14.3、將源目錄同步至目標目錄(完全同步)
- 五、Ansible playbook
- 1、簡介
- 2、playbook的YAML格式
- 2.1、示例:
- 2.2、解析
- 3、playbook的執行與語法檢查
- 4、playbook的核心元素
- 5、基本元件及格式
- 6、安裝nginx並修改配置檔案
- 6.1、準備檔案存放目錄
- 6.2、編寫yaml檔案
- 6.3、編寫conf檔案
- 6.4、檢查語法錯誤,執行playbook
- 6.5、驗證nginx啟動狀態
- 7、安裝nginx,並新增handlers和notify
- 7.1、修改對應的nginx.yml和nginx.conf檔案
- 7.2、驗證nginx程序資訊
- 7.3、測試標籤
- 7.4、測試notify
- 7.4.1、notify的觸發條件是配置檔案被改變
- 7.4.2、重新執行劇本
- 7.4.3、重新檢視埠號
- 8、變數(variables)
- 8.1、定義變數的方式
- 1. Facts(Facts變數)
- 2. 使用者自定義變數
- 3. 透過Roles傳遞變數
- 4. Host Inventory(主機清單)中定義變數
- 8.2、優先順序
- 8.3、案例:使用變數安裝keepalived
- 1、編寫劇本
- 2、複製配置檔案
- 3、執行劇本,變數由命令列傳入
- 4、或者直接再劇本里定義變數
- 5、執行定義過變數的劇本
- 8.1、定義變數的方式
- 9、模板(templates)
- 9.1、簡介
- 9.2、基本資料型別和運算子
- 9.3、案例:生成hosts解析檔案
- 1、修改Ansible主機清單
- 2、修改主機名
- 3、準備模板檔案
- 4、編寫劇本
- 5、執行劇本
- 6、驗證
- 10、條件判斷
- 10.1、舉例
- 11、迴圈迭代
- 11.1舉例
- 11.2、案例:迴圈建立使用者
- 1、迴圈建立以下使用者資訊
- 2、迴圈建立出以上使用者並指定使用者資訊
- 3、執行劇本
- 4、驗證
- 12、字典
- 12.1、舉例
- 13、角色(role)
- 13.1、簡介
- 13.2、角色的目錄結構
- 14、案例:使用角色安裝nginx
- 14.1、建立對應的目錄結構
- 14.2、定義配置檔案
- 14.3、放置檔案到指定目錄
- 14.4、修改變數檔案
- 14.5、定義handlers檔案
- 14.6定義劇本檔案
- 14.7、剩餘的配置檔案
- 14.8、啟動服務
- 14.9、驗證埠號
- 15、案例:使用角色安裝httpd
- 15.1、建立對應的目錄結構
- 15.2、編寫site.yaml檔案
- 15.3、編寫tasks裡的main.yml檔案
- 15.4、執行劇本
- 15.5、驗證
- 16、案例:使用角色安裝java+nginx+halo
- 16.1、準備角色
- 16.2、編寫site.yml
- 16.3、編寫nginx角色
- 16.4、編寫java角色
- 16.5、編寫halo角色
- 16.6、執行劇本
- 16.7、驗證
一、什麼是Ansible
1、簡介
Ansible是一款自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批次系統部署、批次程式部署,批次執行命令等功能。
Ansible是基於模組工作的,本身沒有批次部署的能力,真正具有批次部署能力的是Ansible執行的模組,Ansible只是提供一個框架。Ansible不需要在遠端主機上安裝client/agents,因為它們是基於ssh來和遠端主機通訊的。
2、架構
- ansbile:核心程式
- modules:包括ansible自帶的核心模組以及自定義模組
- plugins:完成模組功能的補充,包括連線外掛,郵箱外掛
- palybooks:劇本,定義ansbile多工配置檔案,由ansible自動執行
- inventory:定義ansbile管理的主機清單
- connection plugins:負責和被監控端實現通訊
3、工作流程
- 載入配置檔案: Ansible 預設查詢
/etc/ansible/ansible.cfg
配置檔案,這個檔案包含了Ansible執行時的行為設定,如連線方式、外掛路徑等。 - 解析Inventory: Ansible 使用 Inventory 檔案(預設是
/etc/ansible/hosts
)來確定需要操作的目標主機或主機組。 - 編譯Playbook或命令: Ansible 準備執行的Playbook或直接執行的Ad-Hoc命令,並解析其中的任務和模組呼叫。
- 模組載入與執行策略準備: 對於每個任務,Ansible 載入相應的模組(如
command
模組),並準備執行上下文,包括變數、環境等。 - 生成並傳輸臨時指令碼: Ansible 會根據任務和模組生成一個或多個臨時的Python指令碼,並透過SSH連線傳輸到目標主機的臨時目錄,通常位於目標使用者的
~/.ansible/tmp/ansible-tmp-<UNIQUE_ID>/
目錄下。 - 賦予執行許可權: 在目標主機上,Ansible 會給這個臨時Python指令碼加上執行許可權,以便能夠執行。
- 執行遠端指令碼: Ansible 透過SSH在目標主機上執行這個臨時指令碼,並收集執行結果。
- 結果收集與處理: 執行完畢後,各個主機的執行結果被收集並彙總,Ansible根據這些結果決定是否繼續執行後續任務,或是根據Playbook中的錯誤處理邏輯(如
rescue
和always
塊)進行操作。 - 清理: 一旦任務執行完成,無論成功還是失敗,Ansible 會清理目標主機上的臨時檔案,包括刪除之前上傳的Python指令碼。
- 退出與報告: 清理完成後,Ansible 程序在目標主機上退出,並向控制機報告最終的執行狀態和結果。
二、部署Ansible批次管理
1、涉及主機
主機名 | 角色 | IP地址 |
---|---|---|
server | 控制節點 | 192.168.112.10 |
host1 | 受管節點 | 192.168.112.20 |
host2 | 受管節點 | 192.168.112.30 |
host3 | 受管節點 | 192.168.112.40 |
2、安裝部署Ansible
控制節點
2.1、yum安裝
yum install -y epel-release #Centos需要安裝EPEL倉庫
yum install -y ansible #yum包管理安裝Ansible
ansible --version #檢視Ansible安裝版本
2.2、其他方式
安裝管理主機
3、設定免密登入
3.1、控制節點設定hosts解析
[root@server ~]# vim /etc/hosts
192.168.112.10 server
192.168.112.20 host1
192.168.112.30 host2
192.168.112.40 host3
3.2、生成金鑰對
[root@server ~]# ssh-keygen -P "" -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:eSgh2wm7WxXS8n61UI4wKK0yEl3mLlzwIFBdOQSAgag root@server
The key's randomart image is:
+---[RSA 2048]----+
|B+=o++o. |
|+o B..oo |
|o . B *.= . |
|Eo o O * * + |
|. = = + S + o |
| . + . + . o . |
| . . . . . |
| o . |
| . |
+----[SHA256]-----+
-P ""
:設定空密碼-t rsa
: 指定生成金鑰的型別為RSA- 簡化後續實驗輸密碼操作
3.3、將公鑰傳送給受管節點
ssh-copy-id -i /root/.ssh/id_rsa.pub root@host1
ssh-copy-id -i /root/.ssh/id_rsa.pub root@host2
ssh-copy-id -i /root/.ssh/id_rsa.pub root@host3
過程中需要輸入受管節點的密碼
3.4、測試免密登入
ssh root@host1
ssh root@host2
ssh root@host3
4、定義主機清單
4.1、ansible常見的配置檔案
- /etc/ansible/ansible.cfg:主配置檔案
- /etc/ansible/hosts:主機清單檔案
- /etc/ansible/roles:角色目錄
4.2、備份主機清單檔案
cp -f hosts hosts.bak
4.3、修改主機清單,設定分組
vim /etc/ansible/hosts
[all-servers]
server
host1
host2
host3
[node1]
host1
[node2]
host2
[node3]
host3
[mysql_test]
host1
host2
[web_test]
host2
host3
[manager]
server
三、Ansible引數說明及執行狀態
1、引數說明
引數 | 說明 |
---|---|
-h |
顯示幫助資訊,包含可用的命令和選項。 |
-i |
指定Inventory檔案的路徑,預設為/etc/ansible/hosts 。 |
-l |
限制playbook或命令的作用範圍,僅對匹配的主機執行。 |
-u |
指定連線遠端主機時使用的使用者名稱。 |
-b |
在遠端主機上執行操作時臨時提升許可權,相當於使用sudo 。 |
--become-user=USER |
提升許可權後切換到的使用者。 |
-m |
用於ad-hoc命令,指定要使用的模組名。 |
-a |
指定模組的引數。 |
-f |
指定併發程序數,預設為5。 |
-v |
增加輸出的詳細程度,多次使用可獲得更多除錯資訊。 |
-vvv |
設定更詳細的輸出級別,有助於除錯。 |
--check |
執行模擬執行,不實際改變系統狀態,用以預覽操作效果。 |
--diff |
修改檔案時,顯示修改前後的差異。 |
-C |
檢查執行結果 |
-e |
指明變數名 |
--syntax-check |
檢查執行命令是否存在語法錯誤 |
2、Ansible的執行狀態
- 綠色:執行成功並且不需要做改變的操作
- 黃色:執行成功並且對目標主機做變更
- 紅色:執行失敗
- 粉色:警告資訊
- 藍色:顯示ansible命令執行的過程
四、Ansible常用模組
1、ping模組
主機連通性測試
#一個一個測試
ansible -m ping node1
ansible -m ping node2
ansible -m ping node3
ansible -m ping manager
#以組為單位測試
ansible -m ping all-servers
2、command模組
ansible的預設模組,用於在遠端主機上執行簡單的Linux命令,並將結果返回主機
不支援管道,變數及重定向等
2.1、選項及描述
ansible-doc -s command
選項 | 描述 |
---|---|
argv | 將命令作為列表而非字串傳遞。使用argv 可避免對原本會被誤解的值(例如使用者名稱中帶空格的情況)進行引用。只能提供字串或列表形式之一,不能同時提供。 |
chdir | 在執行命令前切換到此目錄。 |
cmd | 要執行的命令。 |
creates | 如果該檔案已經存在,此步驟不會執行。 |
removes | 如果該檔案存在,此步驟將會執行。 |
stdin | 直接將指定的值設定為命令的stdin。 |
stdin_add_newline | 如果設定為yes ,在stdin資料末尾追加換行符。 |
strip_empty_ends | 從stdout/stderr結果的結尾去除空行。 |
warn | 啟用或禁用任務警告。 |
2.2、結合chdir和removes、creates列出指定目錄下內容
#node1組先切換到root目錄下aliyun.sh檔案存在不執行ls
ansible node1 -m command -a 'chdir=/root/ creates=aliyun.sh ls'
#node1組先切換到root目錄下aliyun.sh檔案存在就執行ls
ansible node1 -m command -a 'chdir=/root/ removes=aliyun.sh ls'
2.3、檢視磁碟空間
#檢視mysql_test組中所有主機的磁碟空間
ansible mysql_test -m command -a 'df -h'
#檢視web_test組中所有主機的磁碟空間
ansible web_test -m command -a 'df -h'
3、shell模組
shell模組可以在遠端主機上呼叫shell直譯器執行命令,支援shell的各種功能,例如管道等。
3.1、選項及引數
ansible-doc -s command
選項 | 描述 |
---|---|
chdir | 在執行命令前切換到此目錄。 |
cmd | 要執行的命令及其可選引數。 |
creates | 當指定的檔案已存在時,此步驟將不執行。 |
executable | 更改用於執行命令的shell。這需要shell可執行檔案的絕對路徑。 |
free_form | 要執行的Linux指令,一般使用Ansible的-a引數代替。 |
removes | 當指定的檔案存在時,此步驟將執行。 |
stdin | 直接將指定的值設定為命令的stdin。 |
stdin_add_newline | 是否在stdin資料末尾新增換行符。 |
warn | 是否啟用任務警告。 |
3.2、檢查遠端主機的系統版本
#檢視mysql_test組遠端主機的系統版本
ansible mysql_test -m shell -a 'cat /etc/os-release | grep PRETTY_NAME | cut -d "=" -f2'
#檢視web_test組遠端主機的系統版本
ansible web_test -m shell -a 'cat /etc/os-release | grep PRETTY_NAME | cut -d "=" -f2'
3.3、檢視遠端主機防火牆狀態
#檢視mysql_test組中所有的主機防火牆firewalld和selinux的狀態
ansible mysql_test -m shell -a 'systemctl status firewalld ; getenforce'
這裡驗證了
command
模組不能使用命令別名、管道、重定向以及邏輯運算子(如;
,&&
,||
)由於
command
模組直接將整個字串傳遞給系統執行,分號;
以及隨後的getenforce
命令被視為命令的一部分,而不是獨立的指令。這導致系統嘗試查詢名為類似\x3b.service
(分號;
的ASCII轉義序列)的服務狀態,以及嘗試將getenforce
當作一個服務單元來查詢,由於這兩個都不是有效的服務單元名稱,因此返回了錯誤資訊。
3.4、建立、檢視指定目錄
#在mysql_test組下的主機迴圈建立/root/tmp_1/NOW+當前時間的目錄
ansible mysql_test -m shell -a "mkdir -p /root/tmp_1/NOW-$(date +'%H:%M:%S')"
#find查詢是否正確建立
ansible mysql_test -m shell -a "find /root/tmp_1 -mmin -5"
4、user模組
主要用於管理遠端系統上的使用者賬戶,包括建立、修改和刪除使用者。
它允許你設定使用者的密碼、shell、主目錄、許可權等屬性
4.1、選項及描述
ansible-doc -s user
選項 | 描述 |
---|---|
comment | 使用者的描述資訊 |
createhom | 是否建立家目錄 |
force | 在使用state=absent時, 行為與userdel –force一致 |
group | 指定基本組 |
groups | 指定附加組,如果指定為(groups=)表示刪除所有組 |
home | 指定使用者家目錄 |
move_home | 如果設定為home=時, 試圖將使用者主目錄移動到指定的目錄 |
name | 指定使用者名稱 |
non_unique | 該選項允許改變非唯一的使用者ID值 |
password | 指定使用者密碼 |
remove | 在使用state=absent時, 行為是與userdel –remove一致 |
shell | 指定預設shell |
state | 設定帳號狀態,預設為present表示新建使用者,指定值為absent表示刪除 |
system | 當建立一個使用者,設定這個使用者是系統使用者。這個設定不能更改現有使用者 |
uid | 指定使用者的uid |
update_password | 更新使用者密碼 |
expires | 指明密碼的過期時間 |
append | 新增一個新的組 |
4.2、新增系統使用者,指定uid、家目錄及註釋
#給web_test組中新增一個系統使用者zhangsan家目錄為/home/zhangsan,使用者id為111,註釋資訊為hello zhangsan
ansible web_test -m user -a "system=yes name=zhangsan home=/home/zhangsan uid=111 comment='hello zhangsan'"
4.3、檢視新建立的使用者
#id zhangsan驗證使用者是否正確建立,使用grep+awk擷取/etc/passwd上關於zhangsan的註釋資訊
ansible web_test -m shell -a 'id zhangsan ; grep ^zhangsan: /etc/passwd | awk -F ":" '\''{print $5}'\'''
4.4、刪除新建立的使用者
#刪除使用者zhangsan
ansible web_test -m user -a "name=zhangsan state=absent remove=yes"
5、group模組
用於管理Linux系統中的使用者組。
這個模組允許你新增或刪除使用者組,並且可以設定組ID(GID)。
5.1、選項及描述
ansible-doc -s group
選項 | 描述 |
---|---|
gid | 用於設定使用者組的GID(組ID)。 |
local | 強制使用平臺提供的本地命令替代品(如lgroupadd 代替groupadd ),適用於需要操作本地組的集中認證環境。此選項要求目標主機上存在這些命令,否則會導致致命錯誤。 |
name | (必需)指定組的名稱。 |
non_unique | 允許將組ID更改為非唯一值。需要與gid 一起使用。不支援macOS或BusyBox發行版。 |
state | 指定使用者組在遠端主機上應有的狀態,可以是present (存在)或absent (不存在)。 |
system | 如果設定為yes ,表示建立的使用者組是系統組。 |
5.2、建立或更新組
#在web_test組的所有主機上建立一個系統組web_test,組id為1010
ansible web_test -m group -a "name=web_test gid=1010 system=yes"
#透過/etc/group檢視系統組web_test資訊
5.3、刪除組
#刪除web_test組所有主機上的系統組web_test
ansible web_test -m group -a "name=web_test gid=1010 state=absent"
6、copy模組
用於將本地檔案或目錄複製到遠端主機上
支援檔案、目錄、許可權、使用者組功能
6.1、選項及描述
ansible-doc -s copy
選項 | 描述 |
---|---|
backup | 在覆蓋之前,將原始檔備份,備份檔案包含時間資訊。 |
content | 用於替代“src”,可以直接設定指定檔案的值 |
dest | 必選項。要將原始檔複製到的遠端主機的絕對路徑 |
directory_mode | 遞迴設定目錄的許可權,預設為系統預設許可權 |
force | 當目標主機包含該檔案,但內容不同時,設為"yes",表示強制覆蓋;設為"no",表示目標主機的目標位置不存在該檔案才複製。預設為"yes" |
follow | 支援link檔案複製 |
others | 所有file模組裡的選項都可以在這裡使用 |
src | 被複制到遠端主機的本地檔案。可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,則會遞迴複製,用法類似於"rsync" |
6.2、給定內容生成檔案,並修改許可權資訊
#將copy內容為copy test複製到node3主機的/root/copy.txt並設定許可權666
ansible node3 -m copy -a 'content="copy test" dest=/root/copy.txt mode=666'
6.3、修改檔案內容,選擇覆蓋備份
#修改node3主機上copy.txt檔案內容,並選擇備份
ansible node3 -m copy -a 'content="copy test_1\n" backup=yes dest=/root/copy.txt mode=666'
7、fetch模組
Ansible 的
fetch
模組用於從遠端節點抓取檔案並儲存到Ansible控制器(執行Ansible任務的機器)上的指定目錄
7.1、選項及描述
ansible-doc -s fetch
選項 | 描述 |
---|---|
dest | 必選項,用來存放檔案的目錄 |
src | 必選項,在遠端拉取的檔案,並且必須是一個file,不能是目錄 |
flat | 當設定為yes 時,即使src 是一個目錄,也會將所有內容扁平化儲存到指定的dest 目錄下,而不是保留目錄結構。( 預設no ) |
validate_checksum | 當設定為yes 時,在下載完成後校驗檔案的校驗和,確保檔案完整無誤。這可以用來防止因網路問題導致的檔案損壞。(預設no ) |
fail_on_missing | 當設定為yes 時,如果遠端檔案不存在,則標記任務失敗,否則只是簡單地跳過該檔案。(預設no ) |
size | 限制要抓取的檔案大小,可以使用字尾如k 、M 、G 來指定單位(千位元組、兆位元組、吉位元組)。如果遠端檔案超過指定大小,抓取操作將不會執行。 |
timeout | 設定超時時間(秒),用於等待檔案傳輸完成。預設情況下,Ansible使用其內部的連線超時設定。 |
force | 即使本地檔案已經存在,也強制重新抓取。如果設定為no ,則只有當遠端檔案比本地檔案新或不同才執行抓取。(預設yes ) |
unarchive | 如果src 是指向一個歸檔檔案(如.zip或.tar.gz),並且設定了此選項為yes ,Ansible將在抓取後嘗試解壓該歸檔檔案。(預設no ) |
list_files | 當設定為yes 時,模組將只列出遠端目錄下的檔案而不實際抓取它們,可用於預覽目的。(預設no ) |
7.2、從遠端主機抓取檔案
#從mysql_test組的主機中抓取aliyun.sh檔案到本機的/tmp/data目錄下
ansible mysql_test -m fetch -a "src=/root/aliyun.sh dest=/tmp/data"
#透過檢查/tmp/data下的目錄結構可知檔案已完整獲取
ansible manager -m shell -a "tree -L 5 /tmp/data"
7.3、限制抓取檔案的大小、新增檔案存在檢測
#從mysql_test組的主機中抓取install.sh檔案,限制最大抓取大小20kb,傳輸中校驗檔案完整性,新增檔案存在檢測(不存在任務失敗)
ansible mysql_test -m fetch -a "src=/root/install.sh dest=/tmp/data/ verify_checksum=yes fail_on_missing=yes size=20k"
8、file模組
file模組主要用於對檔案的建立、刪除、修改、許可權、屬性
8.1、選項及描述
ansible-doc -s file
選項 | 描述 |
---|---|
path | 必選項,定義檔案/目錄的路徑 |
mode | 定義檔案/目錄的許可權 |
force | 需要在兩種情況下強制建立軟連結,一種是原始檔不存在,但之後會建立的情況下;另一種是目標軟連結已存在,需要先取消之前的軟鏈,然後建立新的軟鏈,有兩個選項:yes |
group | 定義檔案/目錄的屬組,後面可以加上mode :定義檔案/目錄的許可權 |
owner | 定義檔案/目錄的屬主。後面必須跟上path :定義檔案/目錄的路徑 |
recurse | 遞迴設定檔案的屬性,只對目錄有效,後面跟上src :被連結的原始檔路徑,只應用於state=link 的情況 |
dest | 被連結到的路徑,只應用於state=link 的情況 |
src | 被連結的原始檔路徑,只應用於state=link的情況 |
state | 狀態,有以下選項:directory 、file 、link 、hard 、touch 、absent |
8.2、在指定路徑下建立目錄
#在mysql_test組所有主機在/tmp/路徑下建立許可權都是隻讀、屬主屬組都是root的file1目錄
ansible mysql_test -m file -a "path=/tmp/file1 mode=444 owner=root group=root state=directory"
#檢視建立好的目錄
ansible mysql_test -m shell -a "ls -l /tmp/ | grep file1"
8.3、建立軟連結檔案
#給mysql_test組的所有主機建立軟連結檔案test1指向/root/aliyun.sh
ansible mysql_test -m file -a "path=/tmp/test1 src=/root/aliyun.sh state=link"
8.4、建立硬連結檔案
#給mysql_test組的所有主機建立硬連結檔案test1指向/root/aliyun.sh
ansible mysql_test -m file -a "path=/tmp/test2 src=/root/aliyun.sh state=hard"
8.5、刪除檔案
#刪除mysql_test組中所有主機/tmp/目錄下test1
ansible mysql_test -m file -a "path=/tmp/test1 state=absent"
9、yum模組
主要用於在基於 RPM 的 Linux 系統上管理軟體包。
它允許使用者安裝、更新、解除安裝軟體包,並可配置額外的選項以控制操作的具體行為。
9.1、選項及描述
ansible-doc -s yum
選項 | 描述 |
---|---|
name | 必選項,所安裝的包的名稱 |
state | 安裝-> present ; 安裝最新版本的-> latest ;absent-> 解除安裝包 |
update_cache | 強制更新yum的快取 |
conf_file | 指定遠端yum安裝時所依賴的配置檔案(安裝本地已有的包)。 |
disable_pgp_check | 是否禁止GPG checking,只用於present or latest 。 |
disablerepo | 臨時禁止使用yum庫。 只用於安裝或更新時。 |
enablerepo | 臨時使用的yum庫。只用於安裝或更新時。 |
skip_borken | 跳過異常軟體節點 |
autoremove | 當設定為yes 且狀態為absent 時,自動移除不再被任何已安裝包依賴的包。 |
9.2、安裝httpd服務
#給web_test組的所有主機安裝httpd服務
ansible web_test -m yum -a "name=httpd state=present"
#遠端啟動httpd服務
ansible web_test -m shell -a "systemctl start httpd"
#遠端檢視http服務程序
ansible web_test -m shell -a "ps aux | grep httpd"
#遠端停止httpd服務
ansible web_test -m shell -a "systemctl stop httpd"
#遠端解除安裝httpd服務
ansible web_test -m yum -a "name=httpd state=absent"
安裝 |
---|
檢視程序 |
解除安裝 |
9.3、更新所有的軟體包
#給所有主機更新所有的軟體包
ansible all-servers -m yum -a "name=* state=latest"
10、cron模組
用於新增、刪除、更新作業系統的Crontab計劃任務
10.1、選項及描述
ansible-doc -s cron
選項 | 描述 |
---|---|
backup | 如果設定,會在修改crontab前建立備份。備份檔案的位置透過backup_file 變數返回。 |
cron_file | 如果指定,將使用此檔案而非使用者個人的crontab。如果是相對路徑,則相對於/etc/cron.d/ 。絕對路徑通常為/etc/crontab 。為了使用cron_file 引數,必須同時指定user 。 |
day | 任務應執行的月份中的日期 (1-31, *, */2, 等)。 |
disabled | 如果任務應在crontab中被禁用(註釋掉)。僅當state=present 時有效。 |
env | 如果設定,管理crontab的環境變數。新變數會被新增到crontab的頂部。name 和value 引數分別為環境變數的名稱和值。 |
hour | 任務應執行的小時 (0-23, *, */2, 等)。 |
insertafter | 與state=present 和env 一起使用。如果指定,環境變數將在指定環境變數宣告之後插入。 |
insertbefore | 與state=present 和env 一起使用。如果指定,環境變數將在指定環境變數宣告之前插入。 |
job | 要執行的命令,或者如果設定了env ,則是環境變數的值。命令不應包含換行符。當state=present 時必需。 |
minute | 任務應執行的分鐘 (0-59, *, */2, 等)。 |
month | 任務應執行的年份中的月份 (1-12, *, */2, 等)。 |
name | crontab條目的描述,或者如果設定了env ,則是環境變數的名稱。當state=absent 時必需。注意,如果不設定name,且state=present ,則總是會建立新的crontab條目,不管已有條目如何。此引數在未來的版本中將始終是必需的。 |
special_time | 特殊的時間範圍,引數:reboot(重啟時),annually(每年),monthly(每月),weekly(每週),daily(每天),hourly(每小時) |
state | 確保任務或環境變數存在或不存在的狀態。 |
user | 應修改其crontab的具體使用者。未設定時,預設為使用root 。 |
weekday | 任務應執行的星期幾 (0-6 表示週日-週六,*, 等)。 |
10.2、新增計劃任務
#給mysql_test組中的所有主機新增一個以root使用者每天三點執行/root/aliyun.sh指令碼的計劃任務
ansible mysql_test -m cron -a "name='Daily Task' minute=0 hour=3 job='/root/aliyun.sh &> /dev/null' user=root"
10.3、刪除指定計劃任務
#刪除名為Daily Task的計劃任務(沒有明確的計劃任務名稱寫完整的計劃任務也可以刪除)
ansible mysql_test -m cron -a "name='Daily Task' state=absent"
11、service模組
Ansible的
service
模組用於管理系統服務(如啟動、停止、重啟服務等)。這個模組與特定的系統服務管理工具(如systemd、sysvinit、upstart等)相容,能夠跨不同的Linux發行版和系統管理框架工作
11.1、選項及描述
ansible-doc -s service
選項 | 描述 |
---|---|
arguments | 額外的命令列引數,提供給服務管理命令。 |
enabled | 服務是否應該在系統啟動時自動啟動。至少需要指定state 或enabled 中的一個。 |
name | (必需)服務的名稱。 |
pattern | 如果服務不響應狀態查詢命令,可以指定一個子字串作為查詢依據,該子字串應能在ps 命令的輸出中找到,作為服務狀態的替代判斷。如果找到該字串,服務將被認為已啟動。 |
runlevel | 僅針對OpenRC初始化指令碼(如Gentoo)使用。指定該服務屬於哪個執行級別。 |
sleep | 當服務處於restarted 狀態時,停止與啟動命令之間暫停的秒數。有助於解決那些在發出停止訊號後立即退出的不良行為初始化指令碼問題。並非所有服務管理器都支援此設定,例如使用systemd時,此設定會被忽略。 |
state | 有四種狀態,分別為:started --->啟動服務, stopped --->停止服務, restarted --->重啟服務, reloaded --->過載配置 |
use | 服務模組通常透過自動檢測使用系統特定的模組,此設定可以強制使用特定模組。預設情況下,它使用ansible_service_mgr 事實的值,並且在找不到匹配項時回退到舊的service 模組。 |
11.2、遠端開啟/關閉防火牆
#給web_test組中的所有主機重啟firewalld服務
ansible web_test -m service -a "name=firewalld state=restarted"
#檢視web_test組中所有主機的firewalld服務執行狀態
ansible web_test -m shell -a "systemctl status firewalld"
#給web_test組中的所有主機關閉firewalld服務
ansible web_test -m service -a "name=firewalld state=stopped"
開啟firewalld服務 |
---|
檢視firewalld服務狀態 |
關閉firewalld服務 |
12、script模組
Ansible的
script
模組允許你在遠端主機上執行位於Ansible控制節點上的本地指令碼
12.1、選項及描述
ansible-doc -s script
選項 | 描述 |
---|---|
chdir | 在遠端節點上執行指令碼之前切換到的目錄路徑。 |
cmd | 要在遠端節點上執行的本地指令碼的路徑,後面可以跟上可選的引數。注意,這個選項與free_form 二選一使用。 |
creates | 指定遠端節點上的一個檔名,如果該檔案已存在,則此步驟將不執行,可用於防止重複執行指令碼。 |
decrypt | 控制是否自動解密使用Vault加密的原始檔。 |
executable | 用於呼叫指令碼的可執行檔案的名稱或路徑,例如如果指令碼是Python指令碼,可以設定為/usr/bin/python 。 |
free_form | 直接提供本地指令碼檔案的路徑以及可選的引數,與cmd 選項作用相似但格式不同,兩者選其一使用。 |
removes | 指定遠端節點上的一個檔名,如果該檔案不存在,則此步驟將不執行,可以作為執行指令碼的另一個條件。 |
12.2、編輯並部署指令碼
1、控制節點本地編輯指令碼並新增執行許可權
vim /tmp/df.sh
#!/bin/bash
date >> /tmp/data/df.log
df -lh >> /tmp/data/df.log
[root@server ~]# chmod +x /tmp/df.sh
2、透過script模組部署到遠端主機執行
#給web_test組的所有主機執行控制節點上的df.sh指令碼檔案
ansible web_test -m script -a "/tmp/df.sh”
13、setup模組
Ansible的
setup
模組用於收集遠端主機的資訊,並將這些資訊以facts的形式返回給Ansible控制節點。這些facts可以包括系統變數(如作業系統型別、架構、網路配置、已安裝軟體包等),並且在Playbook執行期間可以被其他任務使用。
13.1、選項及描述
ansible-doc -s setup
選項 | 描述 |
---|---|
fact_path | 用於存放本地Ansible事實(*.fact 檔案)的路徑。此目錄下的檔案如果可執行,將被執行,其結果會被新增到ansible_local 事實中;如果檔案不可執行,則會被讀取。適用於從2.1版本開始。檔案/結果格式可以是JSON或INI格式。預設的fact_path 可以在ansible.cfg 中為自動呼叫setup 作為gather_facts 一部分時指定。Windows環境下有特定選項,請檢視註釋。 |
filter | 如果提供,僅返回匹配此shell風格(fnmatch萬用字元)的變數。這允許篩選出特定的facts進行檢視或使用。 |
gather_subset | 如果提供,限制收集的額外事實子集。可能的值包括:all (全部)、min (最小集合)、hardware (硬體資訊)、network (網路資訊)、virtual (虛擬化資訊)、ohai (類似Chef Ohai的擴充套件資訊)、facter (使用Facter收集的資訊)。可以指定值的列表來定義更大的子集。值前可加! 來排除特定子集的收集,例如:!hardware,!network,!virtual,!ohai,!facter 。如果指定!all ,則只收集最小集合。要避免收集最小集合,可以指定!all,!min 。要僅收集特定事實,使用!all,!min 並指定特定的事實子集。如果只想隱藏某些收集到的事實,使用filter 引數。 |
gather_timeout | 設定單個事實收集的預設超時時間(以秒為單位)。這有助於控制事實收集過程,避免因個別慢速收集導致整個任務超時。 |
13.2、檢視記憶體資訊
#檢視mysql_test組所有主機的記憶體資訊
ansible mysql_test -m setup -a "filter='*mem*'"
透過free -m命令檢視記憶體大小是否一致
#透過free -m命令檢視mysql_test組主機的記憶體資訊
ansible mysql_test -m shell -a "free -m"
13.3、儲存資訊
#將篩選的資訊儲存到控制節點的/tmp/data目錄下
ansible web -m setup -a 'filter="*mem*"' --tree /tmp/data
14、synchronize模組
Ansible的
synchronize
模組提供了使用rsync進行檔案和目錄同步的功能。rsync是一個快速且高效的檔案傳輸工具,支援增量更新,特別適合在遠端主機之間同步大量檔案或保持資料夾內容的一致性。
14.1、選項及描述
ansible-doc synchronize
選項 | 描述 |
---|---|
archive | 映象rsync的歸檔標誌,啟用遞迴、連結、許可權、時間戳、所有者、組標誌及-D。預設開啟。 |
checksum | 基於校驗和而非修改時間和大小來跳過同步,注意“archive”選項預設仍啟用,"checksum"選項不會禁用它。預設關閉。從1.6版本起可用。 |
compress | 在傳輸過程中壓縮檔案資料。大多數情況下應保持啟用狀態,除非引起問題。預設開啟。從1.7版本起可用。 |
copy_links | 將符號連結作為它們指向的物件(被連結項)複製,而不是複製符號連結本身。預設關閉。 |
delete | 刪除目標路徑中不存在於源路徑的檔案(在傳輸之後,不是之前)。此選項要求recursive=yes 。表現得像rsync的--delete-excluded 選項,忽略被排除的檔案。預設關閉。 |
dest | 同步的目的地主機路徑,將從源路徑同步而來。路徑可以是絕對或相對的。此選項是必須的。 |
dest_port | 目標主機SSH埠。在Ansible 2.0之前,ansible_ssh_port庫存變數優先於這個值。此引數預設為ansible_ssh_port 或ansible_port 的值、remote_port 配置設定的值,或如果沒有設定前者,則使用SSH客戶端配置的值。從1.5版本起可用。 |
dirs | 僅傳輸目錄而不遞迴進入。預設關閉。 |
existing_only | 跳過在接收端建立新檔案。預設關閉。從1.5版本起可用。 |
group | 保留組資訊。預設值取決於archive選項。 |
link_dest | 新增一個硬連結目標,在rsync期間與之關聯。預設為無。從2.5版本起可用。 |
links | 作為符號連結複製符號連結。預設值取決於archive選項。 |
mode | 指定同步的方向。推模式下,本地主機或代理是源;拉模式下,上下文中的遠端主機是源。(可選值:pull, push)預設為push。 |
owner | 保留所有者(僅超級使用者)。預設值取決於archive選項。 |
partial | 告訴rsync保留部分檔案,這應該會使後續傳輸檔案剩餘部分快得多。預設關閉。從2.0版本起可用。 |
perms | 保留許可權資訊。預設值取決於archive選項。 |
private_key | 為基於SSH的rsync連線指定私鑰(如~/.ssh/id_rsa )。預設為無。從1.6版本起可用。 |
recursive | 遞迴進入目錄。預設值取決於archive選項。 |
rsync_opts | 透過傳遞陣列來指定額外的rsync選項。注意,rsync_opts 中的空字串最終會傳輸當前工作目錄。預設為無。從1.6版本起可用。 |
rsync_path | 指定在遠端主機上執行的rsync命令。參見rsync手冊頁上的--rsync-path 。要指定在本地主機上執行的rsync命令,你需要設定任務變數ansible_rsync_path 。預設為無。 |
rsync_timeout | 為rsync命令指定一個超時時間(秒)。預設為0。 |
set_remote_user | 為遠端路徑新增user@。如果你有自定義的ssh配置來為與庫存使用者不匹配的主機定義遠端使用者,應將此引數設為no 。預設為True。 |
src | 源主機上的路徑,將同步到目的地。路徑可以是絕對或相對的。此選項是必須的。 |
times | 保留修改時間。預設值取決於archive選項。 |
use_ssh_args | 使用ansible.cfg中指定的ssh_args。預設關閉。從2.0版本起可用。 |
verify_host | 驗證目標主機金鑰。預設關閉。從2.0版本起可用。 |
14.2、將源目錄同步至目標目錄(增量同步)
#既然是基於rsync那麼所有主機安裝rsync
ansible all-servers -m shell -a "yum install -y rsync"
#將本地的/tmp/目錄同步到node1組的host1主機上
ansible node1 -m synchronize -a "src=/tmp/ dest=/tmp/"
#檢視node1組的host1主機的/tmp/目錄結構
ansible node1 -m shell -a "tree -L 5 /tmp/"
所有主機安裝rsync |
---|
同步本地/tmp/到host1主機上 |
檢視目錄結構 |
14.3、將源目錄同步至目標目錄(完全同步)
#刪除目標路徑中不存在於源路徑的檔案(在傳輸之後)
ansible node1 -m synchronize -a "src=/tmp/ dest=/tmp/ delete=yes"
五、Ansible playbook
1、簡介
Ansible Playbook 是Ansible用於定義和執行自動化任務的配置、部署和編排的主要方式。它是一種使用YAML語言編寫的劇本檔案,允許使用者以簡潔、可讀性強的方式描述一系列步驟,這些步驟可以跨多臺主機執行,以實現系統的配置管理和應用程式部署。
playbook是由一個或者多個play組成的列表,可以讓這些列表按事先編排的機制執行;所謂task是呼叫ansible的具體模組,在模組引數中可以使用變數。模組執行是冪等性的,意味著多次執行結果相同。使用yaml語言編寫playbook,字尾名一般為.yml
2、playbook的YAML格式
- 檔案的第一行應該以 "---" (三個連字元)開始,表明YMAL檔案的開始。
- 在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。
- YMAL中的列表元素以”-”開頭然後緊跟著一個空格,後面為元素內容。
- 同一個列表中的元素應該保持相同的縮排。否則會被當做錯誤處理。
- play中hosts,variables,roles,tasks等物件的表示方法都是鍵值中間以":"分隔表示,":"後面還要增加一個空格。
- 縮排:使用空格縮排(而非Tab),通常使用2個空格
2.1、示例:
---
- name: update web servers
hosts: node1
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: write the apache config file
template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
- name: ensure that htppd is started
service:
name: httpd
state: started
- name: update db servers
hosts: node1
remote_user: root
tasks:
- name: ensure mariadb is at the latest version
yum:
name: mariadb-server
state: latest
- name: ensure that mariadb is started
service:
name: mariadb
state: started
2.2、解析
Play 1: 更新Web伺服器
- Play標題:"update web servers",表明本Play的目標是更新Web伺服器配置。
- hosts:
node1
,指定該Play作用於名為node1
的主機。 - remote_user:
root
,指定執行任務的遠端使用者為root。 - tasks:
- task 1: 確保Apache是最新的版本。使用
yum
模組安裝httpd
包至最新版。 - task 2: 寫入Apache配置檔案。使用
template
模組將模板檔案/srv/httpd.j2
渲染後複製到/etc/httpd.conf
,允許動態配置生成。 - task 3: 確保Apache服務已啟動。使用
service
模組設定httpd
服務的狀態為started
,如果服務未執行則啟動。
- task 1: 確保Apache是最新的版本。使用
Play 2: 更新資料庫伺服器
- Play標題:"update db servers",目標是更新資料庫伺服器配置。
- hosts:同樣為
node1
,指定該Play作用於名為node1
的主機。 - remote_user:
root
,指定執行任務的遠端使用者為root。 - tasks:
- task 1: 確保MariaDB是最新的版本。使用
yum
模組安裝mariadb-server
至最新版。 - task 2: 確保MariaDB服務已啟動。使用
service
模組設定mariadb
服務的狀態為started
。
- task 1: 確保MariaDB是最新的版本。使用
3、playbook的執行與語法檢查
#執行playbook
ansible-playbook playbook.yml
#語法檢查
ansible-playbook --syntax-check playbook.yml
4、playbook的核心元素
- Hosts(主機組):定義了Playbook將要操作的目標機器集合。可以是單個主機名、IP地址,也可以是主機組名。
- Tasks(任務列表):構成Play的主要部分,定義了在目標主機上執行的具體操作序列。每個任務通常關聯一個特定的Ansible模組及引數。
- Variables(變數):用於在Playbook中傳遞和管理配置資訊,支援多種設定方式(如直接賦值、變數檔案、環境變數、角色預設變數等),增加了Playbook的靈活性和可重用性。
- Templates(模板):使用Jinja2模板引擎動態生成配置檔案。允許根據變數插入動態內容,適用於需要根據不同環境定製配置的情況。
- Handlers(處理程式):特殊型別的任務,僅當被其他任務透過
notify
屬性明確告知時才會執行。常用於服務重啟等需要在特定條件滿足時進行的操作。
5、基本元件及格式
-
remote_user:指定執行Ansible任務的遠端使用者名稱。
-
sudo_user:定義需要臨時提升許可權執行任務時的目標使用者。
-
Tasks格式:
tasks: - name: 簡短任務描述 module: 模組名稱 arguments: 引數列表 notify: 通知的處理程式名稱(可選)
-
Handlers格式:
handlers: - name: 處理程式描述 module: 模組名稱 arguments: 引數列表
- Handlers觸發條件:
- 當某任務狀態變為
changed
時,可以觸發一個或多個預先定義好的處理程式。 - 使用
tags
為任務和處理程式打標籤,可以在執行Playbook時透過--tags
或-t
選項選擇性地執行帶有特定標籤的任務。
- 當某任務狀態變為
- Handlers觸發條件:
-
模組與模組引數:Ansible透過各種模組執行具體操作,模組後跟隨的是該模組接受的引數。對於
shell
和command
這類直接執行系統命令的模組,引數直接是命令字串,而不是鍵值對形式。
6、安裝nginx並修改配置檔案
6.1、準備檔案存放目錄
[root@server ~]# mkdir -p /root/ansible/{conf,bin}
6.2、編寫yaml檔案
[root@server ~]# cd ansible/bin/
[root@server bin]# cat nginx.yml
---
- name: Update web servers
hosts: node1
remote_user: root
tasks:
- name: Install epel
yum:
name: epel-release.noarch
state: latest
- name: Install nginx
yum:
name: nginx
state: present
- name: Copy nginx configure file
copy:
src: /root/ansible/conf/nginx.conf
dest: /etc/nginx/nginx.conf
backup: yes
- name: Start nginx
service:
name: nginx
state: restarted
- name: Create index.html
shell: echo "hello playbook_nginx" > /usr/share/nginx/html/index.html
6.3、編寫conf檔案
[root@server conf]# cat site.conf
events {
worker_connections 1024;
}
http {
server {
listen 8080;
server_name 192.168.112.20:8080;
location / {
index index.html;
}
}
}
6.4、檢查語法錯誤,執行playbook
#語法檢查
ansible-playbook nginx.yml --syntax-check
#執行playbook
ansible-playbook nginx.yml
6.5、驗證nginx啟動狀態
#ps aux|grep nginx顯示nginx的程序,curl -s 檢視實際的響應體內容
ansible node2 -m shell -a "ps aux | grep nginx ; curl -s 192.168.112.30:8080"
7、安裝nginx,並新增handlers和notify
7.1、修改對應的nginx.yml和nginx.conf檔案
nginx2.yml
---
- name: Update web servers
hosts: node2
remote_user: root
tasks:
- name: Install epel
yum:
name: epel-release.noarch
state: latest
- name: Install nginx
yum:
name: nginx
state: present
- name: Copy nginx configure file
copy:
src: /root/ansible/conf/nginx2.conf
dest: /etc/nginx/nginx2.conf
backup: yes
notify: reload #當nginx.conf發生改變時,通知給相應的handlers
tags: reloadnginx #打標籤
- name: Start nginx
service:
name: nginx
state: restarted
tags: startnginx #打標籤
- name: Create index.html
shell: echo "hello playbook_nginx_2" > /usr/share/nginx/html/index.html
handlers: #注意,前面沒有-,是兩個空格
- name: reload
service:
name: nginx
state: restarted
nginx2.conf
[root@server conf]# cat nginx2.conf
events {
worker_connections 1024;
}
http {
server {
listen 8080;
server_name 192.168.112.30:8080;
location / {
index index.html;
}
}
}
7.2、驗證nginx程序資訊
#驗證埠和響應內容
ansible node2 -m shell -a "ss -tunlp | grep nginx ; curl -s 192.168.112.30:8080"
7.3、測試標籤
#先關閉node3上的nginx服務以便測試
ansible node3 -m shell -a "systemctl stop nginx"
#再執行劇本並引用標籤startnginx
ansible-playbook nginx2.yml -t startnginx
7.4、測試notify
7.4.1、notify的觸發條件是配置檔案被改變
#修改監聽的埠號
[root@server conf]# cat nginx2.conf
events {
worker_connections 1024;
}
http {
server {
listen 8848;
server_name 192.168.112.30:8080;
location / {
index index.html;
}
}
}
7.4.2、重新執行劇本
#語法檢查
ansible-playbook nginx2.yml --syntax-check
#再執行劇本並引用標籤reloadnginx
ansible-playbook nginx2.yml -t reloadnginx
7.4.3、重新檢視埠號
ansible node2 -m shell -a "ss -tnulp | grep nginx"
埠號變為8848
8、變數(variables)
在Ansible劇本中,
vars
是用來定義變數的一個關鍵字,它允許你為任務、play或整個劇本設定變數值。這些變數可以在後續的任務中被引用,以提高劇本的靈活性和重用性。
8.1、定義變數的方式
1. Facts(Facts變數)
-
描述:Facts是Ansible自動收集的目標主機資訊,如系統型別、網路配置等。它們不是直接定義的變數,而是透過執行
setup
模組獲取的。儘管不能直接定義Facts,但它們可以在劇本中像其他變數一樣使用。 -
使用方式
- name: Display hostname using a fact debug: msg: "The hostname is {{ ansible_hostname }}"
-
檢視所有可以使用的變數:
ansible node1 -m setup > variables
2. 使用者自定義變數
-
直接在Playbook中定義
-
可以在play或tasks級別定義變數。
- hosts: web_test vars: my_var: "Hello, World!" tasks: - name: Use playbook-defined variable debug: msg: "{{ my_var }}"
-
-
透過命令列引數(
-e
/--extra-vars
)傳入-
在執行Ansible命令時動態新增變數。
ansible-playbook my_playbook.yml -e "my_var=ValueFromCommandLine"
-
3. 透過Roles傳遞變數
-
簡介:Roles是Ansible組織和複用任務的一種方式。變數可以透過角色的
defaults
,vars
,environment
目錄下的檔案來定義,或者在角色的tasks/main.yml
等檔案中直接定義。-
例子:
-
在
roles/my_role/defaults/main.yml
中定義:my_role_variable: default_value
-
然後在使用該角色的playbook中,該變數自動可用,也可被更高優先順序的變數覆蓋。
-
-
4. Host Inventory(主機清單)中定義變數
-
向不同主機傳遞不同變數
[webservers] host1.example.com my_var=value1 host2.example.com my_var=value2
-
向組中的所有主機傳遞相同變數
[webservers:vars] group_variable=value_for_all_hosts_in_group
8.2、優先順序
- 透過命令列指定變數優先順序最高
- /etc/ansible/hosts定義變數(針對單個主機定義,針對主機組進行定義)
- playbook中定義的變數
8.3、案例:使用變數安裝keepalived
1、編寫劇本
#先複製一份
[root@server bin]# cp nginx2.yml keepalived.yml
#再透過vim的替換將nginx替換為變數並最佳化一下src地址
[root@server bin]# cat keepalived.yml
---
- name: Update web servers
hosts: node2
remote_user: root
tasks:
- name: Install epel
yum:
name: epel-release.noarch
state: latest
- name: Install {{ rpmname }}
yum:
name: "{{ rpmname }}"
state: present
- name: Copy {{ rpmname }} configure file
copy:
src: /root/ansible/conf/{{ rpmname }}.conf
dest: /etc/{{ rpmname }}/{{ rpmname }}.conf
backup: yes
notify: reload
tags: reload{{ rpmname }}
- name: Start {{ rpmname }}
service:
name: "{{ rpmname }}"
state: restarted
tags: start{{ rpmname }}
handlers:
- name: reload
service:
name: "{{ rpmname }}"
state: restarted
全域性替換並新增確認動作 |
---|
輸入y確認替換 |
替換好的劇本 |
2、複製配置檔案
我們想要在被監管的機器上安裝什麼服務的話,就直接在我們的server端上把該服務的配置檔案複製到我們定義劇本的
src
目錄下。這樣我們的劇本才能正常執行。
cp /etc/keepalived/keepalived.conf /root/ansible/conf/keepalived.conf
3、執行劇本,變數由命令列傳入
#語法檢查
ansible-playbook keepalived.yml --syntax-check
#執行劇本-e 接變數
ansible-playbook keepalived.yml -e rpmname=keepalived
4、或者直接再劇本里定義變數
我們可以直接在劇本中把變數定義好,這樣就不需要在透過命令列傳入了。
以後想要安裝不同的服務,直接在劇本里把變數修改一下即可。
[root@server bin]# vim keepalived.yml
---
- name: Update web servers
hosts: node2
remote_user: root
vars:
- rpmname: keepalived
tasks:
- name: Install epel
yum:
name: epel-release.noarch
state: latest
- name: Install {{ rpmname }}
yum:
name: "{{ rpmname }}"
state: present
- name: Copy {{ rpmname }} configure file
copy:
src: /root/ansible/conf/{{ rpmname }}.conf
dest: /etc/{{ rpmname }}/{{ rpmname }}.conf
backup: yes
notify: reload
tags: reload{{ rpmname }}
- name: Start {{ rpmname }}
service:
name: "{{ rpmname }}"
state: restarted
tags: start{{ rpmname }}
handlers:
- name: reload
service:
name: "{{ rpmname }}"
state: restarted
5、執行定義過變數的劇本
#語法檢查
ansible-playbook keepalived.yml --syntax-check
#執行劇本
ansible-playbook keepalived.yml
9、模板(templates)
9.1、簡介
Templates主要用於自動生成和管理伺服器上的配置檔案,如nginx的配置、資料庫配置等。這有助於實現基礎設施的配置標準化和自動化。
- 文字檔案,內部巢狀有模板語言的指令碼
- jinja2是由python編寫的,在使用模板檔案時jinja2是很好的解決方案
- 功能:將模板檔案中的變數轉換成對應的本地主機的確定值\
9.2、基本資料型別和運算子
- 字串:在Jinja2模板中,無論是單引號還是雙引號,都可以用來定義字串。例如,
{{ "Hello, World!" }}
或{{ 'Hello, World!' }}
。 - 數字:Jinja2直接支援整數和浮點數的使用,無需特別的標記,如
{{ 42 }}
或{{ 3.14 }}
。 - 列表(List) 和 元組(Tuple):雖然Jinja2原生支援列表(使用方括號
[]
),但元組的直接表示不如Python中常見,因為模板更傾向於動態輸出而不是靜態結構。列表示例:{% for item in [1, 2, 3] %}...{% endfor %}
。 - 字典(Dictionary):與Python類似,使用花括號
{}
定義,鍵值對之間用冒號:
分隔。例如,{{ {"key": "value", "another_key": 42} }}
。 - 布林型(Booleans):在Jinja2中,可以直接使用
true
和false
(全部小寫),用於條件判斷。 - 算術運算:Jinja2支援所有基本的算術運算子,包括
+
,-
,*
,/
,//
,%
,**
。例如,{{ 5 + 3 }}
或{{ 10 // 2 }}
。 - 比較操作:與Python相同,包括
==
,!=
,>
,>=
,<
,<=
。用於條件判斷,如{% if variable > 10 %}...{% endif %}
。 - 邏輯運算:
and
,or
,not
用於邏輯條件組合。例如,{% if condition1 and condition2 %}...{% endif %}
或{% if not condition %}...{% endif %}
。
模板都是透過引用變數來引用的
9.3、案例:生成hosts解析檔案
使用模板替遠端主機生成hosts解析檔案(先把原來的hosts解析都去掉,在ansible配置檔案裡面替換為ip)
1、修改Ansible主機清單
[root@server1 ~]# egrep -v "^$|^#" /etc/ansible/hosts
[all-servers]
server1
server2
server3
server4
[all_ip]
192.168.112.10
192.168.112.20
192.168.112.30
192.168.112.40
2、修改主機名
hostnamectl set-hostname server1
hostnamectl set-hostname server2
hostnamectl set-hostname server3
hostnamectl set-hostname server4
3、準備模板檔案
[root@server1 ~]# vim hosts.j2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups.all_ip %}
{{hostvars[host].ansible_ens33.ipv4.address}} {{hostvars[host].ansible_hostname}}
{% endfor %}
4、編寫劇本
[root@server1 ~]# vim hosts.yml
---
- name: Config hosts file
hosts: all_ip
remote_user: root
tasks:
- name: copy hosts.j2 to group servers
template:
src: hosts.j2
dest: /etc/hosts
5、執行劇本
ansible-playbook hosts.yml --syntax-check
ansible-playbook hosts.yml
6、驗證
ansible all-servers -m shell -a "tail -4 /etc/hosts"
10、條件判斷
when語句:在task中使用,jinja2的語法格式。
10.1、舉例
tasks:
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
11、迴圈迭代
迴圈:迭代,需要重複執行的任務;
對迭代項的引用,固定變數名為"item",而後,要在task中使用with_items給定要迭代的元素列表;
11.1舉例
#基於字串列表
tasks:
‐ name: create rsyncd file
copy: src={{ item }} dest=/tmp/{{ item }}
with_items:
‐ a
‐ b
‐ c
‐ d
*with_itmes 巢狀子變數*
#基於字典列表
‐ hosts: eagleslab
remote_user: root
tasks:
‐ name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
‐ { name: 'testuser1' , groups: 'wheel'}
‐ { name: 'testuser2' , groups: 'root' }
11.2、案例:迴圈建立使用者
1、迴圈建立以下使用者資訊
zhangsan | xsb | /home/xsb/zhangsan | /bin/bash | 銷售 |
---|---|---|---|---|
lisi | xsb | /home/xsb/lisi | /bin/bash | 銷售 |
wangwu | jsb | /home/jsb/wangwu | /bin/sh | java工程師 |
maliu | jsb | /home/jsb/maliu | /bin/sh | linux工程師 |
zhaoqi | cwb | /home/cwb/zhaoqi | /bin/sh | 會計 |
2、迴圈建立出以上使用者並指定使用者資訊
[root@server1 ~]# vim user_manage.yml
---
- name: Manage user
hosts: all-servers
remote_user: root
tasks:
- name: ensure group xsb/jsb/cwb exists
group:
name={{ item.group }}
with_items:
- { group: 'xsb' }
- { group: 'cwb' }
- { group: 'jsb' }
- name: create users zhangsan/lisi/wangwu/maliu/zhaoqi
user:
name={{ item.name }}
group={{ item.group }}
shell={{ item.shell }}
comment={{ item.comment }}
home={{ item.home }}
with_items:
- { name: 'zhangsan', group: 'xsb',home: '/home/xsb/zhangsan',shell: '/bin/bash',comment: '銷售'}
- { name: 'lisi', group: 'xsb',home: '/home/xsb/zhangsan',shell: '/bin/bash',comment: '銷售'}
- { name: 'wangwu', group: 'jsb',home: '/home/jsb/wangwu',shell: '/bin/sh',comment: 'java工程師'}
- { name: 'maliu', group: 'jsb',home: '/home/jsb/maliu',shell: '/bin/sh',comment: 'linux工程師'}
- { name: 'zhaoqi', group: 'cwb',home: '/home/cwb/zhaoqi',shell: '/bin/sh',comment: '會計'}
3、執行劇本
#語法檢查
ansible-playbook user_manage.yml --syntax-check
#執行劇本
ansible-playbook user_manage.yml
4、驗證
ansible all-servers -m shell -a "id zhangsan ; id lisi ; id wangwu ; id maliu ; id zhaoqi"
12、字典
ansible playbook 還支援字典這種資料型別
12.1、舉例
- name: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
- name: add some groups
group: name={{ item }} state=present
with_items:
- group11
- group12
- group13
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user11', group: 'group11' }
- { name: 'user12', group: 'group12' }
- { name: 'user13', group: 'group13' }
13、角色(role)
13.1、簡介
Ansible的角色(Roles)是用於組織和複用配置任務的一種方式,它提供了一種結構化的方法來編寫和管理Playbooks,使得大型專案和重複使用的配置任務變得更加易於管理和維護。
角色設計的初衷是為了促進Playbooks的層次化和模組化,使得不同功能元件能夠清晰分離。
13.2、角色的目錄結構
角色集合:roles/
- mysql/
- httpd/
- nginx/
- files/:儲存由copy或script等模組呼叫的檔案;
- tasks/:此目錄中至少應該有一個名為main.yml的檔案,用於定義各task;其它的檔案需要由main.yml進行“包含”呼叫;、
- handlers/:此目錄中至少應該有一個名為main.yml的檔案,用於定義各handler;其它的檔案需要由main.yml進行“包含”呼叫;
- vars/:此目錄中至少應該有一個名為main.yml的檔案,用於定義各variable;其它的檔案需要由main.yml進行“包含”呼叫;
- templates/:儲存由template模組呼叫的模板文字;
- meta/:此目錄中至少應該有一個名為main.yml的檔案,定義當前角色的特殊設定及其依賴關係;其它的檔案需要由main.yml進行“包含”呼叫;
- default/:此目錄中至少應該有一個名為main.yml的檔案,用於設定預設變數;
14、案例:使用角色安裝nginx
14.1、建立對應的目錄結構
[root@server1 ~]# cd /etc/ansible/roles/
[root@server1 roles]# ls
[root@server1 roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
14.2、定義配置檔案
需要修改的配置檔案為
/tasks/main.yml
[root@server1 roles]# cat /etc/ansible/roles/nginx/tasks/main.yml
---
- name: cp
copy: src=nginx-1.10.2-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm
- name: install
yum: name=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm state=present
- name: conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: nginxconf
notify: new conf to reload
- name: start service
service: name=nginx state=started enabled=true
14.3、放置檔案到指定目錄
rpm包
#rpm包放在files目錄下
cp /tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm /etc/ansible/roles/nginx/files/
#模板放在templates目錄下
cp /tmp/nginx.conf.j2 /etc/ansible/roles/nginx/templates/
#檢視目錄結構
[root@server1 nginx]# tree
14.4、修改變數檔案
[root@server1 nginx]# cat /etc/ansible/roles/nginx/vars/main.yml
nginxport: 6666
14.5、定義handlers檔案
[root@server1 nginx]# cat /etc/ansible/roles/nginx/handlers/main.yml
---
- name: new conf to reload
service: name=nginx state=restarted
14.6定義劇本檔案
[root@server1 ansible]# cat /etc/ansible/roles.yml
---
- hosts: all-servers
remote_user: root
roles:
- nginx
14.7、剩餘的配置檔案
- nginx.conf.j2
events {
worker_connections 1024;
}
http {
server {
listen {{ nginxport }};
}
}
14.8、啟動服務
#語法檢查
ansible-playbook roles.yml --syntax-check
#執行劇本
ansible-playbook roles.yml
14.9、驗證埠號
ansible all-servers -m shell -a "ss -tunlp | grep nginx"
15、案例:使用角色安裝httpd
15.1、建立對應的目錄結構
[root@server1 ~]# cd /etc/ansible/roles/
[root@server1 roles]# ls
[root@server1 roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
#建立一個名為apache的新角色
[root@server1 roles]# ansible-galaxy init apache
- Role apache was created successfully
15.2、編寫site.yaml檔案
[root@server1 roles]# cat /etc/ansible/roles/site.yml
---
- hosts: all-servers
remote_user: root
roles:
- apache
15.3、編寫tasks裡的main.yml檔案
[root@server1 roles]# cat /etc/ansible/roles/apache/tasks/main.yml
---
- name: Install httpd
yum:
name: httpd
state: present
- name: Start httpd
service:
name: httpd
state: restarted
- name: Write index file
shell: echo "http" > /var/www/html/index.html
15.4、執行劇本
#語法驗證
ansible-playbook site.yml --syntax-check
#執行劇本
ansible-playbook site.yml
15.5、驗證
ansible all-servers -m shell -a "curl -s server1 ; curl -s server2 ; curl -s server3 ; curl -s server4"
16、案例:使用角色安裝java+nginx+halo
16.1、準備角色
[root@server1 roles]# ansible-galaxy init halo
- Role halo was created successfully
[root@server1 roles]# ansible-galaxy init java
- Role java was created successfully
[root@server1 roles]# ansible-galaxy init nginx
- Role nginx was created successfully
16.2、編寫site.yml
- pre_tasks為執行play之前執行的任務
- post_tasks為執行play之後執行的任務
[root@server1 roles]# cat site.yml
---
- hosts: node1
remote_user: root
strategy: free
pre_tasks:
- name: config nginx repo for centos 7
yum_repository:
name: nginx
description: nginx
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck: no
when: ansible_distribution_major_version == "7"
- name: Disable SELinux
selinux: state=disabled
roles:
- nginx
post_tasks:
- shell: echo 'Deplay halo finished.'
register: ret
- debug: var=ret.stdout
16.3、編寫nginx角色
nginx/tasks/main.yml
[root@server1 roles]# cat nginx/tasks/main.yml
---
# tasks file for nginx
- name: make sure nginx state is installed
yum: name=nginx state=installed
- name: copy halo to nginx config file
template: src=halo.conf dest="/etc/nginx/conf.d/halo.conf"
- name: make sure nginx service is running
service: name=nginx state=started
- name: make sure port is open
wait_for: port="{{ nginx_port }}"
meta/main.yml為role的依賴關係,要先執行這裡面的內容才會執行自己的nginx這個role。
[root@server1 roles]# cat nginx/meta/main.yml #要修改的是dependencies部分
dependencies:
- role: java
- role: halo
nginx/templates/halo.conf
[root@server1 roles]# cat nginx/templates/halo.conf
upstream halo {
server 127.0.0.1:8090;
}
server {
listen 80;
listen [::]:80;
server_name {{ halo_domain }};
client_max_body_size 1024m;
location / {
proxy_pass http://halo;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
16.4、編寫java角色
為了安裝java
[root@server1 roles]# cat java/tasks/main.yml
---
# tasks file for java
- name: install java
yum: name=java-11-openjdk state=installed
16.5、編寫halo角色
[root@server1 roles]# cat halo/tasks/main.yml
---
# tasks file for halo
- name: get halo
get_url: url=https://dl.halo.run/release/halo-1.4.11.jar dest={{ halopath }}
- name: add halo service file
template: src=halo.service dest=/etc/systemd/system/halo.service
- name: touch ~/.halo directory
file: path=~/.halo state=directory
- name: copy halo config file
template: src=application.yaml dest="~/.halo/application.yaml"
- name: restart halo
systemd:
daemon_reload: yes
name: halo
state: started
enabled: yes
- name: wait to start halo
wait_for: port={{ halo_port }}
修改變數檔案halo/vars/main.yml
[root@server1 roles]# cat halo/vars/main.yml
---
# vars file for halo
memory: 512m
halo_port: 8090
halopath: /root/halo.jar
halo_domain: 192.168.112.10
nginx_port: 80
下載servers檔案並編輯
[root@server1 roles]# wget https://dl.halo.run/config/halo.service -O halo/templates/halo.service
[root@server1 roles]# cat halo/templates/halo.service
[Unit]
Description=Halo Service
Documentation=https://docs.halo.run
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root #修改
ExecStart=/usr/bin/java -server -Xms256m -Xmx256m -jar /root/halo.jar #修改
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=always
StandOutput=syslog
StandError=inherit
[Install]
WantedBy=multi-user.target
[root@server1 roles]# wget https://dl.halo.run/config/application-template.yaml -O halo/templates/application.yaml
16.6、執行劇本
#語法檢查
ansible-playbook site.yml --syntax-check
#執行劇本
ansible-playbook site.yml
16.7、驗證
透過IP+埠訪問
192.168.112.10:8090
至此ansible的學習就告一段落啦