二、Ansible基礎之模塊篇
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=//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=//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=//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='//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"