天天看點

05-Ansible子產品的基本使用

一、如何使用子產品

由前面的學習可知,當我們使用 ansible 完成實際任務時,需要依靠 ansible 的各個子產品,比如,我們想要去 ping 某主機,則需要使用 ping 子產品,指令如下:

ansible all -m ping

除了 ping 子產品,ansible 還有很多子產品可供我們使用。我們可以使用如下指令,檢視 ansible 都有哪些子產品:

[root@ansible-manager ~]# ansible-doc -l
a10_server                                           Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' server object.                                           
a10_server_axapi3                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices                                                           
a10_service_group                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' service groups.                                          
a10_virtual_server                                   Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' virtual servers.                                         
accelerate                                           Enable accelerated mode on remote node                                                                           
aci_aaa_user                                         Manage AAA users (aaa:User)                                                                                      
aci_aaa_user_certificate                             Manage AAA user certificates (aaa:UserCert)                                                                      
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:RsAccBaseGrp, infra:PortBlk)
aci_aep                                              Manage attachable Access Entity Profile (AEP) objects (infra:AttEntityP, infra:ProvAcc)                          
aci_aep_to_domain                                    Bind AEPs to Physical or Virtual Domains (infra:RsDomP)                                                          
aci_ap                                               Manage top level Application Profile (AP) objects (fv:Ap)                                                        
aci_bd                                               Manage Bridge Domains (BD) objects (fv:BD)                                                                       
aci_bd_subnet                                        Manage Subnets (fv:Subnet)                                                                                       
aci_bd_to_l3out                                      Bind Bridge Domain to L3 Out (fv:RsBDToOut)       
......
           

通過上面指令可以看到 ansible 中各個子產品的名稱,以及子產品的大概功能。當然,通過ansible-doc -l指令擷取到的子產品資訊比較概括,并不是特别詳細,如果想要擷取到各個子產品更加詳細的用法,可以使用ansible-doc -s指令。比如,我們想要擷取 ping 子產品的詳細使用方法,則可以使用如下指令:

[root@ansible-manager ~]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
  ping:
      data:                  # Data to return for the `ping' return value. If this parameter is set to `crash', the module will cause an exception.
           

即使使用ansible-doc -s ping指令檢視 ping 子產品的描述,得到的資訊也是比較少的。這是因為 ping 子產品本來就比較簡單,而且 ping 子產品并沒有太多參數可用。但是并非所有子產品都像 ping 子產品一樣簡單,有的子產品在使用時必須使用參數,比如 fetch 子產品,fetch 為”拿來”之意,當我們需要将被管理主機中的檔案拉取到 ansible 主機時,則可以使用此子產品。首先,我們可以使用ansible-doc -s fetch指令,檢視一下 fetch 子產品的用法:

[root@ansible-manager ~]# ansible-doc -s fetch
- name: Fetches a file from remote nodes
  fetch:
      dest:                  # (required) A directory to save the file into. For example, if the `dest' directory is `/backup' a `src' file named `/etc/profile' on host
                               `host.example.com', would be saved into `/backup/host.example.com/etc/profile'
      fail_on_missing:       # When set to 'yes', the task will fail if the remote file cannot be read for any reason.  Prior to Ansible-2.5, setting this would only fail
                               if the source file was missing. The default was changed to "yes" in Ansible-2.5.
      flat:                  # Allows you to override the default behavior of appending hostname/path/to/file to the destination.  If dest ends with '/', it will use the
                               basename of the source file, similar to the copy module. Obviously this is only handy if the filenames are
                               unique.
      src:                   # (required) The file on the remote system to fetch. This `must' be a file, not a directory. Recursive fetching may be supported in a later
                               release.
      validate_checksum:     # Verify that the source and destination checksums match after the files are fetched.
           

從幫助資訊中可以看出,fetch 子產品的作用就是”Fetches a file from remote nodes”,即”從被管理主機中拉取檔案”之意,而且 fetch 子產品提供了一些參數供我們使用,可用的參數有 dest、fail_on_missing、flat、src、validate_checksum ,而且幫助資訊中注釋了每個參數的作用。

比如 src 參數的作用就是指定從被管理主機中拉取哪個檔案。

比如 dest 參數的作用就是指定拉取檔案到本地以後檔案存放的位置。

dest 參數和 src 參數的注釋中都包含”(required)”字樣,這表示在使用 fetch 子產品時,dest 參數與 src參數是必須提供的,如果在使用 fetch 子產品時,沒有提供這兩個參數,将會報錯。想想也對,如果我們想要從遠端主機中拉取檔案,那麼我們必須告訴 ansible,從哪裡拉取檔案,然後将檔案存放到哪裡。是以,在學習怎樣使用一個子產品時,要注意這些必選參數。

現在,我們就以 fetch 子產品為例,看看怎樣使用帶有參數的子產品。

首先來看一下主機清單配置:

[demoA]
ansible-demo1
[demoB]
ansible-demo2
ansible-demo3
[demo:children]
demoA
demoB
           

假如我們想要将 demoB 組中所有主機的 /testdir/testfile1 檔案拉取到本地,則可以使用如下指令:

ansible demoB -m fetch -a "src=/testdir/testfile1 dest=/testdir/ansible/"

