第 3 章 Ansible Ad-Hoc
3.1 命令格式
我們?cè)诳焖偃腴T(mén)中執(zhí)行的Ansible 命令李破,類似于我們的批處理命令预鬓。在Ansible 中統(tǒng)稱為Ansible Ad-Hoc到涂。
其命令語(yǔ)法格式如下:
ansible pattern [-i inventory] -m module -a argument
pattern, 資產(chǎn)選擇器
-i , 指定資產(chǎn)的位置
-m , 指定本次Ansible ad-hoc 要執(zhí)行的模塊蒿赢∩莘剑可以類別成SHELL 中的命令搔扁。
-a , 模塊的參數(shù). 可以類比成SHELL 中的命令參數(shù)
示例:
// 快速入門(mén)的實(shí)例
# ansible all -i 10.3.134.4, -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
copy模塊 文件必須存在
3.2 模塊類型
Ansible 模塊分三種類型: 核心模塊(core module)爸舒、附加模塊(extra module)及用戶自定義模塊(consume module)。
核心模塊是由Ansible 的官方團(tuán)隊(duì)提供的稿蹲。
附加模塊是由各個(gè)社區(qū)提供的扭勉。例如: OPENSTACK 社區(qū)、DOCKER 社區(qū)等等苛聘。
當(dāng)核心模塊和附加模塊都無(wú)法滿足你的需求時(shí)涂炎,用戶可以自定義模塊。
默認(rèn)情況下设哗,在安裝Ansible 的時(shí)候唱捣, 核心模塊和附加模塊都已經(jīng)安裝而無(wú)需用戶干預(yù)。
3.3 聯(lián)機(jī)幫助
Ansible 的核心模塊和附加模塊熬拒,數(shù)量有1000+ 爷光。這樣龐大的模塊數(shù)量,對(duì)于任何一個(gè)接觸Ansible 的人都不可能將
其完全記住澎粟、掌握使用蛀序。 因此能夠順利使用Ansible 的幫助文檔,對(duì)我們來(lái)說(shuō)是很有必要的活烙。Ansible 的幫助文檔徐裸,
由它本身提供的命令 ansible-doc 實(shí)現(xiàn)。
常用幫助參數(shù)
// 列舉出所有的核心模塊和附加模塊
# ansible-doc -l
// 查詢某個(gè)模塊的使用方法
# ansible-doc modulename
// 查詢某個(gè)模塊的使用方法啸盏,比較簡(jiǎn)潔的信息
# ansible-doc -s modulename
// Example
# ansible-doc yum
# ansible-doc -s yum
3.4 常用模塊
command & shell 模塊
兩個(gè)模塊都是在遠(yuǎn)程服務(wù)器上去執(zhí)行命令重贺。但command模塊是ad-hoc的默認(rèn)模塊,在執(zhí)行ad-hoc時(shí),若不指定模塊的名字
則默認(rèn)使用此模塊.常用參數(shù)如下:
command & shell
- chdir 在運(yùn)行命令之前,切換目錄回懦。
[root@biudefor ~]# ansible web_server -m shell -a "chdir=/testdir echo mytest > test"
ansible-demo3 | SUCCESS | rc=0 >>
- executable 更改用于執(zhí)行命令的shell(bash气笙,sh),需要是可執(zhí)行文件的絕對(duì)路徑怯晕。
示例:
// ad-hoc 默認(rèn)在不指定 -m 參數(shù)的時(shí)候潜圃, 使用了默認(rèn)的command 模塊
# ansible all -i inventory -a "ls /root"
# ansible all -i inventory -m command -a "ls /root" //等同第一個(gè)命令
# ansible all -i inventory -m shell -a "ls /root"
兩個(gè)模塊功能類似的模塊又存在的必要嗎? 他們之間的差異在哪里?
shell 模塊可以執(zhí)行SHELL 的內(nèi)置命令
command 模塊無(wú)法執(zhí)行SHELL 的內(nèi)置命令 比如:管道
如何檢測(cè)那些命令是shell 的 內(nèi)置命令呢?
# type -a set // set 為SHELL內(nèi)置命令
set is a shell builtin
# type -a env // env 非內(nèi)置命令
env is /bin/env
env is /usr/bin/env
示例:
[root@biudefor ~]# ansible all -i localhost, -c local -a "set"
localhost | FAILED | rc=2 >>
[Errno 2] No such file or directory
// -c local 表示以本地的方式執(zhí)行,不使用 SSH 連接的方式
# ansible all -i localhost, -c local -m shell -a "set"
localhost | SUCCESS | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_EXECUTION_STRING=set
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.1.2(1)-release'
DIRSTACK=()
......
......
script 模塊
將管理節(jié)點(diǎn)上的腳本傳遞到遠(yuǎn)程服務(wù)器上進(jìn)行執(zhí)行舟茶,理論上此模塊的執(zhí)行完全不需要被管理服務(wù)器上有Python谭期。
示例:
// 管理節(jié)點(diǎn)上的一個(gè)腳本
# cat /root/a.sh
#/bin/bash
touch /tmp/testfile
# ansible all -i inventory -m script -a "/root/a.sh"
copy 模塊
copy 模塊的主要用于管理節(jié)點(diǎn)和被管理節(jié)點(diǎn)之間的文件拷貝。經(jīng)常使用到的參數(shù)如下:
- src 指定拷貝文件的源地址
- dest 指定拷貝文件的目標(biāo)地址
- backup 拷貝文件前吧凉,若原始文件發(fā)生變化隧出,則對(duì)目標(biāo)文件進(jìn)行備份
- woner 指定新拷貝文件的所有者
- group 指定新拷貝文件的所有組
- mode 指定新拷貝文件的權(quán)限
示例:
// copy 管理節(jié)點(diǎn)上的/tmp/a.conf 到被管理節(jié)點(diǎn)上
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
// copy 前, 在被管理節(jié)點(diǎn)上對(duì)原文件進(jìn)行備份
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf backup=yes"
// copy 文件的同時(shí)對(duì)文件進(jìn)行用戶及用戶組設(shè)置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf owner=nobody group=nobody"
// copy 文件的同時(shí)對(duì)文件進(jìn)行權(quán)限設(shè)置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf mode=0755"
service 模塊
管理遠(yuǎn)程節(jié)點(diǎn)上的服務(wù)阀捅。類似于Linux上的service命令胀瞪。常用參數(shù)如下:
– enabled 是否開(kāi)機(jī)啟動(dòng) yes|no
– name 必選項(xiàng),服務(wù)名稱
– runlevel 運(yùn)行級(jí)別
– sleep 如果執(zhí)行了restarted饲鄙,在則stop和start之間沉睡幾秒鐘
– state 對(duì)當(dāng)前服務(wù)執(zhí)行啟動(dòng)赏廓,停止涵紊、重啟、重新加載等操作(started,stopped,restarted,reloaded)
注意:
使用 service 模塊時(shí), enabled 和 state 參數(shù)至少要指定一個(gè)幔摸。
使用 service 模塊管理的服務(wù)摸柄,必須在系統(tǒng)中存在 /etc/init.d/XXX 對(duì)應(yīng)的服務(wù)。
比如若管理Nginx 服務(wù)既忆,則應(yīng)該存在 /etc/init.d/nginx
示例
// 啟動(dòng) Nginx 服務(wù)
# ansible all -i inventory -m service -a "name=nginx state=started"
// 關(guān)閉 Nginx 服務(wù)
# ansible all -i inventory -m service -a "name=nginx state=stopped"
// 重啟 Nginx 服務(wù)
# ansible all -i inventory -m service -a "name=nginx state=restarted"
// 重新加載 Nginx 服務(wù)
# ansible all -i inventory -m service -a "name=nginx state=reloaded"
// 加 Nginx 服務(wù)設(shè)置開(kāi)機(jī)自啟動(dòng)
# ansible all -i inventory -m service -a "name=nginx enabled=yes"
systemd 模塊
管理遠(yuǎn)程節(jié)點(diǎn)上的 systemd 服務(wù)驱负,就是由 systemd 所管理的服務(wù)。常用參數(shù)如下:
- daemon_reload 重新載入 systemd患雇,掃描新的或有變動(dòng)的單元
– enabled 是否開(kāi)機(jī)啟動(dòng) yes|no
– name 必選項(xiàng)跃脊,服務(wù)名稱
– state 對(duì)當(dāng)前服務(wù)執(zhí)行啟動(dòng),停止苛吱、重啟酪术、重新加載等操作(started,stopped,restarted,reloaded)
示例:
// 重新加載 systemd
# ansible all -i inventory -m systemd -a "daemon_reload=yes"
// 啟動(dòng) Mariadb 服務(wù)
# ansible all -i inventory -m systemd -a "name=mariadb state=started"
// 關(guān)閉 Mariadb 服務(wù)
# ansible all -i inventory -m systemd -a "name=mariadb state=stopped"
// 重啟 Mariadb 服務(wù)
# ansible all -i inventory -m systemd -a "name=mariadb state=restarted"
// 重新加載 Mariadb 服務(wù)
# ansible all -i inventory -m systemd -a "name=mariadb state=reloaded"
// 將 Mariadb 服務(wù)設(shè)置開(kāi)機(jī)自啟動(dòng)
# ansible all -i inventory -m systemd -a "name=mariadb enabled=yes"
yum 模塊
等同于 Linux 上的YUM 命令, 對(duì)遠(yuǎn)程服務(wù)器上RPM包進(jìn)行管理翠储。常用參數(shù)如下:
- name 要安裝的軟件包名绘雁, 多個(gè)軟件包以逗號(hào)(,) 隔開(kāi)
- state 對(duì)當(dāng)前指定的軟件安裝、拆卸操作(present installed latest absent removed)
安裝參數(shù) present installed latest
拆卸參數(shù) absent removed
示例:
// 安裝一個(gè)軟件包
#ansible web_server -m yum -a "name=tree state=present"
# ansible all -i inventory -m yum -a "name=nginx state=present"
# ansible all -i inventory -m yum -a "name=nginx state=latest"
# ansible all -i inventory -m yum -a "name=nginx state=installed"
// 拆卸一個(gè)軟件包
# ansible all -i inventory -m yum -a "name=nginx state=absent"
# ansible all -i inventory -m yum -a "name=nginx state=removed"
// 安裝一個(gè)軟件包組
# ansible all -i inventory -m yum -a "name='@Development tools' state=present"
group 模塊
在被管理節(jié)點(diǎn)上援所,對(duì)組進(jìn)行管理庐舟。 常用參數(shù)如下:
- name 組名稱, 必須的
- system 是否為系統(tǒng)組, yes/no
示例:
// 創(chuàng)建普通組 db_admin
# ansible all -i 172.16.153.160, -m group -a "name=db_admin"
user 模塊
用于在被管理節(jié)點(diǎn)上對(duì)用戶進(jìn)行管理住拭。常用參數(shù)如下:
- name 必須的參數(shù)挪略, 指定用戶名
- password 設(shè)置用戶的密碼,這里接受的是一個(gè)加密的值滔岳,因?yàn)闀?huì)直接存到 shadow
- update_password 假如設(shè)置的密碼不同于原密碼杠娱,則會(huì)更新密碼. 在 1.3 中被加入
- home 指定用戶的家目錄
- shell 設(shè)置用戶的 shell
- uid 指定用戶的 UID
- comment 用戶的描述信息
- create_home 在創(chuàng)建用戶時(shí),是否創(chuàng)建其家目錄谱煤。默認(rèn)創(chuàng)建摊求,假如不創(chuàng)建,設(shè)置為 no趴俘。2.5版本之前
使用 createhome
- group 設(shè)置用戶的主組
- groups 將用戶加入到多個(gè)組中睹簇,多個(gè)用逗號(hào)隔開(kāi)奏赘,也可以是個(gè)列表
- system 設(shè)置為 yes 時(shí)寥闪,將會(huì)創(chuàng)建一個(gè)系統(tǒng)賬號(hào)
- expires 設(shè)置用戶的過(guò)期時(shí)間,值為時(shí)間戳,會(huì)轉(zhuǎn)為為天數(shù)后磨淌,放在 shadow 的最后一個(gè)字段里
- generate_ssh_key 設(shè)置為 yes 將會(huì)為用戶生成密鑰疲憋,這不會(huì)覆蓋原來(lái)的密鑰
- ssh_key_type 指定用戶的密鑰類型, 默認(rèn) rsa, 具體的類型取決于被管理節(jié)點(diǎn)
- remove 當(dāng)與 state=absent 一起使用梁只,刪除一個(gè)用戶及其家目錄缚柳,可選的值為: yes/no
示例:
// 生成加密的密碼
# echo test |openssl passwd -1 -stdin
// 創(chuàng)建一個(gè)用戶 nginx, 指定其 shell 為 nologin
# ansible all -i inventory -m user -a "name=nginx shell=/sbin/nologin"
// 創(chuàng)建用戶 yangge, 并且為其創(chuàng)建密鑰對(duì)埃脏,并且密鑰類型為: ecdsa
# ansible all -i inventory -m user -a "name=yangge generate_ssh_key=yes ssh_key_type=ecdsa"
// 創(chuàng)建用 tom, 并且設(shè)置其有效期到 2020年8月16日, 加入到組 db_admin 中
# timestamp=$(date +%s -d 20200816)
// 或者
# timestamp=$(python -c 'import time;print(time.mktime(time.strptime("2019-08-16", "%Y-%m-%d")))')
# ansible all -i 172.16.153.160, -m user -a "name=tom expires=$timestamp"
// 修改已有用戶 tom 在 31 天后過(guò)期
# ansible all -i 172.16.153.160, -m user -a "name=tom expires=$(echo $((86400 * 31))) groups=db_admin,"
date 命令
// 計(jì)算 3 小時(shí)之后是幾點(diǎn)幾分
# date +%T -d '3 hours'
// 任意日期的前 N 天,后 N 天的具體日期
# date +%F -d "20190910 1 day"
# date +%F -d "20190910 -1 day"
// 計(jì)算兩個(gè)日期相差天數(shù), 比如計(jì)算生日距離現(xiàn)在還有多少天
# d1=$(date +%s -d 20180728)
# d2=$(date +%s -d 20180726)
# echo $(((d1-d2)/86400))
file 模塊
file 模塊主要用于遠(yuǎn)程主機(jī)上的文件操作秋忙,經(jīng)常使用的模塊參數(shù)如下:
- group 定義文件/目錄的屬組
- mode 定義文件/目錄的權(quán)限
- owner 定義文件/目錄的屬主
- path 必選項(xiàng)彩掐,定義文件/目錄的路徑
- recurse 遞歸的設(shè)置文件的屬性,只對(duì)目錄有效
- src 要被鏈接(軟/硬)的源文件的路徑灰追,只應(yīng)用于state=link的情況
- dest 被鏈接到的路徑堵幽,只應(yīng)用于state=link的情況
- state
?? directory 如果目錄不存在,創(chuàng)建目錄
?? file 文件不存在弹澎,則不會(huì)被創(chuàng)建朴下,存在則返回文件的信息,常用于檢查文件是否存在苦蒿。
?? link 創(chuàng)建軟鏈接
?? hard 創(chuàng)建硬鏈接
?? touch 如果文件不存在殴胧,則會(huì)創(chuàng)建一個(gè)新的文件,如果文件或目錄已存在佩迟,則更新其最后修改時(shí)間
?? absent 刪除目錄团滥、文件或者取消鏈接文件
示例:
// 創(chuàng)建一個(gè)文件
# ansible all -i inventory -m file -a "path=/tmp/foo.conf state=touch"
// 改變文件所有者及權(quán)限
# ansible all -i inventory -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"
// 創(chuàng)建一個(gè)軟連接
# ansible all -i inventory -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
// 創(chuàng)建一個(gè)目錄
# ansible all -i inventory -m file -a "path=/tmp/testdir state=directory"
// 取消一個(gè)連接
# ansible all -i inventory -m file -a "path=/tmp/link.conf state=absent"
// 刪除一個(gè)文件
# ansible all -i inventory -m file -a "path=/tmp/foo.conf state=absent"
cron 模塊
管理遠(yuǎn)程節(jié)點(diǎn)的CRON 服務(wù)。等同于Linux 中的CRON音五。 常用命令如下:
- name 指定一個(gè)cron job 的名字惫撰。一定要指定,便于日之后刪除躺涝。
- minute 指定分鐘厨钻,可以設(shè)置成(0-59, *, */2 等)格式。 默認(rèn)是 * , 也就是每分鐘坚嗜。
- hour 指定小時(shí)夯膀,可以設(shè)置成(0-23, *, */2 等)格式。 默認(rèn)是 * , 也就是每小時(shí)苍蔬。
- day 指定天诱建, 可以設(shè)置成(1-31, *, */2 等)格式。 默認(rèn)是 * , 也就是每天碟绑。
- month 指定月份俺猿, 可以設(shè)置成(1-12, *, */2 等)格式。 默認(rèn)是 * , 也就是每周格仲。
- weekday 指定星期押袍, 可以設(shè)置成(0-6 for Sunday-Saturday, * 等)格式。默認(rèn)是 *凯肋,也就是每星期谊惭。
- job 指定要執(zhí)行的內(nèi)容,通常可以寫(xiě)個(gè)腳本圈盔,或者一段內(nèi)容豹芯。
- state 指定這個(gè)job的狀態(tài),可以是新增(present)或者是刪除(absent)驱敲。 默認(rèn)為新增(present)
示例:
// 新建一個(gè) CRON JOB 任務(wù)
# ansible all -i inventory -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
# ansible web_server -m cron -a "name='new' minute=59 hour=23 weekday=5 job='ls -l /root/ &>/dev/null'"
// 刪除一個(gè) CRON JOB 任務(wù)铁蹈,刪除時(shí),一定要正確指定job 的name參數(shù)众眨,以免誤刪除木缝。
# ansible all -i inventory -m cron -a "name='create new job' state=absent"
登陸任何一臺(tái)管理機(jī)驗(yàn)證cron
# crontab -l
#Ansible: create new job
0 * * * * ls -alh > /dev/null
debug模塊
debug 模塊主要用于PlayBook調(diào)試時(shí)使用,通常的作用是將一個(gè)變量的結(jié)果打印出來(lái)围辙。常用參數(shù)如下:
- var 直接打印一個(gè)指定的變量值
- msg 打印一段可以格式化的字符串
示例:
// 這里引入了變量我碟,我們只需了解 debug 模板的使用即可。在學(xué)習(xí)變量姚建、劇本時(shí)矫俺,我們會(huì)對(duì)它有更深刻的理解。
# ansible all -i inventory -m debug -a "var=role" -e "role=web"
# ansible all -i inventory -m debug -a "msg='role is {{role}} '" -e "role=web"
template 模塊
template 模塊使用了Jinjia2格式作為文件模版掸冤,可以進(jìn)行文檔內(nèi)變量的替換厘托。
它的每次使用都會(huì)被ansible標(biāo)記為”changed”狀態(tài)。文件以 .j2 結(jié)尾
模塊常用參數(shù)如下:
- backup 創(chuàng)建一個(gè)包含時(shí)間戳信息的備份文件稿湿,這樣如果您以某種方式錯(cuò)誤地破壞了原始文件铅匹,
就可以將其恢復(fù)原狀。yes/no
- force 默認(rèn)值是yes饺藤,當(dāng)內(nèi)容與源不同時(shí)包斑,它將替換遠(yuǎn)程文件。如果no涕俗,僅在目標(biāo)不存在時(shí)才傳輸文件罗丰。
- src 指定 Ansible 控制端的 文件路徑
- dest 指定 Ansible 被控端的 文件路徑
- owner 指定文件的屬主
- group 指定文件的屬組
- mode 指定文件的權(quán)限
- newline_sequence 指定新文件的換行符; \n,\r, 或 \r\n
內(nèi)置變量
ansible_managed - 包含一個(gè)字符串再姑,可用于描述模板名稱萌抵,主機(jī),模板文件的修改時(shí)間和所有者的uid
template_host - 包含模板機(jī)器的節(jié)點(diǎn)名稱
template_uid - 所有者的uid
template_path - 模版路徑
template_fullpath - 模版的絕對(duì)路徑
template_run_date - 模版呈現(xiàn)的時(shí)間
示例:
// 把本地的當(dāng)前目錄下的 jinja2 模板文件 foo.j2 傳送到目標(biāo)機(jī)器上元镀,并指定屬主為 shark, 屬組 為 wheel, 權(quán)限為 0644
# ansible all -i 172.16.153.160, -m template -a "src=./foo.j2 dest=/tmp/foo.conf owner=shark group=wheel mode=0644"
// 上面的用法其實(shí)和 copy 模塊一樣绍填,下面我們就來(lái)介紹 template 模塊的強(qiáng)大之處
1. 建立一個(gè) template 文件, 名為 hello_world.j2
# cat hello_world.j2
Hello {{var}} !
2. 執(zhí)行命令,并且設(shè)置變量 var 的值為 world
# ansible all -i 172.16.153.160, -m template -a "src=hello_world.j2 dest=/tmp/hello_world.world" -e "var=world"
3. 在被控主機(jī)上驗(yàn)證
# cat /tmp/hello_world.world
Hello world !
所有模塊列表 https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html
模塊按照首字母排序