記錄:部署Ansible,Ansible ad-hoc應用(1
1 案例1:部署Ansible
1.1 問題
本案例要求先快速搭建好一個Ansible平臺,並測試環境,要求如下:
- 建立實驗主機(控制端和被控制端)
- 配置SSH實驗環境
- 安裝Ansible自動化軟體
- 修改Ansible配置
1.2 方案
準備如表-1所示的實驗環境,作業系統為RHEL8,配置主機名稱、IP地址、YUM源。
ansible原理:
控制端主機自帶很多模組(模組就是指令碼);
ansible通過ssh遠端被管理主機,將控制端的模組(指令碼)或命令傳輸到被管理主機;
在被管理端主機執行模組(指令碼)或命令,執行不同的模組或命令可以實現不同的功能;
最後ansible退出ssh遠端。
絕大多數模組(指令碼)都需要引數才能執行成功!!!類似於shell指令碼的位置變數!
拓撲結構如圖-1所示。
提醒:全天的實驗不需要死記硬背每個模組的每個引數,所有引數都可以檢視幫助!
1.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:準備基礎環境
控制節點要求:
- 域名解析(為了方便後期操作,可以不做)
- 配置SSH金鑰(ansible是基於ssh實現遠端控制)
- 安裝Ansible軟體
1)Control控制節點
修改/etc/hosts,在檔案中手動新增如下內容,修改該檔案的目的是做域名解析。
[root@control ~]# vim /etc/hosts #修改檔案,手動新增如下內容(不要刪除檔案原來的內容)
192.168.4.253 control
192.168.4.11 node1
192.168.4.12 node2
192.168.4.13 node3
192.168.4.14 node4
192.168.4.15 node5
如何驗證?
[root@control ~]# ping node1 #可以使用ping命令依次ping所有域名
配置SSH金鑰實現免密碼登入(非常重要)
Ansible是基於SSH遠端的原理實現遠端控制,如果控制端主機無法免密登入被管理端主機,後續的所有試驗都會失敗!!
[root@control ~]# ssh-keygen -f /root/.ssh/id_rsa -N '' #生成ssh金鑰
#-f指定金鑰檔案存放在哪個目錄,檔案叫什麼名字,-N ''設定金鑰的密碼為空
[root@control ~]# for i in node1 node2 node3 node4 node5
do
ssh-copy-id $i
done
#拷貝金鑰到遠端主機
#提示:拷貝金鑰到遠端主機時需要輸入對方電腦的賬戶密碼才可以!!
#拷貝金鑰到node1就需要輸入node1對應賬戶的密碼,拷貝金鑰到node2就需要輸入node2對應的密碼
如何驗證?
警告:如果有任何一臺主機遠端還需要密碼,就不要往下繼續操作,後面實驗都會失敗!!!
[root@control ~]# ssh node1 #使用ssh命令依次遠端所有主機都可以免密碼登入
2)部署Ansible軟體(僅Control主機操作,軟體包在ansible_soft目錄)。
[root@control ~]# tar -xf ansible_soft.tar.gz [root@control ~]# cd ansible_soft [root@control ansible_soft]# dnf -y install *
被控制節點要求:
- Ansible預設通過SSH協議管理機器
- 被管理主機要開啟SSH服務,並允許控制主機登入
- 被管理主機需要安裝有Python
步驟二:修改配置檔案
主配置檔案說明:
主配置檔案ansible.cfg(主配置檔案的內容可以參考/etc/ansible/ansible.cfg)
ansible配置檔案查詢順序
首先檢測ANSIBLE_CONFIG變數定義的配置檔案(預設沒有這個變數)
其次檢查當前目錄下的./ansible.cfg檔案
再次檢查當前使用者家目錄下~/ansible.cfg檔案
最後檢查/etc/ansible/ansible.cfg檔案
1) 修改主配置檔案。
[root@control ~]# mkdir ~/ansible
[root@control ~]# vim ~/ansible/ansible.cfg
[defaults]
inventory = ~/ansible/inventory
#主機清單配置檔案(inventory可以是任意檔名),英語詞彙:inventory(清單、財產清單)
#forks = 5 #ssh併發數量
#ask_pass = True #使用金鑰還是密碼遠端,True代表使用密碼
#host_key_checking = False #是否校驗金鑰(第一次ssh時是否提示yes/no)
2) 修改主機清單檔案(清單檔名必須與主配置檔案inventory定義的一致)。
[root@control ~]# vim ~/ansible/inventory
[test] #定義主機組(組名稱任意)
node1 #定義組中的具體主機,組中包括一臺主機node1
[proxy] #定義主機組(組名稱任意),英語詞彙:proxy(代理人,委託人)
node2 #proxy組中包括一臺主機node2
[webserver]
node[3:4] #這裡的node[3:4]等同於node3和node4
[database]
node5
[cluster:children] #巢狀組(children為關鍵字),不需要也可以不建立巢狀組
webserver #巢狀組可以在組中包含其他組
database
2 案例2:Ansible ad-hoc應用一
2.1 問題
沿用練習一,練習Ansible ad-hoc具體應用,要求如下:
- 測試主機列表中的主機是否可以ping通
- 檢視被管理主機的伺服器資訊(如時間、版本、記憶體等)
- 學習ansible-doc命令的用法
- 測試command與shell模組的區別
- 使用script模組在遠端主機執行指令碼(裝軟體包、啟服務)
2.2 方案
Ansible ad-hoc是一種通過命令列批量管理的方式,命令基本格式如下:
格式:ansible 主機集合 -m 模組名 -a "引數"
2.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:測試環境
1)檢視主機列表
[root@control ~]# cd ~/ansible #非常重要 [root@control ansible]# ansible all --list-hosts #檢視所有主機列表 # --list-hosts是ansible這個命令的固定選項,如同ls -a一樣(-a是ls命令的固定選項) #英語詞彙:list(列表,清單)、host(主機、主辦、主人)
2) 測試遠端主機是否能ping通。
當需要遠端多個主機或者多個組時,中間使用逗號分隔!!!
[root@control ansible]# ansible node1 -m ping #呼叫ping模組 [root@control ansible]# ansible node1,webserver -m ping
常見報錯(有問題可以參考,沒問題可以忽略):
node1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
問題分析:
英語詞彙:Failed(失敗),connect(連線),to(到),host(主機),via(通過)
permission(許可權),denied(被拒絕)
Failed to connect to host via ssh(通過ssh遠端連線到主機失敗)
Permission denied(因為無法連線,所以報錯說許可權被拒絕)
解決辦法:手動ssh其他主機(如node1),看看是否可以實現免密碼登入。
Ansible的原理是基於ssh遠端管理,如果無法實現免密碼登入,後面的實驗無法成功!
如何實現免密碼登入,可以參考案例上面的命令,或者第一階段知識。
提示:該模組雖然叫ping,但是它不會發送任何ICMP協議的ping資料包,控制端主機僅僅是ssh遠端被管理端主機,檢查其是否有python環境,能順利遠端並且有Python環境就會返回正確的提示資訊,否則報錯。拓撲如圖-2所示。
3)快速入門。
模組就是指令碼(多數為Python指令碼),多數指令碼都支援引數,預設模組為command。
[root@control ansible]# ansible node1 -m command -a "uptime" #檢視CPU負載 [root@control ansible]# ansible node1 -m command -a "uname -r" #檢視核心版本 [root@control ansible]# ansible node1 -a "ip a s" #檢視網絡卡資訊 [root@control ansible]# ansible all -a "date" #檢視時間
拓撲如圖-3所示。
通過ansible-doc獲取幫助。
[root@control ansible]# ansible-doc -l #列出所有模組 [root@control ansible]# ansible-doc -l | grep yum #在所有模組中過濾關鍵詞 [root@control ansible]# ansible-doc yum #檢視模組幫助
4)Shell模組。
command和shell模組的區別,command不支援bash的特性(bash有哪些特性可以參考Shell課程第一天的PPT),如管道和重定向等功能,但是shell模組可以支援。
不可以使用shell模組執行互動命令,如vim、top等。
[root@control ansible]# ansible test -m command -a "ps | wc -l" #報錯 [root@control ansible]# ansible test -m command -a "ls &" #報錯 [root@control ansible]# ansible test -m shell -a "ps aux | wc -l" #程序數量 [root@control ansible]# ansible test -m shell -a "who" #登陸資訊 [root@control ansible]# ansible test -m shell -a "touch /tmp/txt.txt" #使用shell模組建立檔案會有Warning警告提示,正常!!!
5)script模組
script模組會把-a後面的指令碼拷貝到被管理端主機,然後執行這個指令碼。
[root@control ansible]# vim ~/ansible/test.sh
#!/bin/bash
dnf -y install httpd
systemctl start httpd
[root@control ansible]# ansible test -m script -a "./test.sh"
#test是主機組的名稱,-m呼叫script模組,-a後面的./test.sh是上面建立指令碼的相對路徑和檔名
#./是當前目錄的意思,在當前目錄下有個指令碼叫test.sh
拓撲如圖-4所示。
如何驗證?
因為ansible遠端的是node1,所以開啟node1這臺電腦,檢視下是否安裝了httpd軟體、是否啟動了服務。
[root@node1 ~]# rpm -q httpd [root@node1 ~]# systemctl status httpd
3 案例3:Ansible ad-hoc應用二
3.1 問題
沿用練習二,繼續練習Ansible ad-hoc應用案例,具體要求如下:
- 遠端目標主機新建檔案和目錄、修改檔案或目錄的許可權
- 在遠端目標主機建立連結檔案
- 刪除遠端目標主機上的檔案或目錄
- 將控制端本地的檔案拷貝到被管理端
- 從被管理端下載檔案到本地
- 修改遠端目標主機上的檔案內容
3.2 方案
很多ansible模組都具有冪等性的特徵。
冪等性:任意次執行所產生的影響均與一次執行的影響相同。
步驟一:file模組
file模組可以建立檔案、目錄、連結;修改許可權與屬性等(ansible-doc file)
[root@control ansible]# ansible test -m file -a "path=/tmp/file.txt state=touch" #遠端test組中所有主機,新建檔案,path後面指定要建立的檔案或目錄的名稱 #state=touch是建立檔案,state=directory是建立目錄 ## 驗證: 到node1主機,使用ls /tmp/file.txt看看檔案是否被建立成功 ##
拓撲如圖-5所示。
常見報錯(有問題可以參考,沒問題可以忽略):
node1 | FAILED! => {
… …
"changed": false,
"msg": "value of state must be one of: absent, directory, file, hard, link, touch, got: touc"
}
英語詞彙:value(值),must(必須),be(是),of(…的),one(一個)
value of state must be one of:【state的值必須是後面給出的其中一個值】
解決辦法:檢查state的值是否有字母錯誤,上面報錯例子中輸入的是touc,不是touch
常見錯誤(有問題可以參考,沒問題可以忽略):
node1 | FAILED! => {
… …
"msg": "Unsupported parameters for (file) module: nmae Supported parameters include: _diff_peek, _original_basename, access_time,
access_time_format, attributes, backup, content, delimiter, directory_mode,
follow, force, group, mode, modification_time, modification_time_format, owner,
path, recurse, regexp, remote_src, selevel, serole, setype, seuser, src, state,
unsafe_writes"
}
英語詞彙:unsupported(不支援的),parameters(引數),supported(支援的)include(包括)
問題分析:file模組不支援nmae這個引數,它支援的引數包括哪些,後面有提示.
解決辦法:檢查模組的引數是否有字母錯誤,上面錯誤案例將name錯寫為nmae。
更多file模組的案例:
[root@control ansible]# ansible test -m file \ -a "path=/tmp/mydir state=directory" #遠端test組中所有主機,建立目錄,path後面指定要建立的檔案或目錄的名稱 ## 驗證:到node1主機,使用ls /tmp/看看tmp目錄下是否有mydir子目錄 [root@control ansible]# ansible test -m file \ -a "path=/tmp/file.txt owner=sshd group=adm mode=0777" #修改檔案或目錄許可權,path後面指定要修改的檔名或目錄名稱,owner後面指定使用者,group後面指定組,mode後面指定要修改的許可權(0777中第一個0代表的是無特殊許可權,如SUID、SGID等) ## 驗證:到node1主機,使用ls -l /tmp/file.txt檢視檔案的詳細資訊是否正確 [root@control ansible]# ansible test -m file -a "path=/tmp/mydir state=absent" #state=absent代表刪除(刪除目錄) [root@control ansible]# ansible test -m file -a "path=/tmp/file.txt state=absent" # state=absent代表刪除(刪除檔案) [root@control ansible]# ansible test -m file \ -a "src=/etc/hosts path=/tmp/host.txt state=link" #給/etc/hosts檔案建立一個連結檔案/tmp/host.txt(src指定原始檔,path是軟連結檔名) #相當於執行命令 ln -s /etc/hosts /tmp/host.txt ## 驗證:到node1主機使用ls -l /tmp/hosts檢視檔案是否為軟連結
步驟二:copy模組
copy模組可以將檔案拷貝到遠端主機 (ansible-doc copy)。
[root@control ansible]# echo AAA > ~/a3.txt #新建測試檔案 [root@control ansible]# ansible test -m copy -a "src=~/a3.txt dest=/root/" #把管理端本機的a3.txt檔案,拷貝到test組中所有主機的/root/目錄 #src代表原始檔,dest代表目標檔案 ## 驗證:到node1主機使用ls /root/a3.txt檢視是否有該檔案
拓撲如圖-6所示
步驟三:fetch模組
fetch模組與copy類似,但是作用相反,可以將其他主機的檔案拷貝到本地(ansible-doc fetch)。
[root@control ansible]# ansible test -m fetch -a "src=/etc/hostname dest=~/" #將遠端test組中所有主機的hostname檔案下載到本地家目錄 #src代表原始檔,dest代表目標檔案 [root@control ansible]# ls ~/ #使用ls檢視下是否下載成功 #不能下載目錄,如果需要下載目錄,可以先打包後再下載
拓撲如圖-7所示。
步驟四:lineinfile|replace模組
在修改單個檔案的單行內容時可以使用lineinfile模組(ansible-doc lineinfile)。
[root@control ansible]# ansible test -m lineinfile \ -a "path=/etc/issue line='hello world'" #在/etc/issue檔案中新增一行內容hello world,預設新增到最後,line後面跟的是需要新增的檔案內容 ## 驗證:到node1主機執行命令cat /etc/issue檢視檔案內容是否正確 [root@control ansible]# ansible test -m lineinfile \ -a "path=/etc/issue line='hello world'" #基於冪等原則,重複執行,不會建立多行內容 [root@control ansible]# ansible test -m lineinfile \ -a "path=/etc/issue line='insert' insertafter='Kernel'" #將line後面的內容插入到/etc/issue檔案中Kernel行的後面 #英語詞彙:insert(插入),after(在…後面) ## 驗證:到node1主機執行命令cat /etc/issue檢視檔案內容是否正確
lineinfile會替換一整行,replace可以替換關鍵詞(ansible-doc replace)。
[root@control ansible]# ansible test -m replace \ -a "path=/etc/issue.net regexp=Kernel replace=Ocean" #將node1主機中/etc/issue.net檔案全文所有的Kernel替換為Ocean #regexp後面是需要替換的舊內容;replace後面是需要替換的新內容 ## 驗證:到node1主機執行命令cat /etc/issue.net檢視檔案內容是否正確
---------------------------------------------------------------------------
4 案例4:Ansible ad-hoc應用三
4.1 問題
沿用練習三,繼續練習Ansible ad-hoc應用案例,具體要求如下:
- 遠端目標主機建立、刪除系統賬戶;設定系統賬戶屬性、修改賬戶密碼
- 為目標主機建立、刪除yum源配置檔案;遠端目標主機安裝、解除安裝軟體包
- 使用service模組管理遠端主機的服務
- 建立、刪除邏輯卷
步驟一:user模組
user模組可以實現Linux系統賬戶管理(ansible-doc user)。
[root@control ansible]# ansible test -m user -a "name=tuser1" #遠端test組中的所有主機並建立系統賬戶tuser1,預設state的值為present,代表建立使用者 ## 驗證:到node1主機執行命令id tuser1檢視是否有該使用者
拓撲如圖-8所示。
[root@control ansible]# ansible test -m user -a \ "name=tuser2 uid=1010 group=adm groups=daemon,root home=/home/tuser2" #建立賬戶並設定對應的賬戶屬性,uid指定使用者ID號,group指定使用者屬於哪個基本組 #groups指定使用者屬於哪些附加組,home指定使用者的家目錄 ## 驗證: 到node1主機執行命令id tuser2檢視是否有該使用者
拓撲如圖-9所示
[root@control ansible]# ansible test -m user \ -a "name=tuser1 password={{'abc'| password_hash('sha512')}}" #修改賬戶密碼,使用者名稱是tuser1,密碼是abc,密碼經過sha512加密 [root@control ansible]# ansible test -m user \ -a "name=tuser1 state=absent" #刪除賬戶tuser1,state=absent代表刪除賬戶的意思,name指定要刪除的使用者名稱是什麼 #賬戶的家目錄不會被刪除,相當於執行userdel tuser1 [root@control ansible]# ansible test -m user \ -a "name=tuser2 state=absent remove=true" #刪除tuser2賬戶同時刪除家目錄、郵箱,相當於執行userdel -r tuser2
步驟二:yum_repository模組
使用yum_repository可以建立或修改yum源配置檔案(ansible-doc yum_repository)。
[root@control ansible]# ansible test -m yum_repository \
-a "name=myyum description=hello baseurl=ftp://192.168.4.254/centos gpgcheck=no"
#新建一個yum源配置檔案/etc/yum.repos.d/myyum.repo
#yum原始檔名為myyum,該檔案的內容如下:
[myyum]
baseurl = ftp://192.168.4.254/centos
gpgcheck = 0
name = hello
## 驗證:到node1主機ls /etc/yum.repos.d/檢視該目錄下是否有新的yum檔案
[root@control ansible]# ansible test -m yum_repository \
-a "name=myyum description=test baseurl=ftp://192.168.4.254/centos gpgcheck=yes gpgkey=…"
#修改yum原始檔內容
[root@control ansible]# ansible test -m yum_repository -a "name=myyum state=absent"
#刪除yum原始檔myyum
步驟三:yum模組
使用yum模組可以安裝、解除安裝、升級軟體包(ansible-doc yum),
state: present(安裝)|absent(解除安裝)|latest(升級)。
[root@control ansible]# ansible test -m yum -a "name=unzip state=present" #安裝unzip軟體包,state預設為present,也可以不寫 ## 驗證:到node1主機執行命令rpm -q unzip檢視是否有該軟體 [root@control ansible]# ansible test -m yum -a "name=unzip state=latest" #升級unzip軟體包,軟體名稱可以是*,代表升級所有軟體包 [root@control ansible]# ansible test -m yum -a "name=unzip state=absent" #呼叫yum模組,解除安裝unzip軟體包,state=absent代表解除安裝軟體 ## 驗證:到node1主機執行命令rpm -q unzip檢視該軟體是否已經被解除安裝
步驟四:service模組(ansible-doc service)
service為服務管理模組(啟動、關閉、重啟服務等),
state:started|stopped|restarted,
enabled:yes設定開機啟動。
[root@control ansible]# ansible test -m yum -a "name=httpd" #呼叫yum模組,安裝httpd軟體包 ## 驗證:到node1主機執行命令rpm -q httpd檢視該軟體是否被安裝 [root@control ansible]# ansible test -m service -a "name=httpd state=started" #呼叫service模組,啟動httpd服務 ## 驗證:到node1主機執行命令systemctl status httpd檢視服務狀態 [root@control ansible]# ansible test -m service -a "name=httpd state=stopped" #呼叫service模組,關閉httpd服務 ## 驗證:到node1主機執行命令systemctl status httpd檢視服務狀態 [root@control ansible]# ansible test -m service -a "name=httpd state=restarted" #呼叫service模組,重啟httpd服務 [root@control ansible]# ansible test -m service -a "name=httpd enabled=yes" #呼叫service模組,設定httpd服務開機自啟
步驟五:邏輯卷相關模組(ansible-doc lvg、ansible-doc lvol)
提示:做實驗之前需要給對應的虛擬機器新增額外磁碟,並建立磁碟2個分割槽
提示:可以使用前面學習過的parted或fdisk命令給磁碟建立分割槽
提示:這裡的磁碟名稱僅供參考,不要照抄!!!
lvg模組:建立、刪除卷組(VG),修改卷組大小,
state:present(建立)|absent(刪除)。
[root@control ansible]# ansible test -m yum -a "name=lvm2" #安裝lvm2軟體包,安裝了lvm2軟體後,才有pvcreate、vgcreate、lvcreate等命令 [root@control ansible]# ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1" #建立名稱為myvg的卷組,該卷組由/dev/sdb1組成 #注意:這裡的磁碟名稱要根據實際情況填寫 ## 驗證:到node1主機執行命令pvs和vgs檢視是否有對應的PV和VG [root@control ansible]# ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1,/dev/sdb2" #修改卷組大小,往卷組中新增一個裝置/dev/sdb2
lvol模組:建立、刪除邏輯卷(LV),修改邏輯卷大小,
state:present(建立)|absent(刪除)。
[root@control ansible]# ansible test -m lvol -a "lv=mylv vg=myvg size=2G" #使用myvg這個卷組建立一個名稱為mylv的邏輯卷,大小為2G ## 驗證:到node1主機執行命令lvs檢視是否有對應的LV邏輯卷 [root@control ansible]# ansible test -m lvol -a "lv=mylv vg=myvg size=4G" #修改LV邏輯卷大小 [root@control ansible]# ansible test -m lvol -a "lv=mylv vg=myvg state=absent force=yes" #刪除邏輯卷,force=yes是強制刪除 [root@control ansible]# ansible test -m lvg -a "vg=myvg state=absent" #刪除卷組myvg
附加思維導圖,如圖-10所示:
附加思考題(假設在沒有建立ssh金鑰的情況下):
在沒有建立ssh金鑰的情況下,如果node1需要ssh遠端node2是否需要輸入密碼?
如果node1需要ssh遠端node2,應該輸入誰的使用者名稱和密碼?
node1使用自己系統的賬戶和密碼能否ssh遠端node2,node2可以被隨便登入還安全嗎?
路人甲能否使用自己家的鑰匙,去路人乙家(開路人乙家的門)?
node1執行命令ssh [email protected],這裡的root是誰的賬戶名?輸入誰的密碼?
如果使用真機windows的Xshell去ssh遠端node2虛擬機器,需要在windows也有一個root使用者嗎?
-----------------------------------------------------------------------------------------------------------------------------