二、Ansible基礎之模組篇

錦書致南辭發表於2021-10-20

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.144192.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 確保安裝,且升級為最新

  • absentremoved 確認已經刪除

練習

  • 安裝一個軟體包
[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|no
  • name 必選項,服務名稱,比如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,預設是no
  • state 刪除組 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 指定使用者的shell
  • comment 使用者的描述資訊
  • create_home 在建立使用者時,是否建立其家目錄。預設建立,假如不建立,設定為no
  • group 設定使用者的主組
  • groups 將使用者加入到多個其他組中,可以用逗號隔開。預設會把使用者從其他已經加入的組中刪除
  • append yes|no 和groups配合使用,yes時,不會把使用者已經加入的其他組刪除
  • system 設定為yes時,將會建立一個新的系統賬號
  • expires 設定使用者過期時間,值為時間戳,會轉為多少天后,放在shadow的第八個欄位裡
  • generate_ssh_key 設定成yes將會為使用者產生祕鑰,不會覆蓋原來的祕鑰
  • ssh_key_type 指定使用者的祕鑰型別,預設rsa,具體的型別取決於被管理的節點
  • state 刪除或者新增使用者,present為新增,absent為刪除,預設為present
  • remove 當與 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"

相關文章