typora-root-url: ./AnsiblePic
Ansible運維
第 1 章 Ansible 介紹及安裝
1.1 介紹
Ansible 是一個 IT 自動化工具频敛。它能配置系統(tǒng)、部署軟件屋讶、編排更復(fù)雜的 IT 任務(wù)诀紊,如連續(xù)部署或零停機時間滾動更新锦溪。Ansible 用 Python 編寫颤芬,盡管市面上已經(jīng)有很多可供選擇的配置管理解決方案(例如 Salt哩至、Puppet捕虽、Chef等),但它們各有優(yōu)劣,而Ansible的特點在于它的簡潔。讓 Ansible 在主流的配置管理系統(tǒng)中與眾不同的一點便是奥务,它并不需要你在想要配置的每個節(jié)點上安裝自己的組件物独。同時提供的另一個優(yōu)點,如果需要的話氯葬,你可以在不止一個地方控制你的整個基礎(chǔ)架構(gòu)挡篓。
1.2 工作原理
1、在ANSIBLE 管理體系中溢谤,存在"管理節(jié)點" 和 "被管理節(jié)點" 兩種角色瞻凤。
2、被管理節(jié)點通常被稱為"資產(chǎn)"
3世杀、在管理節(jié)點上,Ansible將 AdHoc 或 PlayBook 轉(zhuǎn)換為Python腳本肝集。并通過SSH將這些Python 腳本傳遞到
被管理服務(wù)器上瞻坝。在被管理服務(wù)器上依次執(zhí)行,并實時的將結(jié)果返回給管理節(jié)點杏瞻。
管理節(jié)點
確保存在OpenSSH
確保Python 版本 >= 2.6
確保安裝ansible
被管理節(jié)點
確保存在OpenSSH
確保Python 版本 >= 2.4 //若為2.4 版本所刀,確保安裝了python-samplesjson 擴展
不需要安裝ansible
安裝Ansible
# pip install ansible // 確保最新版本ansible 或者 pip3 install ansible
# yum -y install ansible // 不一定是最新版本ansible
確保管理節(jié)點與被管理節(jié)點之間SSH 信任關(guān)系
// 生成公私鑰對
# ssh-keygen -t rsa
# cd ~/.ssh && ls
id_rsa id_rsa.pub
// 將公鑰 id_rsa.pub copy 到 被管理服務(wù)器上 authorized_keys 文件中, 確保文件的權(quán)限為 0600
// managedhost 為被管理服務(wù)器捞挥,copy的過程中需要用戶名及密碼
# ssh-copy-id root@managedhost
1.4 快速入門
場景假設(shè)
管理節(jié)點:
192.168.122.130
被管理節(jié)點(資產(chǎn)):
192.168.122.129
192.168.122.131
且管理節(jié)點 和 被管理節(jié)點之間的節(jié)點已經(jīng)打通 SSH 信任關(guān)系浮创。
場景一
在管理節(jié)點上,確保同所有被管理節(jié)點的網(wǎng)絡(luò)連通性砌函。
# ansible all -i 192.168.122.129,192.168.122.131 -m ping
// 注意 -i 參數(shù)后面接的是一個列表(List)斩披。因此當(dāng)為一個被管理節(jié)點時,我們后面一定要加一個逗號(,)告知是List
# ansible all -i 192.168.122.129, -m ping
場景二
在管理節(jié)點上讹俊,確保文件/tmp/a.conf 發(fā)布到所有被管理節(jié)點
# ansible all -i 192.168.122.129,192.168.122.131 -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
參數(shù)解釋
-i // 指定Ansible 的資產(chǎn)垦沉,也就是被管理服務(wù)器。
-m // 指定要運行的模塊,比如這里的 ping 模塊和 copy 模塊
-a // 指定模塊的參數(shù), 這里模塊 ping 沒有指定參數(shù)仍劈。 模塊 copy 指定了 src 和 dest 參數(shù)
all // ansible 中厕倍, 將其叫做pattern , 即匹配。我通常稱它為資產(chǎn)選擇器贩疙。
// 就是匹配資產(chǎn)(-i 參數(shù)指定) 中的一部分讹弯。這里的 all 是匹配所有指定的所有資產(chǎn)。
// 在資產(chǎn)的章節(jié)中这溅,我們將詳細闡述组民。
第 2 章 Ansible 資產(chǎn)
在快速入門的場景中,我們一共管理了兩臺服務(wù)器芍躏。但是在實際場景中邪乍,我們要管理的服務(wù)器往往要多得多。難道依然要在Ansible 的 -i 參數(shù)后面一個個追加IP指定嗎? 這顯然不合乎常理。因此這一節(jié)我們主要去介紹一下Ansible的資產(chǎn)庇楞。Ansible 的資產(chǎn)分為靜態(tài)資產(chǎn)和動態(tài)資產(chǎn)榜配,下面我們將圍繞這兩部分分別介紹。
1.1 靜態(tài)資產(chǎn)
顧名思義它本身是一個文本文件吕晌,一個格式類似INI的文件蛋褥。默認情況下,Ansible的資產(chǎn)文件位于 /ect/ansible/hosts睛驳。我們這里給出一個自定義的靜態(tài)資產(chǎn)實例烙心,然后再具體解釋其含義。
# cat inventory
1.1.1.1
2.2.2.2
3.3.3.[1:15]
test01.qfedu.com
test03.qfedu.com
test[05:09].qfedu.com
[web-servers]
192.168.1.2
192.168.1.3
192.168.1.5
[db-servers]
192.168.2.2
192.168.2.3
192.168.1.5
[all-servers]
[all-servers:children]
db-servers
web-servers
1乏沸、Ansible 的資產(chǎn)文件中淫茵,可以以IP地址的形式或者主機名的形式存在
2、Ansible 的資產(chǎn)若連續(xù)蹬跃,可以使用[stat:end] 的形式去表達
3匙瘪、可以將服務(wù)器按照業(yè)務(wù)場景定義成組,比如db-servers 和 web-servers
4蝶缀、組和組之間可以存在繼承關(guān)系丹喻,比如db-servers 和 web-servers 同時繼承all-servers 組
如何使用自定義資產(chǎn)
// 通過 -i 參數(shù)指定自定義資產(chǎn)的位置即可(可以是全路徑,也可以是相對路徑)翁都。
# ansible all -i inventory.ini ... // 偽指令碍论,不可執(zhí)行
如何驗證自定義資產(chǎn)
// 假如我們剛剛定義的資產(chǎn)為 inventory.ini
// 列舉出所有資產(chǎn)
# ansible all -i inventory.ini --list-hosts
// 列舉出選定資產(chǎn),比如這里列舉出web-servers
// 注意這里使用的了資產(chǎn)選擇器(pattern)柄慰,我們將會在下面對他進行詳細的闡述
# ansible web-servers -i inventory.ini --list-hosts
// 以上指令鳍悠,若能列舉出我們在資產(chǎn)中定義的服務(wù)器,那么你的自定義資產(chǎn)也就生效了先煎。
1.2 動態(tài)資產(chǎn)
動態(tài)資產(chǎn), -i 參數(shù)后面接的是一個可運行的腳本贼涩。腳本的結(jié)果為一個 Ansible 可理解的 JSON 格式字符串。
為什么要存在動態(tài)資產(chǎn)呢? 往往我們在使用 Ansible 管理服務(wù)器前薯蝎,公司中有可能已經(jīng)將服務(wù)器信息存儲在了特定位置,比如 CMDB, 數(shù)據(jù)庫等系統(tǒng)遥倦。
此時若我們再使用靜態(tài)資產(chǎn)去管理服務(wù)器,勢必會造成資產(chǎn)管理入口不統(tǒng)一的問題占锯。
因此我們只能拋棄原先的靜態(tài)資產(chǎn)袒哥,通過腳本從已存在的系統(tǒng)中獲取要管理的節(jié)點,并按照特定的形>式傳給 Ansible消略。這樣既解決了公司資產(chǎn)統(tǒng)一入口堡称, 也解決了Ansible 的服務(wù)器管理來源。
動態(tài)資產(chǎn)實例
{
"_meta": {
"hostvars": {
"192.168.100.10": {
"host_var": "hoge"
},
"192.168.100.20": {
"host_var": "fuga"
}
}
},
"sample-servers": {
"hosts": [
"192.168.100.10",
"192.168.100.20"
],
"vars": {
"group_var": "hogefuga"
}
}
}
1.3 資產(chǎn)選擇器
有時操作者希望只對資產(chǎn)中的一部分服務(wù)器進行操作艺演,而不是資產(chǎn)中列舉的所有服務(wù)器却紧。此時我們該如何選擇呢桐臊?
這里我們將學(xué)習(xí) Ansible 的資產(chǎn)選擇器 PATTERN,通過資產(chǎn)選擇器晓殊,我們可以靈活的選擇想要操作的服務(wù)器断凶。
格式
# ansible PATTERN -i inventory -m module -a argument // 偽代碼,勿執(zhí)行
選擇一臺或者幾臺服務(wù)器
# ansible 1.1.1.1 -i inventory.ini --list-hosts
# ansible test01.qfedu.com -i inventory.ini --list-hosts
# ansible 1.1.1.1,2.2.2.2 -i inventory.ini --list-hosts
選擇所有服務(wù)器
# ansible '*' -i inventory.ini --list-hosts
# ansible all -i inventory.ini --list-hosts
選擇一組服務(wù)器
# ansible web-servers -i inventory.ini --list-hosts
使用 * 匹配
# ansible 3.3.3.* -i inventory.ini --list-hosts
使用邏輯匹配
// web-servers 和 db-servers 的并集
# ansible 'web-servers:db-servers' -i inventory.ini --list-hosts
// web-servers 和 db-servers 的交集
# ansible 'web-servers:&db-servers' -i inventory.ini --list-hosts
// 在 web-servers 中巫俺, 但不在 db-servers 的服務(wù)器
# ansible 'web-servers:!db-servers' -i inventory.ini --list-hosts
第 3 章 Ansible Ad-Hoc
3.1 命令格式
我們在快速入門中執(zhí)行的Ansible 命令认烁,類似于我們的批處理命令。在Ansible 中統(tǒng)稱為Ansible Ad-Hoc介汹。
其命令語法格式如下:
ansible pattern [-i inventory] -m module -a argument
pattern, 資產(chǎn)選擇器
-i , 指定資產(chǎn)的位置
-m , 指定本次Ansible ad-hoc 要執(zhí)行的模塊却嗡。可以類別成SHELL 中的命令嘹承。
-a , 模塊的參數(shù). 可以類比成SHELL 中的命令參數(shù)
Example
// 快速入門的實例
# ansible all -i 192.168.122.129,192.168.122.131 -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
3.2 模塊類型
Ansible 模塊分三種類型: 核心模塊(core module)窗价、附加模塊(extra module)及用戶自定義模塊(consume module)。
核心模塊是由Ansible 的官方團隊提供的赶撰。
附加模塊是由各個社區(qū)提供的舌镶。例如: OPENSTACK 社區(qū)、DOCKER 社區(qū)等等豪娜。
當(dāng)核心模塊和附加模塊都無法滿足你的需求時,用戶可以自定義模塊哟楷。
默認情況下瘤载,在安裝Ansible 的時候, 核心模塊和附加模塊都已經(jīng)安裝而無需用戶干預(yù)卖擅。
3.3 聯(lián)機幫助
Ansible 的核心模塊和附加模塊鸣奔,數(shù)量有1000+ 。這樣龐大的模塊數(shù)量惩阶,對于任何一個接觸Ansible 的人都不可能將其完全記住挎狸、掌握使用。 因此能夠順利使用Ansible 的幫助文檔断楷,對我們來說是很有必要的锨匆。Ansible 的幫助文檔,由
它本身提供的命令 ansible-doc 實現(xiàn)冬筒。
常用幫助參數(shù)
// 列舉出所有的核心模塊和附加模塊
# ansible-doc -l
// 查詢某個模塊的使用方法
# ansible-doc modulename
// 查詢某個模塊的使用方法恐锣,比較簡潔的信息
# ansible-doc -s modulename
// Example
# ansible-doc yum
# ansible-doc -s yum
3.4 常用模塊
command & shell 模塊
兩個模塊都是在遠程服務(wù)器上去執(zhí)行命令。但command模塊是ad-hoc的默認模塊,在執(zhí)行ad-hoc時,若不指定模塊的名字則默認使用此模塊.常用參數(shù)如下:
command & shell
- chdir 在運行命令之前舞痰,切換到此目錄土榴。
- executable 更改用于執(zhí)行命令的shell(bash,sh)响牛,需要是可執(zhí)行文件的絕對路徑玷禽。
Example
// ad-hoc 默認在不指定 -m 參數(shù)的時候赫段, 使用了默認的command 模塊
# ansible all -i inventory -a "ls /root"
# ansible all -i inventory -m command -a "ls /root" //等同第一個命令
# ansible all -i inventory -m shell -a "ls /root"
兩個模塊功能類似的模塊又存在的必要嗎? 他們之間的差異在哪里?
shell 模塊可以執(zhí)行SHELL 的內(nèi)置命令
command 模塊無法執(zhí)行SHELL 的內(nèi)置命令
如何檢測那些命令是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
Example2
# ansible all -i localhost, -c local -a "set"
localhost | FAILED | rc=2 >>
[Errno 2] 沒有那個文件或目錄
// -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é)點上的腳本傳遞到遠程服務(wù)器上進行執(zhí)行矢赁,理論上此模塊的執(zhí)行完全不需要被管理服務(wù)器上有Python糯笙。
Example
// 管理節(jié)點上的一個腳本
# cat /root/a.sh
#/bin/bash
touch /tmp/testfile
# ansible all -i inventory -m script -a "/root/a.sh"
copy 模塊
copy 模塊的主要用于管理節(jié)點和被管理節(jié)點之間的文件拷貝。經(jīng)常使用到的參數(shù)如下:
- src 指定拷貝文件的源地址
- dest 指定拷貝文件的目標地址
- backup 拷貝文件前坯台,若原始文件發(fā)生變化炬丸,則對目標文件進行備份
- woner 指定新拷貝文件的所有者
- group 指定新拷貝文件的所有組
- mode 指定新拷貝文件的權(quán)限
Example
// copy 管理節(jié)點上的/tmp/a.conf 到被管理節(jié)點上
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
// copy 前, 在被管理節(jié)點上對原文件進行備份
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf backup=yes"
// copy 文件的同時對文件進行用戶及用戶組設(shè)置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf owner=nobody group=nobody"
// copy 文件的同時對文件進行權(quán)限設(shè)置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf mode=0755"
service 模塊
管理遠程節(jié)點上的服務(wù)蜒蕾。類似于Linux上的service命令稠炬。常用參數(shù)如下:
– enabled 是否開機啟動 yes|no
– name 必選項,服務(wù)名稱
– runlevel 運行級別
– sleep 如果執(zhí)行了restarted咪啡,在則stop和start之間沉睡幾秒鐘
– state 對當(dāng)前服務(wù)執(zhí)行啟動首启,停止、重啟撤摸、重新加載等操作(started,stopped,restarted,reloaded)
注意:
使用 service 模塊時, enabled 和 state 參數(shù)至少要指定一個毅桃。
使用 service 模塊管理的服務(wù),必須在系統(tǒng)中存在 /etc/init.d/XXX 對應(yīng)的服務(wù)准夷。
比如若管理Nginx 服務(wù)钥飞,則應(yīng)該存在 /etc/init.d/nginx
Example
// 啟動 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è)置開機自啟動
# ansible all -i inventory -m service -a "name=nginx enabled=yes"
systemd 模塊
管理遠程節(jié)點上的 systemd 服務(wù),就是由 systemd 所管理的服務(wù)衫嵌。常用參數(shù)如下:
- daemon_reload 重新載入 systemd读宙,掃描新的或有變動的單元
– enabled 是否開機啟動 yes|no
– name 必選項,服務(wù)名稱
– state 對當(dāng)前服務(wù)執(zhí)行啟動楔绞,停止结闸、重啟、重新加載等操作(started,stopped,restarted,reloaded)
Example
// 重新加載 systemd
# ansible all -i inventory -m systemd -a "daemon_reload=yes"
// 啟動 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è)置開機自啟動
# ansible all -i inventory -m systemd -a "name=mariadb enabled=yes"
yum 模塊
等同于 Linux 上的YUM 命令酒朵, 對遠程服務(wù)器上RPM包進行管理桦锄。常用參數(shù)如下:
- name 要安裝的軟件包名, 多個軟件包以逗號(,) 隔開
- state 對當(dāng)前指定的軟件安裝蔫耽、拆卸操作(present installed latest absent removed)
安裝參數(shù) present installed latest
拆卸參數(shù) absent removed
Example
// 安裝一個軟件包
# 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"
// 拆卸一個軟件包
# ansible all -i inventory -m yum -a "name=nginx state=absent"
# ansible all -i inventory -m yum -a "name=nginx state=removed"
// 安裝一個軟件包組
# ansible all -i inventory -m yum -a "name='@Development tools' state=present"
group 模塊
在被管理節(jié)點上结耀,對組進行管理。 常用參數(shù)如下:
- name 組名稱针肥, 必須的
- system 是否為系統(tǒng)組, yes/no
Example
// 創(chuàng)建普通組 db_admin
# ansible all -i 172.16.153.160, -m group -a "name=db_admin"
user 模塊
用于在被管理節(jié)點上對用戶進行管理饼记。常用參數(shù)如下:
- name 必須的參數(shù), 指定用戶名
- password 設(shè)置用戶的密碼慰枕,這里接受的是一個加密的值具则,因為會直接存到 shadow
- update_password 假如設(shè)置的密碼不同于原密碼,則會更新密碼. 在 1.3 中被加入
- home 指定用戶的家目錄
- shell 設(shè)置用戶的 shell
- uid 指定用戶的 UID
- comment 用戶的描述信息
- create_home 在創(chuàng)建用戶時具帮,是否創(chuàng)建其家目錄博肋。默認創(chuàng)建低斋,假如不創(chuàng)建,設(shè)置為 no匪凡。2.5版本之前
使用 createhome
- group 設(shè)置用戶的主組
- groups 將用戶加入到多個組中膊畴,多個用逗號隔開,也可以是個列表
- system 設(shè)置為 yes 時病游,將會創(chuàng)建一個系統(tǒng)賬號
- expires 設(shè)置用戶的過期時間唇跨,值為時間戳,會轉(zhuǎn)為為天數(shù)后,放在 shadow 的最后一個字段里
- generate_ssh_key 設(shè)置為 yes 將會為用戶生成密鑰衬衬,這不會覆蓋原來的密鑰
- ssh_key_type 指定用戶的密鑰類型买猖, 默認 rsa, 具體的類型取決于被管理節(jié)點
- remove 當(dāng)與 state=absent 一起使用,刪除一個用戶及其家目錄滋尉,可選的值為: yes/no
Example
// 生成加密的密碼
# echo test |openssl passwd -1 -stdin
// 創(chuàng)建一個用戶 nginx, 指定其 shell 為 nologin
# ansible all -i inventory -m user -a "name=nginx shell=/sbin/nologin"
// 創(chuàng)建用戶 yangge, 并且為其創(chuàng)建密鑰對玉控,并且密鑰類型為: ecdsa
# ansible all -i inventory -m user -a "name=yangge generate_ssh_key=yes ssh_key_type=ecdsa"
// 創(chuàng)建用 tom, 并且設(shè)置其有效期到 2019年8月16日, 加入到組 db_admin 中
# timestamp=$(date +%s -d 20180725)
// 或者
# 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 天后過期
# ansible all -i 172.16.153.160, -m user -a "name=tom expires=$(echo $((86400 * 31))) groups=db_admin,"
date 命令說明
// 計算 3 小時之后是幾點幾分
# date +%T -d '3 hours'
// 任意日期的前 N 天,后 N 天的具體日期
# date +%F -d "20190910 1 day"
# date +%F -d "20190910 -1 day"
// 計算兩個日期相差天數(shù), 比如計算生日距離現(xiàn)在還有多少天
# d1=$(date +%s -d 20180728)
# d2=$(date +%s -d 20180726)
# echo $(((d1-d2)/86400))
file 模塊
file 模塊主要用于遠程主機上的文件操作狮惜,經(jīng)常使用的模塊參數(shù)如下:
- group 定義文件/目錄的屬組
- mode 定義文件/目錄的權(quán)限
- owner 定義文件/目錄的屬主
- path 必選項高诺,定義文件/目錄的路徑
- recurse 遞歸的設(shè)置文件的屬性,只對目錄有效
- src 要被鏈接(軟/硬)的源文件的路徑碾篡,只應(yīng)用于state=link的情況
- dest 被鏈接到的路徑虱而,只應(yīng)用于state=link的情況
- state
?? directory 如果目錄不存在,創(chuàng)建目錄
?? file 文件不存在开泽,則不會被創(chuàng)建薛窥,存在則返回文件的信息,常用于檢查文件是否存在眼姐。
?? link 創(chuàng)建軟鏈接
?? hard 創(chuàng)建硬鏈接
?? touch 如果文件不存在,則會創(chuàng)建一個新的文件佩番,如果文件或目錄已存在众旗,則更新其最后修改時間
?? absent 刪除目錄、文件或者取消鏈接文件
Example
// 創(chuàng)建一個文件
# 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)建一個軟連接
# ansible all -i inventory -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
// 創(chuàng)建一個目錄
# ansible all -i inventory -m file -a "path=/tmp/testdir state=directory"
// 取消一個連接
# ansible all -i inventory -m file -a "path=/tmp/link.conf state=absent"
// 刪除一個文件
# ansible all -i inventory -m file -a "path=/tmp/foo.conf state=absent"
cron 模塊
管理遠程節(jié)點的CRON 服務(wù)趟畏。等同于Linux 中的CRON贡歧。 常用命令如下:
- name 指定一個cron job 的名字。一定要指定赋秀,便于日之后刪除利朵。
- minute 指定分鐘,可以設(shè)置成(0-59, *, */2 等)格式猎莲。 默認是 * , 也就是每分鐘绍弟。
- hour 指定小時,可以設(shè)置成(0-23, *, */2 等)格式著洼。 默認是 * , 也就是每小時樟遣。
- day 指定天而叼, 可以設(shè)置成(1-31, *, */2 等)格式。 默認是 * , 也就是每天豹悬。
- month 指定月份葵陵, 可以設(shè)置成(1-12, *, */2 等)格式。 默認是 * , 也就是每周瞻佛。
- weekday 指定星期脱篙, 可以設(shè)置成(0-6 for Sunday-Saturday, * 等)格式。默認是 *伤柄,也就是每星期绊困。
- job 指定要執(zhí)行的內(nèi)容,通诚煊兀可以寫個腳本考抄,或者一段內(nèi)容。
- state 指定這個job的狀態(tài)蔗彤,可以是新增(present)或者是刪除(absent)川梅。 默認為新增(present)
Example
// 新建一個 CRON JOB 任務(wù)
# ansible all -i inventory -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
// 刪除一個 CRON JOB 任務(wù),刪除時然遏,一定要正確指定job 的name參數(shù)贫途,以免誤刪除。
# ansible all -i inventory -m cron -a "name='create new job' state=absent"
登錄任何一臺管理機驗證cron
# crontab -l
#Ansible: create new job
0 * * * * ls -alh > /dev/null
debug模塊
debug 模塊主要用于PlayBook調(diào)試時使用待侵,通常的作用是將一個變量的結(jié)果打印出來丢早。常用參數(shù)如下:
- var 直接打印一個指定的變量值
- msg 打印一段可以格式化的字符串
Example
// 這里引入了變量,我們只需了解 debug 模板的使用即可秧倾。在學(xué)習(xí)變量怨酝、劇本時,我們會對它有更深刻的理解那先。
# 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格式作為文件模版农猬,可以進行文檔內(nèi)變量的替換。
它的每次使用都會被ansible標記為”changed”狀態(tài)售淡。文件以 .j2 結(jié)尾
模塊常用參數(shù)如下:
- backup 創(chuàng)建一個包含時間戳信息的備份文件斤葱,這樣如果您以某種方式錯誤地破壞了原始文件,
就可以將其恢復(fù)原狀揖闸。yes/no
- force 默認值是yes揍堕,當(dāng)內(nèi)容與源不同時,它將替換遠程文件汤纸。如果no衩茸,僅在目標不存在時才傳輸文件。
- src 指定 Ansible 控制端的 文件路徑
- dest 指定 Ansible 被控端的 文件路徑
- owner 指定文件的屬主
- group 指定文件的屬組
- mode 指定文件的權(quán)限
- newline_sequence 指定新文件的換行符; \n蹲嚣,\r, 或 \r\n
內(nèi)置變量
ansible_managed - 包含一個字符串递瑰,可用于描述模板名稱祟牲,主機,模板文件的修改時間和所有者的uid
template_host - 包含模板機器的節(jié)點名稱
template_uid - 所有者的uid
template_path - 模版路徑
template_fullpath - 模版的絕對路徑
template_run_date - 模版呈現(xiàn)的時間
Example
// 把本地的當(dāng)前目錄下的 jinja2 模板文件 foo.j2 傳送到目標機器上抖部,并指定屬主為 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"
// 上面的用法其實和 copy 模塊一樣说贝,下面我們就來介紹 template 模塊的強大之處
1. 建立一個 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. 在被控主機上驗證
# cat /tmp/hello_world.world
Hello world !
所有模塊列表 https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html
模塊按照首字母排序
第 4 章 Ansible 劇本
通過對 AD-HOC 的學(xué)習(xí)慎颗,我們發(fā)現(xiàn) AD-HOC 每次只能在被管理節(jié)點上執(zhí)行簡單的命令乡恕。而日常工作中,我們往往面臨的是一系列的復(fù)雜操作俯萎,例如我們有可能需要安裝軟件傲宜、更新配置、啟動服務(wù)等等一系列操作的結(jié)合夫啊。此時再通過 AD-HOC 去完成任務(wù)就有些力不從心了函卒。在這種場景下,Ansible引進了 PLAYBOOK 來幫忙我們解決這樣復(fù)雜問題撇眯。
4.1 PlayBook是什么
Playbook 也通常被大家翻譯成劇本报嵌。可以認為它是Ansible 自定義的一門語言(可以將 Playbook 比作 Linux 中的 shell熊榛,而 Ansible 中的 Module 可以比作為 Linux 中的各種命令锚国。通過這樣的類比扼褪,我們對PlayBook就有了一個更形象的認識了)概页。既然 Playbook 是一門語言,那么它遵循什么樣的語法格式? 有哪些語言呢性? 我們將通過下面的學(xué)習(xí)逐步了解消恍。
4.2 YAML 學(xué)習(xí)
PlayBook遵循YAML 的語法格式煎楣。 因此在學(xué)習(xí)PlayBook之前豺总,我們必須要先弄明白YAML 相關(guān)知識點。
YAML特點
YAML 文件以 # 為注釋符
YAML 文件以 .yml 或者.yaml 結(jié)尾
YAML 文件以 --- 開始 , 以 ... 結(jié)束, 但開始和結(jié)束標志都是可選的
基本語法
大小寫敏感
使用縮進表示層級關(guān)系
縮進時是使用Tab鍵還是使用空格一定要達到統(tǒng)一择懂,建議使用空格园欣。
相同層級的元素必須左側(cè)對齊即可
YAML 支持的數(shù)據(jù)結(jié)構(gòu)有三種: 字符串、列表休蟹、字典。
字符串
---
# YAML 中的字符串可以不使用引號日矫,即使里面存在空格的時候赂弓,當(dāng)然了使用單引號和雙引號也沒有錯。
this is a string
'this is a string'
"this is a string"
# YAML 中若一行寫不下你要表述的內(nèi)容哪轿,可以進行折行盈魁。寫法如下:
long_line: |
Example 1
Example 2
Example 3
# 或者
long_line: >
Example 1
Example 2
Example 3
...
列表
---
# 若熟悉 Python 的話, 可以認為它就是Python中的List ,若熟悉 C 語言的話窃诉, 可以認為它是 C 中的數(shù)組杨耙。
# 如何定義: 以短橫線開頭 + 空格 + 具體的值
- red
- green
- blue
# 以上的值假如轉(zhuǎn)換成 python 的 List 會是這樣:
# ['red', 'green', 'blue']
...
字典
---
# 若熟悉Python 的話赤套, 可以認為它就是Python中的 Dict
# 如何定義: key + 冒號(:) + 空格 + 值(value), 即 key: value
name: Using Ansible
code: D1234
# 轉(zhuǎn)換為 python 的 Dict
# {'name': 'Using Ansibel', 'code': 'D1234'}
...
混合結(jié)構(gòu)
以上,針對YAML 的所有基礎(chǔ)知識點就介紹完了。但在日常生活中珊膜,往往需要的數(shù)據(jù)結(jié)構(gòu)會特別復(fù)雜容握,有可能會是字符串、列表车柠、字典的組合形式剔氏。 這里舉一個小例子:
所有人都上過學(xué),都知道到學(xué)校里是以班級為單位竹祷。我們?nèi)ナ褂昧斜砗妥值涞男问饺ッ枋鲆粋€班級的組成谈跛。
---
class:
- name: stu1
num: 001
- name: stu2
num: 002
- name: stu3
num: 003
# {'class': [{'name': 'stu1', 'num': 1},{'name': 'stu2', 'num': 2},...]}
...
驗證YAML 語法
// 將YAML文件,通過Python 的YAML 模塊驗證塑陵, 若不正確則報錯感憾。若正確則會輸出YAML 里的內(nèi)容。
// 注意使用時令花,一定確保安裝了yaml 軟件包阻桅。
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
python3 -c 'import yaml,sys; print(yaml.load(sys.stdin))' < myyaml.yml
Example
// 正確的情況
# cat myyaml.yml
---
- red
- green
- blue
...
# python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
['red', 'green', 'blue']
// 錯誤的情況, 將YAML文件寫錯
# cat myyaml.yml
---
- red
- green
-blue
...
# python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/usr/local/lib/python2.7/site-packages/yaml/constructor.py", line 37, in get_single_data
node = self.get_single_node()
...
...
4.3 Play 定義
由于Playbook 是由一個或者多個Play組成,那么如果我們熟悉Play 的寫法彭则,就自然掌握了我們這章的PlayBook鳍刷。
那如何定義一個Play呢
1、每一個Play 都是以短橫杠開始的
2俯抖、每一個Play 都是一個YAML 字典格式
根據(jù)上面兩條Play 的規(guī)則输瓜,一個假想的 Play 應(yīng)該是如下的樣子
---
- key1: value1
key2: value2
key3: value3
...
...
由于一個Playbook 是由一個或者多個Play構(gòu)成, 那么一個含有多個Play的Playbook 結(jié)構(gòu)上應(yīng)該是如下的樣子
---
# 一個含有3個Play 的偽PlayBook構(gòu)成
- key1: value1
key2: value2
key3: value3
- key4: value1
key5: value2
key6: value3
- key1: value1
key2: value2
key3: value3
...
4.4 Play 屬性
以上一小節(jié)中的Play為基礎(chǔ), Play中的每一個key, key1芬萍、key2尤揣、key3等;這些key在PlayBook中被定義為Play的屬性柬祠。這些屬性都具有特殊的意義,我們不能隨意的自定義Play 的屬性北戏。那么Ansible本身都支持哪些Play屬性呢
常用屬性
(1)、name 屬性漫蛔, 每個play的名字
(2)嗜愈、hosts 屬性, 每個play 涉及的被管理服務(wù)器,同ad hoc 中的patten
(3)莽龟、tasks 屬性, 每個play 中具體要完成的任務(wù)蠕嫁,以列表的形式表達
(4)、become 屬性毯盈,如果需要提權(quán)剃毒,則加上become 相關(guān)屬性
(5)、become_user 屬性, 若提權(quán)的話,提權(quán)到哪個用戶上
(6)赘阀、remote_user屬性益缠,指定連接用戶。若不指定基公,則默認使用當(dāng)前執(zhí)行 ansible Playbook 的用戶
4.5 一個完整劇本
根據(jù)上一小節(jié)中介紹的真實的屬性幅慌,一個含有一個Play 的 Playbook 應(yīng)該是如下的樣子
---
- name: the first play example
hosts: all
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
tasks 屬性中任務(wù)的多種寫法
# 以啟動 nginx 服務(wù),并增加開機啟動為例
# 一行的形式:
service: name=nginx enabled=true state=started
# 多行的形式:
service: name=nginx
enabled=true
state=started
# 多行寫成字典的形式:
service:
name: nginx
enabled: true
state: started
具有多個Play 的Playbook
---
- name: manage web servers
hosts: web-servers
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
- name: manager db servers
hosts: db-servers
tasks:
- name: update database confg
copy: src=my.cnf dest=/etc/my.cnf
如何對Playbook 進行語法校驗
// 因為PlayBook 屬于YAML 格式酌媒, 我們同樣可以使用檢查YAML的語法格式的方法進行檢查PlayBook的語法正確性欠痴。
// 此形式的校驗,只能校驗PlayBook是否正確秒咨,而不能校驗YAML文件是否語法正確喇辽。
# ansible-playbook myplaybook.yml --syntax-check
如何運行PlayBook
# ansible-playbook myplaybook.yml
如何單步跟從調(diào)試PlayBook
// 執(zhí)行Task中的任務(wù),需要手動確認是否往下執(zhí)行雨席。
# ansible-playbook myplaybook.yml --step
如何測試運行PlayBook
// 會執(zhí)行完整個PlayBook ,但是所有Task中的行為都不會在遠程服務(wù)器上執(zhí)行菩咨,所有執(zhí)行都是模擬行為。
# ansible-playbook myplaybook.yml -C
// -C 為大寫的字母 C
第 5 章 Ansible 變量
我們在PlayBook一節(jié)中陡厘,將PlayBook類比成了Linux中的shell抽米。那么它作為一門Ansible特殊的語言,肯定要涉及到變量定義糙置、控制結(jié)構(gòu)的使用等特性云茸。在這一節(jié)中主要討論變量的定義和使用。
變量命名規(guī)則
變量的名字由字母谤饭、下劃線和數(shù)字組成标捺,以字母開頭。
如下變量命名為正確:
good_a OK
ok_b OK
如下變量命名為錯誤:
_aaa FAIL
2_bb FAIL
保留關(guān)鍵字不能作為變量名稱
add, append, as_integer_ratio, bit_length, capitalize, center, clear, conjugate, copy, count, decode, denominator, difference, difference_update, discard, encode, endswith, expandtabs, extend, find, format, fromhex, fromkeys, get, has_key, hex, imag, index, insert, intersection, intersection_update, isalnum, isalpha, isdecimal, isdigit, isdisjoint, is_integer, islower, isnumeric, isspace, issubset, issuperset, istitle, isupper, items, iteritems, iterkeys, itervalues, join, keys, ljust, lower, lstrip, numerator, partition, pop, popitem, real, remove, replace, reverse, rfind, rindex, rjust, rpartition, rsplit, rstrip, setdefault, sort, split, splitlines, startswith, strip, swapcase, symmetric_difference, symmetric_difference_update, title, translate, union, update, upper, values, viewitems, viewkeys, viewvalues, zfill