您好,登錄后才能下訂單哦!
本節(jié)包括的模塊:
(1)shell和command
(2)復制模塊copy
(3)template模塊
(4)文件模塊file
(5)拉取文件模塊fetch
(6)rsync模塊synchronize
可以從ansible-doc -l | grep module_name
來找出想要的模塊。再使用ansible-doc -s module_name
來查看此模塊的用法。
官方模塊列表和說明: https://docs.ansible.com/ansible/latest/modules_by_category.html
關于模塊的使用方法,需要注意的是state
。很多模塊都會有該選項,且其值幾乎都包含有present
和absent
, 表示肯定和否定的意思。
ansible絕大多數(shù)模塊都天然具有 冪等 特性,只有極少數(shù)模塊如shell和command模塊不具備冪等性。所謂的冪等性是指多次執(zhí)行同一個操作不會影響最終結(jié)果。例如,ansible的yum模塊安裝rpm包時,如果待安裝的包已經(jīng)安裝過了,則再次或多次執(zhí)行安裝操作都不會真正的執(zhí)行下去。
再例如,copy模塊拷貝文件時,如果目標主機上已經(jīng)有了完全相同的文件,則多次執(zhí)行copy模塊不會真正的拷貝。ansible具有冪等性的模塊在執(zhí)行時,都會自動判斷是否要執(zhí)行。
默認ansible使用的模塊是command
,即可以執(zhí)行一些shell命令。shell和command的用法基本一樣,實際上shell模塊執(zhí)行命令的方式是在遠程使用/bin/sh來執(zhí)行的,如/bin/sh ping。
command不能解析變量如$HOME
和某些操作符"<", ">", "|", ";"以及"&"
,所以明確要使用這些不可解析的操作符時,使用shell模塊來代替command。
shell--Ansible官方使用說明文檔
command--Ansible官方使用說明文檔
ansible-doc -s shell
- name: Execute commands in nodes.
action: shell
chdir # 在執(zhí)行命令前,先cd到指定的目錄下
creates # 用于判斷命令是否要執(zhí)行。如果指定的文件(可以使用通配符)存在,則不執(zhí)行。
removes # 用于判斷命令是否要執(zhí)行。如果指定的文件(可以使用通配符)不存在,則不執(zhí)行。
executable # 不再使用默認的/bin/sh解析并執(zhí)行命令,而是使用此處指定的命令解析。
# 例如使用expect解析expect腳本。必須為絕對路徑。
在ansible中使用shell或command模塊一定要注意,它們默認不滿足冪等性,很多操作會重復執(zhí)行,但有些操作是不允許重復執(zhí)行的。例如mysql的初始化命令mys ql_ins t all_db,它只能在第一次配置的過程中初始化一次,其他任何時候如非需要則不允許執(zhí)行。這時候要實現(xiàn)冪等性,可以通過模塊的creates
和removes
選項進行判斷,但無論如何,在執(zhí)行這兩個模塊的時候都需要考慮要執(zhí)行的命令是否應該實現(xiàn)冪等性。
例子如下:
tasks:
- shell: touch helloworld.txt creates=/tmp/hello.txt
但建議,在參數(shù)可能產(chǎn)生歧義的情況下,使用args來傳遞ansible的參數(shù)。如:
- shell: touch helloworld.txt
args:
creates: /tmp/hello.txt
# You can use shell to run other executables to perform actions inline
- name: Run expect to wait for a successful PXE boot via out-of-band CIMC
shell: |
set timeout 300
spawn ssh admin@{{ cimc_host }}
expect "password:"
send "{{ cimc_password }}\n"
expect "\n{{ cimc_name }}" send "connect host\n"
expect "pxeboot.n12" send "\n"
exit 0
args:
executable: /usr/bin/expect
delegate_to: localhost
copy--Ansible官方使用說明文檔
ansible-doc -l |grep copy
使用方法:
ansible-doc -s copy
ansible-doc -s copy
- name: Copy files to remote locations
copy:
backup=[yes|no]: # 拷貝的同時也創(chuàng)建一個包含時間戳信息的備份文件,默認為no
dest: # 目標路徑,只能是絕對路徑,如果拷貝的文件是目錄,則目標路徑必須也是目錄
content: # 直接以content給定的字符串或變量值作為文件內(nèi)容保存到遠程主機上,它會替代src選項
directory_mode: # 當對目錄做遞歸拷貝時,設置了directory_mode將會使得只拷貝新建文件,
# 舊文件不會被拷貝。默認未設置
follow=[yes|no]: # 是否追蹤到鏈接的源文件。
force=[yes|no]: # 設置為yes(默認)時,將覆蓋遠程同名文件。設置為no時,忽略同名文件的拷貝
group: # 設置遠程文件的所屬組
owner: # 設置遠程文件的所有者
mode: # 設置遠程文件的權(quán)限。使用數(shù)值表示時不能省略第一位,如0644。
# 也可以使用'u+rwx'或'u=rw,g=r,o=r'等方式設置。
src: # 拷貝本地源文件到遠程,可使用絕對路徑或相對路徑。如果路徑是目錄,且目錄后加了
# 斜杠"/",則只會拷貝目錄中的內(nèi)容到遠程,如果目錄后不加斜杠,則拷貝目錄本身和
# 目錄內(nèi)的內(nèi)容到遠程。
默認情況下,ansible copy會檢查文件md5查看是否需要拷貝,相同則不會拷貝,否則會拷貝。如果設置force=yes,則當文件md5不同時(即文件內(nèi)容不同)才覆蓋拷貝,設置force=no時,則只拷貝對方?jīng)]有的文件。
關于 copy 模塊的backup
這里使用幾個例子說明下:
(1)當目標機上沒有待copy的文件時,即使設置了backup=yes
也是沒有什么用處的,如:
ansible test -m copy -a "src=/tmp/temp/test.pub dest=/tmp backup=yes" -o -f 6
執(zhí)行完之后,目標機 /tmp 目錄下只有一個 copy 過去的 test.pub 文件,并沒有像 test.pub.3286.2019-11-14@11:22:34~
這樣的備份文件出現(xiàn)~
(2)當目標機上已經(jīng)有待copy的文件時,但server端與目標機上該文件是相同時(即server端該文件未更改),即使設置了backup=yes
也是沒有什么用處的。
(3)當目標機上已經(jīng)有待copy的文件時,但server端與目標機上該文件是不同時(即server端該文件做了更改),設置了backup=yes
,備份文件則會在目標機上目標文件路徑下出現(xiàn),如:
# 我們更改下server端 test.pub 文件的內(nèi)容,然后執(zhí)行ansible
ansible test -m copy -a "src=/tmp/temp/test.pub dest=/tmp backup=yes" -o -f 6
# 我們登入到目標機上 /tmp 目錄下查看,會發(fā)現(xiàn)有一個備份文件出現(xiàn),即 test.pub.3286.2019-11-14@11:22:34~ ,它的內(nèi)容就是上次 server 端copy過來的文件內(nèi)容~
如果拷貝的是目錄,則目標路徑必須是目錄路徑。如果使用"/"結(jié)尾,則拷貝的是目錄中的文件,如果不以斜杠結(jié)尾,則拷貝的是目錄加目錄中的文件。舉例如下:
(1)情況一:使用"/"結(jié)尾
## server端
# pwd
/tmp/temp
# ll
-rw-r--r-- 1 root root 0 11月 13 11:18 a.log
-rwxr-xr-x 1 root root 338 11月 13 11:31 auto_sshcopyid.exp
-rw------- 1 root root 1679 11月 13 10:31 id_rsa
-rw-r--r-- 1 root root 395 11月 13 10:31 id_rsa.pub
-rw-r--r-- 1 root root 416 11月 13 11:27 sshkey.sh
-rw------- 1 root root 1679 11月 13 10:34 test
-rw-r--r-- 1 root root 342 11月 5 10:48 test01.py
-rw-r--r-- 1 root root 75 11月 5 14:23 test02.py
-rw-r--r-- 1 root root 299 11月 5 16:18 test03.py
-rw-r--r-- 1 root root 371 11月 5 18:52 test04.py
-rw-r--r-- 1 root root 217 11月 5 22:26 test05.py
-rw-r--r-- 1 root root 60 11月 5 22:26 test06.py
-rw-r--r-- 1 root root 406 11月 14 11:22 test.pub
執(zhí)行使用"/"結(jié)尾,則拷貝的是目錄中的文件:
ansible test -m copy -a "src=/tmp/temp/ dest=/tmp/test" -o -f 6
查看目標機 /tmp/test 目錄的內(nèi)容:
# pwd
/tmp/test
# ll
總用量 48
-rw-r--r-- 1 root root 0 11月 14 11:39 a.log
-rw-r--r-- 1 root root 338 11月 14 11:39 auto_sshcopyid.exp
-rw-r--r-- 1 root root 1679 11月 14 11:39 id_rsa
-rw-r--r-- 1 root root 395 11月 14 11:39 id_rsa.pub
-rw-r--r-- 1 root root 416 11月 14 11:39 sshkey.sh
-rw-r--r-- 1 root root 1679 11月 14 11:39 test
-rw-r--r-- 1 root root 342 11月 14 11:39 test01.py
-rw-r--r-- 1 root root 75 11月 14 11:39 test02.py
-rw-r--r-- 1 root root 299 11月 14 11:39 test03.py
-rw-r--r-- 1 root root 371 11月 14 11:39 test04.py
-rw-r--r-- 1 root root 217 11月 14 11:39 test05.py
-rw-r--r-- 1 root root 60 11月 14 11:39 test06.py
-rw-r--r-- 1 root root 406 11月 14 11:39 test.pub
(2)情況二:不以斜杠結(jié)尾
執(zhí)行不以斜杠"/"結(jié)尾,則拷貝的是目錄加目錄中的文件:
ansible test -m copy -a "src=/tmp/temp dest=/tmp/test01 backup=yes" -o -f 6
查看目標機 /tmp/test01 目錄的內(nèi)容:
# pwd
/tmp/test01
# ll
總用量 0
drwxr-xr-x 2 root root 224 11月 14 11:40 temp
# cd temp
# pwd
/tmp/test01/temp
# ll
總用量 48
-rw-r--r-- 1 root root 0 11月 14 11:40 a.log
-rw-r--r-- 1 root root 338 11月 14 11:40 auto_sshcopyid.exp
-rw-r--r-- 1 root root 1679 11月 14 11:40 id_rsa
-rw-r--r-- 1 root root 395 11月 14 11:40 id_rsa.pub
-rw-r--r-- 1 root root 416 11月 14 11:40 sshkey.sh
-rw-r--r-- 1 root root 1679 11月 14 11:40 test
-rw-r--r-- 1 root root 342 11月 14 11:40 test01.py
-rw-r--r-- 1 root root 75 11月 14 11:40 test02.py
-rw-r--r-- 1 root root 299 11月 14 11:40 test03.py
-rw-r--r-- 1 root root 371 11月 14 11:40 test04.py
-rw-r--r-- 1 root root 217 11月 14 11:40 test05.py
-rw-r--r-- 1 root root 60 11月 14 11:40 test06.py
-rw-r--r-- 1 root root 406 11月 14 11:40 test.pub
template模塊用法和copy模塊用法基本一致,它主要用于復制配置文件。template--Ansible官方使用說明文檔
ansible-doc -s template
- name: Template a file out to a remote server
template:
backup: # 拷貝的同時也創(chuàng)建一個包含時間戳信息的備份文件,默認為no
dest: # 目標路徑
force: # 設置為yes (默認)時,將覆蓋遠程同名文件。設置為no時,忽略同名文件的拷貝
group: # 設置遠程文件的所屬組
owner: # 設置遠程文件的所有者
mode: # 設置遠程文件的權(quán)限。使用數(shù)值表示時不能省略第一位,如0644。
# 也可以使用'u+rwx' or 'u=rw,g=r,o=r'等方式設置
src: # ansible控制器上Jinja2格式的模板所在位置,可以是相對或絕對路徑
validate: # 在復制到目標主機后但放到目標位置之前,執(zhí)行此選項指定的命令。
# 一般用于檢查配置文件語法,語法正確則保存到目標位置。
# 如果要引用目標文件名,則使用%s,下面的示例中的%s即表示目標機器上的/etc/nginx/nginx.conf。
示例如下:
ansible centos -m template -a "src=/tmp/nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=0770 owner=root group=root backup=yes validate='nginx -t -c %s'" -o -f 6
雖然template模塊可以按需求修改配置文件內(nèi)容來復制模板到被控主機上,但是有一種情況它是不能解決的:不同被控節(jié)點所需的配置文件差異很大,并非修改幾個變量就可以滿足。例如在centos 6和centos 7上通過yum安裝的 nginx,它們的配置文件內(nèi)容相差非常大,且centos 6上的nginx的默認就有一個/etc/nginx/conf.d/default.conf。 如果直接復制同一個模板的nginx配置文件到centos 6和centos 7上,很可能導致某一版本的nginx不能啟動。
這時就有必要在復制模板時挑選對應發(fā)行版的模板文件進行配對復制,例如要復制到 centos 6上的源模板是 nginx6.conf.j2,復制到centos 7上的源模板是nginx7.conf.j2。這種行為可以稱之為"基于變量選擇文件或模板"。
---
- tasks:
- name: template file based var
template: src=/templates/nginx{{ ansible_distribution_major_version }}.conf.j2 dest=/etc/nginx/nginx.conf validate="/usr/sbin/nginx -t -c %s"
還可以在文件內(nèi)容中指定jinja2的替代變量,在ansible執(zhí)行時首先會根據(jù)變量內(nèi)容進行渲染,渲染后再執(zhí)行相關模塊。例如,此處的template模塊,復制一個基于發(fā)行版本號的yum源配置文件。以下是某個repo文件模板 base.repo.j2的內(nèi)容。
[epel]
name=epel
baseurl=http://mirrors.aliyun.com/epel/{{ ansible_distribution_major_version }}Server/x86_64/ enable=1
gpgcheck=0
再復制即可。
---
- tasks:
- template: src=my.repo.j2 dest=/etc/yum.repos.d/my.repo
管理文件、目錄的屬性,也可以創(chuàng)建文件或目錄。file--Ansible官方使用說明文檔
ansible-doc -s file
- name: Manage files and file properties
file:
group: # file/directory的所屬組
owner: # file/directory的所有者
mode: # 修改權(quán)限,格式可以是0644、'u+rwx'或'u=rw,g=r,o=r'等
path: # 指定待操作的文件,可使用別名'dest'或'name'來替代path
recurse: # (默認no)遞歸修改文件的屬性信息,要求state=directory
src: # 要鏈接到的文件的路徑。
# 這只適用于state=link和state=hard。
# 對于state=link,這也將接受一個不存在的路徑。
# 相對路徑相對于正在創(chuàng)建的文件(路徑),這是Unix命令ln -s SRC DEST處理相對路徑的方式。
state: # directory:如果目錄不存在則遞歸創(chuàng)建
# file:文件不存在時,不會被創(chuàng)建(默認值)
# touch:touch由path指定的文件,即創(chuàng)建一個新文件,或修改其mtime和atime
# link:修改或創(chuàng)建軟鏈接
# hard:修改或創(chuàng)建硬鏈接
# absent:目錄和其中的文件會被遞歸刪除,文件或鏈接將取消鏈接狀態(tài)
需要注意的是,file模塊可以遞歸創(chuàng)建目錄,但是不能在不存在的目錄中創(chuàng)建文件,只能先創(chuàng)建目錄,再在此目錄中創(chuàng)建文件。我們做個測試驗證下:
# 被控制機上并不存在/root/test這個目錄
# 使用ansible在被控制機上/root/test目錄下創(chuàng)建foo.conf
ansible test -m file -a "path=/root/test/foo.conf owner=duser group=duser mode='0644' state=touch"
ansible執(zhí)行結(jié)果是:
192.168.246.187 | FAILED! => {
"changed": false, ## 失敗
"msg": "Error, could not touch target: [Errno 2] 沒有那個文件或目錄: b'/root/test/foo.conf'",
"path": "/root/test/foo.conf"
}
# 現(xiàn)在我們在被控制機上創(chuàng)建/root/test目錄
# 再次執(zhí)行ansible
ansible test -m file -a "path=/root/test/foo.conf owner=duser group=duser mode='0644' state=touch"
ansible執(zhí)行結(jié)果是:
192.168.246.187 | CHANGED => {
"changed": true, ## 成功
"dest": "/root/test/foo.conf",
"gid": 1009,
"group": "duser",
"mode": "0644",
"owner": "duser",
"size": 0,
"state": "file",
"uid": 1009
}
創(chuàng)建目錄,并遞歸修改目錄的屬性。
ansible test -m file -a "path=/tmp/xyz/test state=directory owner=root group=root mode='0755' recurse=yes"
修改目錄/tmp/xyz/test中test的權(quán)限
ansible test -m file -a "path=/tmp/xyz/test state=directory mode='0777'"
創(chuàng)建或修改文件屬性/權(quán)限
ansible test -m file -a "path=/tmp/xyz/test/wtf.txt state=touch mode='0644'"
和copy工作方式類似,只不過是從遠程主機將文件拉取到本地端,存儲時使用主機名作為目錄樹,且只能拉取文件不能拉取目錄!
fetch--Ansible官方使用說明文檔
ansible-doc -s fetch
- name: Fetch files from remote nodes
fetch:
dest: # 本地存儲拉取文件的目錄。例如dest=/data,src=/etc/fstab,
# 遠程主機名host.exp.com,則保存的路徑為/data/host.exp.com/etc/fstab。
fail_on_missing: # 當設置為yes時,如果拉取的源文件不存在,則此任務失敗。默認為no。
flat: # 改變拉取后的路徑存儲方式。如果設置為yes,且當dest以"/"結(jié)尾時,將直接把源文件
# 的basename存儲在dest下。顯然,應該考慮多個主機拉取時的文件覆蓋情況。
src: # 遠程主機上的源文件。只能是文件,不支持目錄。在未來的版本中可能會支持目錄遞歸拉取。
validate_checksum: # fetch到文件后,檢查其md5和源文件是否相同。
存儲為/tmp/192.168.246.187/etc/fstab:
ansible test -m fetch -a "src=/etc/fstab dest=/tmp"
存儲為/tmp/fstab:
ansible test -m fetch -a "src=/etc/fstab dest=/tmp/ flat=yes"
存儲為/tmp/fstab-192.168.246.187:
ansible test -m fetch -a "src=/etc/fstab dest=/tmp/fstab-{{inventory_hostname}} flat=yes"
這里說明一點:
上面中的{{inventory_hostname}}指的是/etc/ansible/hosts中的主機別名,如:
# /etc/ansible/hosts如下定義:
[test]
192.168.246.187
[test:vars]
ansible_ssh_private_key_file=/root/.ssh/rsa_back/id_rsa
ansible_python_interpreter=/usr/local/python3/bin/python3
這種情況下控制端生成的文件名就是/tmp/fstab-192.168.246.187。
# /etc/ansible/hosts如下定義:
[test]
nginx ansible_ssh_host=192.168.246.187
[test:vars]
ansible_ssh_private_key_file=/root/.ssh/rsa_back/id_rsa
ansible_python_interpreter=/usr/local/python3/bin/python3
這種情況下控制端生成的文件名就是/tmp/fstab-nginx。
synchronize模塊用于實現(xiàn)rsync的簡單版常用功能,它無法實現(xiàn)完整版的rsync,畢竟rsync功能太多太細致。如果要使用rsync,還是應該使用command或shell模塊來調(diào)用rsync命令。
完整的rsync功能見rsync命令中文手冊。
ansible-doc -s synchronize
- name: A wrapper around rsync to make common tasks in your playbooks quick and easy
synchronize:
src: # 指定待傳輸?shù)脑次募?梢允窍鄬β窂剑部梢允墙^對路徑。
dest: # 目標路徑。可以是絕對路徑,也可以是相對路徑。
mode: # 指定推(push)還是拉(pull)的傳輸模式。
# push時,本地為sender端,pull時,遠程為sender端。默認為push。
archive: # 等價于rsync的"-a"選項,即使用歸檔模式。它等價于rsync的"-rtopgDl"選項。值為yes/no。
times: # 保留mtime屬性,值為yes/no。
group: # 保留所屬組屬性,值為yes/no。
owner: # 保留所有者屬性,值為yes/no。
links: # 拷貝鏈接文件自身,值為yes/no。
perms: # 保留權(quán)限屬性,值為yes/no。
recursive: # 遞歸到目錄中的文件,值為yes/no。
compress: # 傳輸過程中壓縮傳輸。應該總是開啟,除非遇到問題。即rsync的"-z"選項。值為yes/no,默認是yes。
copy_links: # 拷貝軟鏈接的文件名和其指向的文件的內(nèi)容。即a指向b文件時,將在目標端生成a普通
# 文件,但此文件中的內(nèi)容是b中的內(nèi)容。
dirs: # 非遞歸方式傳輸目錄。
delete: # 目標端如果比源端文件多,則刪除這些多出來的文件,要求recursive=yes。
checksum: # 等價于"-c"選項,將基于文件的checksum來判斷是否同步,而不是默認的quick check
# 算法,該算法基于文件大小和最近的mtime來判斷是否要同步。該選項會大幅降低效率,
# 應謹慎使用。注意,它無法影響archive,即archive仍會啟用。
existing_only:# receiver端沒有的文件不同步。但仍會傳輸,只是臨時文件重組后不重命名而已。
partial: # 等價于"--partial"選項。默認rsync在傳輸中斷時會刪除傳輸了一半的文件,指定該選
# 項將保留這部分不完整的文件,使得下次傳輸時可以直接從未完成的數(shù)據(jù)塊開始傳輸。
dest_port: # ssh的連接端口。
rsync_opts: # 指定額外的rsync選項。使用數(shù)組的方式傳遞這些選項。
rsync_path: # 等價于"--rsync-path"選項,目的是啟動遠程rsync。
# 例如可以指定[--rsync-path=rsync],甚至[--rsync-path=cd /tmp/c && rsync]。
# 當不指定rsync路徑時,默認為/usr/bin/rysnc。
rsync_timeout:# 指定rsync在多久時間內(nèi)還沒有數(shù)據(jù)傳輸就超時退出。
verify_host: # 對目標主機進行ssh的host key驗證。
本博文是參考馬龍帥大佬文章整理生成,屬于博主讀書筆記,如有侵權(quán),請大佬與我聯(lián)系,立刪!
最后,感謝開源,擁抱開源~
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。