如上述指令所示,-m 選項用于調用指定的子產品,”-m fetch“表示調用 fetch 子產品,-a 選項用于傳遞子產品所需要使用的參數, -a "src=/testdir/testfile1 dest=/testdir/ansible/" 表示我們在使用 fetch 子產品時,為 fetch 子產品傳入了兩個參數,src 與 dest。

我們看一下上述指令的執行效果:

從指令的執行結果可以看出,上述指令執行成功了,因為兩個主機對應的傳回資訊都傳回了”SUCCESS”字樣。

為什麼指令執行成功了,傳回的資訊卻是”黃色”的,在我們的印象中,執行成功,傳回的資訊不應該是”綠色”的嗎?這個後面我們再解釋。

從傳回資訊可以看出,執行上述 ansible 指令後,主機 ansible-demo2 和主機 ansible-demo3 中的檔案已經拉取成功,ansible-demo2 的 testfile1 檔案被拷貝到了本機的 /testdir/ansible目錄中,而且,ansible在 /testdir/ansible 目錄中自動建立了目錄結構 ansible-demo2/testdir/,由于我們是同時從多台被管理主機中拉取相同名稱的檔案,是以 ansible 會自動為我們建立各個主機對應的目錄,以區分存放不同主機中的同名檔案。是不是很友善,很人性化呢?

二、關于幂等性

在00節介紹 ansible 特點時說過,ansible 具有幂等性,幂等性能夠保證我們重複的執行一項操作時,得到的結果是相同的,下面詳細介紹一下幂等性的概念。

舉個例子,你想把一個檔案拷貝到目标主機的某個目錄上,但是你不确定此目錄中是否已經存在此檔案,當你使用 ansible 完成這項任務時,就非常簡單了,因為如果目标主機的對應目錄中已經存在此檔案,那麼 ansible 則不會進行任何操作,如果目标主機的對應目錄中并不存在此檔案,ansible 就會将檔案拷貝到對應目錄中。說白了,ansible 是”以結果為導向的”,我們指定了一個”目标狀态”,ansible 會自動判斷,”目前狀态”是否與”目标狀态”一緻,如果一緻,則不進行任何操作,如果不一緻,那麼就将”目前狀态”變成”目标狀态”,這就是”幂等性”,”幂等性”可以保證我們重複的執行同一項操作時,得到的結果是一樣的。

現在我們就來實驗一下,看看重複執行相同的 ansible 指令時,會得到什麼效果,如下圖所示:

從上圖可以看出,傳回資訊仍然包含”SUCCESS”字樣,證明 ansible 指令執行成功,不過很明顯,這次的傳回資訊為”綠色”,而且細心的你一定發現了,這次綠色的傳回資訊中,”changed” 字段的值為false,而之前黃色的傳回資訊中,”changed” 字段的值為 true。

當傳回資訊為綠色時,”changed” 為 false,表示 ansible 沒有進行任何操作,沒有”改變什麼”。

當傳回資訊為黃色時,”changed” 為 true,表示 ansible 執行了操作,”目前狀态”已經被 ansible 改變成了”目标狀态”。

這就是幂等性的展現,當第一次執行上述指令時,ansible 發現目前主機中并沒有我們需要的 testfile1檔案,ansible 就會按照我們指定的操作,拉取 testfile1 檔案,也就是說,ansible “改變”了”目前狀态”,将目前”沒有 testfile1 檔案的狀态”變為了”有 testfile1 檔案的狀态”。當我們再次執行同樣的指令時,ansible 發現對應檔案已經存在于對應目錄中,于是 ansible 并沒有做出任何操作,也沒有進行任何改變,因為”目前狀态”與我們預期的”目标狀态”一緻,沒有必要再做出重複的無用功。

看到這裡,你應該已經明白,為什麼執行 ansible 指令時,會傳回黃色的成功資訊或者綠色的成功資訊了吧?我們可以通過傳回資訊的顔色,更加精準的判斷執行指令之前的狀态是否與我們預期的一緻。

從傳回資訊中可以看到,當 ansible 進行 fetch 操作時,會對對應檔案進行哈希計算,算出檔案哈希值,也就是說,如果我們改變了檔案中的内容,哈希值也将随之發生改變,這個時候,即使對應目錄中存在同名的檔案,ansible 也會判斷出兩個檔案屬于不同的檔案,因為它們的哈希值并不相同,我們來實驗一下,操作如下:

如上圖所示,我們在 /testdir/ansible/ansible-demo2/testdir/testfile1檔案的尾部加入一個”空格”,以改變檔案内容,然後又執行了 fetch 指令,結果發現,ansible-demo2 的傳回資訊為黃色,ansible-demo3 主機的傳回資訊為綠色,證明 ansible 已經做出了正确的判斷,将修改過的檔案替換為重新拉取的檔案。

三、總結

我們對上面的一些指令進行總結,友善以後回顧:

1.列出ansible所支援的子產品。

ansible-doc -l

2.檢視子產品的詳細幫助資訊,比如檢視 fetch 子產品的幫助。

ansible-doc -s fetch

3.調用子產品,比如調用 ping子產品。

ansible 192.168.128.83 -m ping

4.調用子產品的同時傳入子產品所需要的參數,以 fetch 子產品為例。

ansible 192.168.128.83 -m fetch -a "src=/testdir/testfile1 dest=/testdir/ansible/"

繼續閱讀