1. Ansible Ad-Hoc 命令
Ad-Hoc 命令是什麼呢? 這其實是一個概念性的名詞,是相對於寫Ansible playbook 來說的,類似於在命令列敲shell命令和,寫shell scripts 兩者之間的關係,可以用於執行一些臨時命令。
如果我們敲入一些命令去比較快的完成一些事情,而不需要將這個命令儲存下來,這樣的命令就叫 Ad-Hoc 命令。
Ansible 提供兩種方式去完成任務 一是Ad-Hoc 命令,另一個就是寫ansible playbook。
前者解決簡單的任務,後者解決比較複雜的任務,比如做配置管理或部署。
1.1 命令格式
在快速入門中執行的 Ansible 命令,類似於批量執行命令。
在 Ansible 中統稱為 Ad-Hoc 命令。
格式如下:
ansible pattern [-i inventory] -m module -a argment
-
pattern
資產選擇器 -
-i
指定資產清單檔案的位置 -
-m
指定本次Ansible ad-hoc 要執行的模組,可以類比成shell中的命令 -
-a
模組的引數,可以類比成shell中的命令引數
1.2 模組型別
Ansible 模組分為三種型別:核心模組(core module)、附加模組(extra module)、使用者自定義模組(consume module)。
核心模組是由Ansible官方提供的
附加模組是由各社群提供的。如OPENSTACK社群、DOCKER社群等。
當核心模組和附加模組都無法滿足你的需求時,使用者可以自定義模組。
預設情況下,安裝ansible的時候核心模組和附加模組都已經安裝完成無需使用者干預。
1.3 聯機幫助
Ansible 的核心模組和附加模組,數量有1000+,這樣龐大的模組量,對任何一個接觸Ansible的人都不可能完成記住、掌握使用。因此能夠順利使用Ansible的幫助文件,對我們來說很重要,Ansible 的幫助文件,由它本身提供的命令 ansible-hoc 實現。
1.3.1 常用幫助引數
- 列舉出所有的核心模組和附加模組
# ansible-doc -l
- 查詢某個模組的使用方法
# ansible-doc mdulename
- 查詢某個模組的使用方法,比較簡介的資訊
# ansible-doc -s modulename
練習:
# ansible-doc yum
# ansible-doc -s yum
1.4 常用模組
為了便於演示和操作,現在把之前的測試主機ip192.168.10.144
和192.168.10.145
,儲存在當前目錄下新建的hosts
檔案中。
[root@ansible-01 ~]# cat hosts
[dbservers]
192.168.10.144
[webservers]
192.168.10.145
1.4.1 command & shell 模組
兩個模組都在遠端伺服器上執行命令。
但command模組是ad-hoc的預設模組,在執行ad-hoc時,若不指定模組的名子,則預設使用此模組。
[root@ansible-01 ~]# ansible all -i hosts -a "echo hello"
192.168.10.145 | CHANGED | rc=0 >>
hello
192.168.10.144 | CHANGED | rc=0 >>
hello
[root@ansible-01 ~]# ansible all -i hosts -m shell -a "echo hello"
192.168.10.145 | CHANGED | rc=0 >>
hello
192.168.10.144 | CHANGED | rc=0 >>
hello
兩個模組的差異:
-
shell 模組可以執行shell的內建命令和特徵(比如管道符)
-
command 模組無法執行shell 的內建命令和特徵
練習
# shell 模組
[root@ansible-01 ~]# ansible all -i hosts -m shell -a "echo 'hello' | grep -o 'e'"
192.168.10.145 | CHANGED | rc=0 >>
e
192.168.10.144 | CHANGED | rc=0 >>
e
# command 模組
[root@ansible-01 ~]# ansible all -i hosts -a "echo 'hello' | grep -o 'e'"
192.168.10.145 | CHANGED | rc=0 >>
hello | grep -o e
192.168.10.144 | CHANGED | rc=0 >>
hello | grep -o e
1.4.2 script 模組
將管理節點上的指令碼傳遞到被管理節點(遠端伺服器)上進行執行,理論上此模組的執行完全不需要被管理伺服器上有python
練習
管理節點上的一個指令碼
[root@ansible-01 ~]# cat /root/a.sh
touch /tmp/testfile
執行
[root@ansible-01 ~]# ansible webservers -i hosts -m script -a "/root/a.sh"
192.168.10.145 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.10.145 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.10.145 closed."
],
"stdout": "",
"stdout_lines": []
}
1.4.3 copy 模組
copy 模組只要用於管理節點和被管理節點之間的檔案拷貝。
常用引數:
-
src
指定拷貝檔案的源地址 -
dest
指定拷貝檔案的目標地址 -
backup
拷貝檔案前,若原目標檔案發生了變化,則對目標檔案進行備份 -
woner
指定新拷貝檔案的所有者 -
group
指定新拷貝檔案的所有組 -
mode
指定新拷貝檔案的許可權
練習
- copy 管理節點上的
epel.repo
到被管理節點上。
[root@ansible-01 ~]# cat epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://mirrors.aliyun.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=http://mirrors.aliyun.com/epel/7/$basearch/debug
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0
[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=http://mirrors.aliyun.com/epel/7/SRPMS
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0
# 執行
[root@ansible-01 ~]# ansible webservers -i hosts -m copy -a "src=./epel.repo dest=/tmp/epel.repo"
# 檢視
[root@ansible-01 ~]# ansible webservers -i hosts -m shell -a "ls -l /tmp/"
192.168.10.145 | CHANGED | rc=0 >>
total 4
-rw-r--r--. 1 root root 0 Oct 2 22:02 a.conf
drwx------. 2 root root 41 Oct 3 21:21 ansible_command_payload_5XcIxi
-rw-r--r--. 1 root root 665 Oct 3 21:20 epel.repo # 拷貝的檔案
-rw-r--r--. 1 root root 0 Oct 3 21:03 testfile
drwx------. 2 root root 6 Oct 2 21:36 vmware-root_708-2998936538
drwx------. 2 root root 6 Oct 3 20:12 vmware-root_716-2965513684
- copy前,會在被管理節點上備份
[root@ansible-01 ~]# ansible webservers -i hosts -m copy -a "src=./epel.repo dest=/tmp/epel.repo backup=yes"
- copy 檔案的同時對檔案進行使用者及使用者組操作
[root@ansible-01 ~]# ansible all -i hosts -m copy -a "src=./epel.repo dest=/tmp/epel.repo owner=nobody group=nobody"
- copy檔案的同時,對檔案進行許可權設定
[root@ansible-01 ~]# ansible all -i hosts -m copy -a "src=./epel.repo dest=/tmp/epel.repo mode=0755"
1.4.4 yum_repsitory
新增yum倉庫
常用引數:
-
name
倉庫名稱,就是倉庫中第一行中括號裡面的內容,必須是引數 -
description
倉庫描述資訊,新增時必須的引數 -
baseurl
yum 儲存庫“repodata”,目錄所在目錄的url,必須新增的引數 -
file
倉庫檔案儲存到被管理節點的檔名,不包含.repo
,預設是name的指 -
state
preset 確認新增倉庫檔案,absent確認刪除倉庫檔案 -
gpgcheck
是否檢查 GPG yes|no ,沒有預設值,使用/etc/yum.conf中的配置
練習
新增epel源
[root@ansible-01 ~]# ansible dbservers -i hosts -m yum_repository -a "name=epel baseurl='http://mirrors.aliyun.com/epel/7/$basearch' description='EPEL YUM repo'"
刪除epel源
[root@ansible-01 ~]# ansible dbservers -i hosts -m yum_repository -a "name=epel state=absent"
1.4.5 yum 模組
等同於Linux上的yum命令,對遠端伺服器上的RPM包進行管理
常用引數
-
name
要安裝的軟體包名,多個軟體包可以用英文逗號隔開 -
state
對當前指定的軟體進行安裝、移除操作(present、installed、latest absent removed)
支援的引數
-
present
確認已經安裝,但不升級 -
installed
確認已經安裝 -
latest
確保安裝,且升級為最新 -
absent
和removed
確認已經刪除
練習
- 安裝一個軟體包
[root@ansible-01 ~]# ansible webservers -i hosts -m yum -a "name=vim state=present"
[root@ansible-01 ~]# ansible webservers -i hosts -m yum -a "name=vim state=latest"
[root@ansible-01 ~]# ansible webservers -i hosts -m yum -a "name=vim state=installed"
- 移除一個軟體包
[root@ansible-01 ~]# ansible webservers -i hosts -m yum -a "name=vim state=absent"
[root@ansible-01 ~]# ansible webservers -i hosts -m yum -a "name=vim state=removed"
- 安裝一個軟體包組
[root@ansible-01 ~]# ansible all -i hosts -m yum -a "name='@Development tools' state=present"
1.4.6 systemd 模組
Centos6以前的版本是
service
模組
請使用ansible-doc service
命令自行檢視幫助
管理遠端節點上的systemd服務,就是由systemd管理的服務
常用引數
daemon_reload
重新載入systemd 掃描新的或者有變動的單元enabled
是否開機自啟動 yes|noname
必選項,服務名稱,比如httpd、vsftpd等state
對當前服務執行啟動、重啟、停止、重新載入等操作(started、stopped、restarted、reloaded)
練習
- 重新載入systemd服務
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "daomon_reload=yes"
- 重啟nginx服務
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=started"
- 關閉nginx服務
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=stopped"
- 重啟nginx服務
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=restarted"
- 重新載入nginx服務
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=reloaded"
- 加入開機自啟
[root@ansible-01 ~]# ansible webservers -i hosts -m systemd -a "name=nginx enabled=yes"
1.4.7 group 模組
在被管理節點上,對組進行管理
常用引數
name
組名稱,必須有system
是否為系統組 yes|no,預設是nostate
刪除組 present/absent
練習
- 建立普通組
[root@ansible-01 ~]# ansible dbservers -i hosts -m group -a "name=group_admin"
1.4.8 user 模組
用於在被管理節點上對使用者進行管理
常用引數
name
使用者名稱,必須有password
設定使用者的密碼,這裡接收的是一個加密的指,因為直接存到shadow,預設不設定密碼update_password
假如設定的密碼不同於原始密碼home
指定的家目錄shell
指定使用者的shellcomment
使用者的描述資訊create_home
在建立使用者時,是否建立其家目錄。預設建立,假如不建立,設定為nogroup
設定使用者的主組groups
將使用者加入到多個其他組中,可以用逗號隔開。預設會把使用者從其他已經加入的組中刪除append
yes|no 和groups配合使用,yes時,不會把使用者已經加入的其他組刪除system
設定為yes時,將會建立一個新的系統賬號expires
設定使用者過期時間,值為時間戳,會轉為多少天后,放在shadow的第八個欄位裡generate_ssh_key
設定成yes將會為使用者產生祕鑰,不會覆蓋原來的祕鑰ssh_key_type
指定使用者的祕鑰型別,預設rsa,具體的型別取決於被管理的節點state
刪除或者新增使用者,present為新增,absent為刪除,預設為presentremove
當與state=absent
一起使用,刪除一個使用者及其關聯的目錄,比如家目錄、郵箱目錄、可選值為 yes|no
練習
- 建立使用者並設定密碼
# 1. 先生成加密密碼
[root@ansible-01 ~]# pass=$(echo "123456" | openssl passwd -l -stdin
# 2. 執行ansible命令,建立使用者foo並設定密碼
[root@ansible-01 ~]# ansible all -i hosts -m user -a "name=foo password=${pass}"
# 3. 建立使用者mage,併為其設定金鑰對,祕鑰型別為ecdsa
[root@ansible-01 ~]# ansible all -i hosts -m user -a "name=mage generate_ssh_key=yes ssh_key_type=ecdsa}"
# 4. 建立tom,並設定其有效期到2021-10-5,並加入到組db_admin中(新增的組在被管理節點上要有),不改變用於原有組
[root@ansible-01 ~]# ansible dbservers -i hosts -m user -a "name=tom expires=$(date +%s -d 20211005) groups=db_admin append=yes"
date命令說明
# 計算3小時後是幾點幾分
[root@web-01 ~]# date +%T -d '3 hours'
# 任意日期的前N天,後N天的具體日期
[root@web-01 ~]# date +%F -d "20190910 1 day"
2019-09-11
[root@web-01 ~]# date +%F -d "20190910 -1 day"
2019-09-09
# 計算兩個日期相差幾天,比如計算生日距離現在還有多少天
[root@web-01 ~]# d1=$(date +%s -d 20180728)
[root@web-01 ~]# d2=$(date +%s -d 20180726)
[root@web-01 ~]# echo $(((d1-d2)/86400))
2
1.4.9 file 模組
file 模組主要用於遠端主機上的檔案操作.
常用引數:
-
group
定義檔案/目錄的屬組 -
mode
定義檔案/目錄的許可權 -
owner
定義檔案/目錄的屬主 -
path
必選項,定義檔案/目錄的路徑 -
recurse
遞迴的設定檔案的屬性,只對目錄有效 -
src
連結(軟/硬)檔案的原始檔的路徑 -
dest
被連結到的路徑,只應用於state=link 的情況 -
state
- directory 如果目錄不存在,則建立目錄
- file 檔案不存在,則不會建立,存在返回檔案的資訊,常用於檢測檔案是否存在
- link 建立軟連線
- hard 建立硬連結
- touch 如果檔案不存在,則會建立一個新的檔案,如果檔案已經存在,則更新其最後修改的時間
- absent 刪除目錄/檔案,或者軟連線
練習
# 建立一個檔案
[root@ansible-01 ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf state=touch"
# 改變檔案所有者和許可權
[root@ansible-01 ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=644"
# 建立一個軟連線
[root@ansible-01 ~]# ansible all -i hosts -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
# 建立一個目錄
[root@ansible-01 ~]# ansible all -i hosts -m file -a "path=/tmp/testdir state=directory"
# 取消連結
[root@ansible-01 ~]# ansible all -i hosts -m file -a "path=/tmp/link.conf state=absent "
# 刪除一個檔案
[root@ansible-01 ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf state=absent"
1.4.10 cron 模組
管理遠端節點的CRON 服務, 等同於Linux的計劃任務。
注意:使用Ansible 建立的計劃任務,是不能在本地用crontab -e 去編輯的,否則Ansible 無法再次編輯此計劃任務
常用引數:
-
name
指定一個cron job 的名字,一定要指定,以便以後刪除 -
minute
指定分鐘,可以設定成(0-59,* ,*/2)等格式,預設是 *,也就是每分鐘 -
hour
指定小時,可以設定成(0-23,,/2)等格式,預設是 *,也就是每小時 -
day
指定天,可以設定成(1-31,,/2)等格式,預設是 * ,也就是每天 -
month
指定月,可以設定成(1-12,,/2)等格式,預設是 * ,也就是每月 -
weekday
指定星期,可以設定成(0-6 for Sunday-Saturday,*)等,預設是 * ,也就是每星期 -
job
指定要執行的內容,通常可以寫一個指令碼,或者一段內容 -
state
指定這個job的狀態,可以是新增(present)或者是刪除(absent)預設為新增(present)
練習:
# 1.建立一個cron job 任務
[root@ansible-01 ~]# ansible all -i hosts -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
# 登入任何一臺管理機驗證
[root@web-01 ~]# crontab -l
#Ansible: create new job
0 * * * * ls -alh > /dev/null
# 2.刪除一個cron job 任務,刪除是一定要指定job的name引數,以免誤刪。
[root@ansible-01 ~]# ansible all -i hosts -m cron -a "name='create new job' state=absent"
1.4.11 debug 模組
debug 模組主要用於除錯時使用,通常的作用是將一個變數的指列印出來。
常用引數:
var
:直接列印一個指定的變數msg
:列印一段可以格式化的字串
練習:
這裡引入了變數,我們只需要瞭解debug即可,後面會在學習劇本時,更加深刻的瞭解
[root@ansible-01 ~]# ansible all -i hosts -m debug -a "var=role" -e "role=web"
[root@ansible-01 ~]# ansible all -i hosts -m debug -a "msg='role is {{role}}'" -e "role=web"
1.4.12 template 模組
template 模組使用了jinjia2格式作為檔案模組,可以進行文件內的變數替換。檔案以.j2 結尾。
常用引數:
src
指定 ansible 控制端的,檔案路徑dest
指定 ansible 被控制端的,檔案路徑owner
指定檔案的屬主group
指定檔案的屬組mode
指定檔案的許可權backup
建立一個包含時間戳資訊的備份檔案,這樣您以一種錯誤的方式破環了原始檔案,就可以將其恢復原狀,yes/no
練習:
其用法和copy模組一樣,template 模組的強大之處,就是使用變數替換,就是可以把傳遞給 ansible 的變數的值替換到模板檔案中。
# 1.建立一個 template 檔案,名為 hello_world.j2
# cat hello_world.j2
Hello {{var}} !
# 2.執行命令,並設定變數var的值為world
[root@ansible-01 ~]# ansible all -i hosts -m template -a "src=hello_world.j2 dest=/tmp/hello_world" -e "var=world"
# 3.在被控制主機驗證
[root@web-01 ~]# cat /tmp/hello_world
Hello world !
1.4.13 lineinfile 模組
在被管理節點上,用正則匹配的方式對目標檔案的一行內容 刪除等操作。
如果是在一個檔案中把所有匹配到的多行都進行統一處理,請參考replace模組。
如果想對一個檔案的多行進行新增/更新/刪除等操作,參考blockinfile模組。
常用引數:
path
在被管理節點的檔案路徑,必須存在state
可選值absent刪除,present替換(預設值)regexp
在檔案的每一行中查詢的正規表示式,對於state=present 僅找到的最後一行被替換line
要在檔案中插入/替換的行,需要state=present
create
檔案不存在是建立,是否要建立檔案並新增內容,yes|no
練習:
# 1.刪除被控節點檔案裡的某一條內容
[root@ansible-01 ~]# ansible dbservers -i hosts -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"
# 2.替換某一行
[root@ansible-01 ~]# ansible dbservers -i hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"