公司計划在年底做一次大型市場促銷活動,全面沖刺下交易額,為明年的上市做准備。公司要求各業務組對年底大促做准備,運維部要求所有業務容量進行三倍的擴容,並搭建出多套環境可以共開發和測試人員做測試,運維老大為了在年底有所表現,要求運維部門同學盡快實現,當你接到這個任務時,有沒有更快的解決方案?
一、簡單介紹
1、定義:
ansible是新出現的自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。
ansible是基於 paramiko(框架) 開發的,並且基於模塊化工作,本身沒有批量部署的能力。真正具有批量部署的是ansible所運行的模塊,ansible只是提供一種框架。ansible不需要在遠程主機上安裝client/agents,因為它們是基於ssh來和遠程主機通訊的。ansible目前已經已經被紅帽官方收購,是自動化運維工具中大家認可度最高的,並且上手容易,學習簡單。是每位運維工程師必須掌握的技能之一。

2、ansible 特點
1)部署簡單,只需在主控端部署Ansible環境,被控端無需做任何操作,沒有agent;
2) 默認使用SSH協議對設備進行管理;
3) 有大量常規運維操作模塊,可實現日常絕大部分操作。
4) 配置簡單、功能強大、擴展性強;
5) 支持API及自定義模塊,可通過Python輕松擴展;
6) 通過Playbooks(劇本)來定制強大的配置、狀態管理;
7) 輕量級,無需在客戶端安裝agent,更新時,只需在操作機上進行一次更新即可;
8) 提供一個功能強大、操作性強的Web管理界面和REST API接口——AWX平台。
9)模塊化:調用特定的模塊,完成特定任務。
10)無需代理不依賴PKI(無需ssl)
11)冪等性:一個任務執行1遍和執行n遍效果一樣,不因重復執行帶來意外情況
12)可使用任何編程語言寫模塊
13)安全,基於OpenSSH
14)有Paramiko,PyYAML,Jinja2(模板語言)三個關鍵模塊
3、ansible架構

上圖為ansible的基本架構,從上圖可以了解到其由以下部分組成:
- 核心:ansible
- 核心模塊(Core Modules):這些都是ansible自帶的模塊
- 擴展模塊(Custom Modules):如果核心模塊不足以完成某種功能,可以添加擴展模塊
- 插件(Plugins):完成模塊功能的補充
- 劇本(Playbooks):ansible的任務配置文件,將多個任務定義在劇本中,由ansible自動執行
- 連接插件(Connectior Plugins):ansible基於連接插件連接到各個主機上,雖然ansible是使用ssh連接到各個主機的,但是它還支持其他的連接方法,所以需要有連接插件
- 主機群(Host Inventory):定義ansible管理的主機
4、工作原理:

Ansible主要組成部分
- ANSIBLE PLAYBOOKS:任務劇本(任務集),編排定義Ansible任務集的配置文件,由Ansible順序依次執行,通常是JSON格式的YML文件
- INVENTORY:Ansible管理主機的清單/etc/anaible/hosts
- MODULES:Ansible執行命令的功能模塊,多數為內置核心模塊,也可自定義
- PLUGINS:模塊功能的補充,如連接類型插件、循環插件、變量插件、過濾插件等,該功能不常用
- API:供第三方程序調用的應用程序編程接口
- ANSIBLE:組合INVENTORY、API、MODULES、PLUGINS的綠框,可以理解為是ansible命令工具,其為核心執行工具
- Ansible命令執行來源:
USER,普通用戶,即SYSTEM ADMINISTRATOR CMDB(配置管理數據庫) API 調用 PUBLIC/PRIVATE CLOUD API調用 USER-> Ansible Playbook -> Ansibile
8. 利用ansible實現管理的方式:
1、Ad-Hoc 即ansible命令,主要用於臨時命令使用場景 2、Ansible-playbook 主要用於長期規划好的,大型項目的場景,需要有前提的規划9)Ansible-playbook(劇本)執行過程: 3、將已有編排好的任務集寫入Ansible-Playbook 4、通過ansible-playbook命令分拆任務集至逐條ansible命令,按預定規則逐條執行
9. Ansible主要操作對象:
HOSTS主機 NETWORKING網絡設備
注意事項
執行ansible的主機一般稱為主控端,中控,master或堡壘機 主控端Python版本需要2.6或以上 被控端Python版本小於2.4需要安裝python-simplejson 被控端如開啟SELinux需要安裝libselinux-python windows不能做為主控端
5、ansible 任務執行模式
Ansible系統由控制主機對被管節點的操作方式可分為兩類,即ad-hoc和playbook:
·ad-hoc(點對點)模式:使用單個模塊,支持批量執行單條命令。 ad-hoc 命令是一種可以快速輸入的命令,而且不需要保存起來的命令。就相當於bash中的一句話shell。
·playbook(劇本)模式:是Ansible主要管理方式,也是Ansible功能強大的關鍵所在。playbook通過多個task集合完成一類功能,如Web服務的安裝部署、數據庫服務器的批量備份等。可以簡單地把playbook理解為通過組合多條ad-hoc操作作的配置文件。
6、Ansible命令執行過程
ansible命令執行過程 1)加載自己的配置文件 默認/etc/ansible/ansible.cfg 2)查找對應的主機配置文件,找到要執行的主機或者組 3)加載自己對應的模塊文件,如command 4)通過ansible將模塊或命令生成對應的臨時py文件,並將該文件傳輸至遠程服務器端對應執行用戶的家目錄的.ansible/tmp/XXX/XXX.PY文件 5)給文件+x執行 6)執行並返回結果 7)刪除臨時py文件,sleep 0退出 執行狀態: 綠色:執行成功並且不需要做改變的操作 黃色:執行成功並且對目標主機做變更 紅色:執行失敗

實戰一:安裝ansible 及指令講解
1、安裝ansible
ansible安裝常用兩種方式,yum安裝和pip程序安裝
這里提供二種安裝方式,任選一種即可
(1)使用yum 安裝
yum install ansible –y
(2)使用pip :pip是安裝Python包的管理器,類似yum
pip install ansible 如果沒pip,需先安裝pip.yum可直接安裝:
yum install python-pip
pip install ansible
確認安裝: ansible --version 查詢版本
2、Ansible配置文件
Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默認)
[defaults] #inventory = /etc/ansible/hosts # 主機列表配置文件 #library = /usr/share/my_modules/ # 庫文件存放目錄 #remote_tmp = $HOME/.ansible/tmp #臨時py命令文件存放在遠程主機目錄 #local_tmp = $HOME/.ansible/tmp # 本機的臨時命令執行目錄 #forks = 5 # 默認並發數 #sudo_user = root # 默認sudo用戶 #ask_sudo_pass = True #每次執行ansible命令是否詢問ssh密碼 #ask_pass = True #remote_port = 22 #host_key_checking = False # 檢查對應服務器的host_key,建議取消注釋 #log_path=/var/log/ansible.log #日志文件 #module_name = command #默認模塊
① sudo_user:
這是設置默認執行命令的用戶,也可以在playbook中重新設置這個參數。配置實例如下:
sudo_user = root
② remote_port:
這是指定連接被管節點的管理端口,默認是22。除非設置了特殊的SSH端口,不然這個參數一般是 不需要修改的。配置實例如下:
remote_port = 22
③ host_key_checking:
這是設置是否檢查SSH主機的密鑰。可以設置為True或False,關閉后第一次連接沒有提示配置實例
host_key_checking = False
④ timeout:
這是設置SSH連接的超時間隔,單位是秒。配置實例如下:
timeout = 60
log_path:Ansible系統默認是不記錄日志的,如果想把Ansible系統的輸出記錄到日志文件中,需要設置log_path 來指定一個存儲Ansible日志的文件。配置實例如下:
log_path = /var/log/ansible.log
另外需要注意,執行Ansible的用戶需要有寫入日志的權限,模塊將會調用被管節點的syslog來記錄
3、配置文件、程序及命令:
配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性 /etc/ansible/hosts 主機清單 /etc/ansible/roles/ 存放角色的目錄
程序
/usr/bin/ansible 主程序,臨時命令執行工具 /usr/bin/ansible-doc 查看配置文檔,模塊功能查看工具 /usr/bin/ansible-galaxy 下載/上傳優秀代碼或Roles模塊的官網平台 /usr/bin/ansible-playbook 定制自動化任務,編排劇本工具/usr/bin/ansible-pull 遠程執行命令的工具 /usr/bin/ansible-vault 文件加密工具 /usr/bin/ansible-console 基於Console界面與用戶交互的執行工具
ansible系列命令
ansible
ansible-doc
ansible-playbook 定制任務,編排劇本
ansible-galaxy
連接 https://galaxy.ansible.com 下載相應的roles 列出所有已安裝的galaxy ansible-galaxy list 安裝galaxy ansible-galaxy install geerlingguy.redis 刪除galaxy ansible-galaxy remove geerlingguy.redis
ansible-vault
功能:管理加密解密yml文件 ansible-vault [create|decrypt|edit|encrypt|rekey|view] ansible-vault encrypt hello.yml 加密 ansible-vault decrypt hello.yml 解密 ansible-vault view hello.yml 查看 ansible-vault edit hello.yml 編輯加密文件 ansible-vault rekey hello.yml 修改口令 ansible-vault create new.yml 創建新文件
ansible-console: 2.0+新增,可交互執行命令,支持tab
root@test (2)[f:10] $ 執行用戶@當前操作的主機組 (當前組的主機數量)[f:並發數]$ 設置並發數: forks n 例如: forks 10 切換組: cd 主機組 例如: cd web 列出當前組主機列表: list 列出所有的內置命令: ?或help 示例: root@all (2)[f:5]$ list root@all (2)[f:5]$ cd appsrvs root@appsrvs (2)[f:5]$ list root@appsrvs (2)[f:5]$ yum name=httpd state=present root@appsrvs (2)[f:5]$ service name=httpd state=started
ansible-pull 推送命令至遠程,效率無限提升,對運維要求較高
ansible-doc: 顯示模塊幫助
ansible-doc [options] [module...]
-a 顯示所有模塊的文檔 -l, --list 列出可用模塊 -s, --snippet顯示指定模塊的playbook片段
示例:
ansible-doc –l 列出所有模塊 ansible-doc ping 查看指定模塊幫助用法 ansible-doc –s ping 查看指定模塊幫助用法
ansible通過ssh實現配置管理、應用部署、任務執行等功能,建議配置ansible端能基於
密鑰認證的方式聯系各被管理節點
ansible <host-pattern> [-m module_name] [-a args]
--version 顯示版本 -m module 指定模塊,默認為command -v 詳細過程 –vv -vvv更詳細 --list-hosts 顯示主機列表,可簡寫 --list -k, --ask-pass 提示輸入ssh連接密碼,默認Key驗證 -K, --ask-become-pass 提示輸入sudo時的口令 -C, --check 檢查,並不執行 -T, --timeout=TIMEOUT 執行命令的超時時間,默認10s -u, --user=REMOTE_USER 執行遠程執行的用戶 -b, --become 代替舊版的sudo 切換 --become-user=USERNAME 指定sudo的runas用戶,默認為root
4、ansible的Host-pattern
匹配主機的列表
All :表示所有Inventory中的所有主機
- ansible all -m ping
* :通配符
- ansible “*” -m ping #其中*代表的意思就是all,所有的IP地址
- ansible 192.168.1.* -m ping #匹配1.*的IP地址
- ansible “*srvs” -m ping
或關系
- ansible “websrvs:appsrvs” -m ping #或關系,取IP地址的並集
- ansible “192.168.1.10:192.168.1.20” -m ping
- ansible的Host-pattern
邏輯與
- ansible “websrvs:&dbsrvs” -m ping #與關系,取IP地址的交集
- 在websrvs組並且在dbsrvs組中的主機
邏輯非
- ansible ‘websrvs:!dbsrvs’ -m ping #在websrvs中,取dbsrvs的反
- 在websrvs組,但不在dbsrvs組中的主機
- 注意:此處為單引號
綜合邏輯
- ansible ‘websrvs:dbsrvs:&appsrvs:!ftpsrvs’ -m ping
正則表達式
- ansible “websrvs:&dbsrvs” -m ping
- ansible “~(web|db).*\.magedu\.com” -m ping
5、ansible 使用前配置
(1)Ansible配置公私鑰
配置ansible 使用公鑰驗證
雖然ansible支持其他主機認證方式,但是我們最常用的的還是基於秘鑰的認證:
① 首先生成秘鑰
ssh-keygen -t rsa -P " " -f /root/.ssh/id_rsa
② 然后向主機分發秘鑰:
ssh-copy-id root@ #@后面跟主機名或者IP地址3、如果出現以下情況:
# ssh-copy-id -i root/.ssh/id_rsa.pub 10.1.6.72
-bash: ssh-copy-id: command not found
請嘗試: yum -y install openssh-clientsansible
(2)直接執行腳本批量將本地公鑰傳遞到對方主機:
vim iplist.txt 將對方的主機IP地址寫入 192.168.34.102 192.168.34.103 192.168.34.105
#!/bin/bash 書寫批量執行腳本
user=root
password=centos
ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa
while read ip ;do
expect <<EOF
set timeout 10
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect eof
EOF
done < iplist.txt
實戰二:ad-hoc(點對點)常用模塊
1、設置hosts 遠程被控制主機
vim /etc/ansible/hosts 在最底部寫入兩個組的內容,分別寫入遠程主機的IP地址 [webs] 192.168.34.102 192.168.34.103 [apps] 192.168.34.103 192.168.34.105
定義hosts 有3類:
① Ex 1:未分組的主機,在任何組頭之前指定
② Ex 2:有組的主機,一組屬於"webservers"組的主機
③ Ex 3:和數據庫有關的,"dbservers"組中的數據庫服務器集合

在最底部寫入遠程主機的IP地址:

2、ping 模塊,主機連通性測試
[root@ansibale~]#ansible all -m ping 嘗試ping對方主機地址,由於是基於key驗證,此時已經不需要輸入密碼。
192.168.34.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.34.103 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.34.105 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
3、Command 模塊
(1)介紹
命令模塊接受命令名稱,后面是空格分隔的列表參數。給定的命令將在所有選定的節點上執行,(此時command模塊是默認模塊,可忽略-m選項)。
它不會通過shell進行處理,比如$HOME和操作如"小於"<",">", "|", ";","&"' 工作(需要使用(shell)模塊實現這些功能)。
(2)選項
chdir # 在執行命令之前,先切換到該目錄 creates # 一個文件名,當這個文件存在,則該命令不執行,可以用來做判斷 removes # 一個文件名,這個文件不存在,則該命令不執行,與creates相反的判斷 executable # 切換shell來執行命令,需要使用命令的絕對路徑(不常用,常用下面shell 模塊) free_form # 要執行的Linux指令,一般使用Ansible的-a參數代替(不常用,常用下面shell 模塊)
(3)實例
ansible webs -m command -a 'chdir=/data ls'
[root@ansibaledata]#ansible webs -m command -a "chdir=/data ls" 可以切換到data目錄下執行ls命令 192.168.34.103 | CHANGED | rc=0 >> f1 192.168.34.102 | CHANGED | rc=0 >> f2 lost+found
ansible webs -m command -a 'creates=/data/f1 touch /data/f2'
[root@ansibaledata]#ansible webs -m command -a "creates=/data/f1 touch /data/f1" #在webs組主機里,如果兩個主機data下都有f1,就不會在data下創建f1 [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.34.102 | CHANGED | rc=0 >> 192.168.34.103 | SUCCESS | rc=0 >> skipped, since /data/f1 exists [root@ansibaledata]#ansible webs -m command -a "chdir=/data ls" #IP102的主機data下沒有f1,就會創建f1. 192.168.34.102 | CHANGED | rc=0 >> f1 f2 lost+found 192.168.34.103 | CHANGED | rc=0 >> f1
ansible webs -m command -a 'removes=/data/f1 touch /data/f2' data下有f1文件就會創建f2文件
[root@ansibaledata]#ansible webs -a "removes=/data/f1 touch /data/f2" #如果有f1文件就會進行創建f2 [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.34.102 | CHANGED | rc=0 >> 192.168.34.103 | CHANGED | rc=0 >> [root@ansibaledata]#ansible webs -a "chdir=/data/ ls" 查詢之前有f1,此時已經查到創建f2的結果 192.168.34.102 | CHANGED | rc=0 >> f1 f2 192.168.34.103 | CHANGED | rc=0 >> f1 f2
4、shell 模塊
shell模塊在遠程主機上調用shell解釋器運行命令,支持shell的各種功能,例如管道、echo等
在配置文件中將模塊進行修改,就不需要輸入-m shell選項,修改位置:
vim /etc/ansible/ansible.cfg module_name = shell
(1)實例:
ansible webs -m shell -a 'cat /etc/passwd |grep root'
[root@ansibaledata]#ansible webs -m shell -a "getent passwd | grep root" 192.168.34.102 | CHANGED | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin 192.168.34.103 | CHANGED | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@ansibaledata]#ansible webs -a "getent passwd | grep root" 由於是默認的shell模塊,不需要加-m shell 192.168.34.102 | CHANGED | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin 192.168.34.103 | CHANGED | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
5、script 模塊
在指定節點運行服務端的腳本
(1)示例,書寫腳本:
[root@Ansible ~]#vim test.sh
#/bin/bash
touch /data/test #創建/data/test
df -h >> /data/test #將df內容追加到/data/test文件中
ansible webs -m script -a '/data/test.sh' 在遠程被控制的機器執行腳本
ansible webs -m command -a "chdir=/data ls" 查看文件生成
ansible webs -m shell -a "cat /data/test 查看文件內容正確
[root@ansibaledata]#ansible webs -m script -a "/data/test.sh" 通過腳本創建文件及追加文件內容
192.168.34.102 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.34.102 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.34.102 closed."
],
"stdout": "",
"stdout_lines": []
}
192.168.34.103 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.34.103 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.34.103 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@ansibaledata]#ansible webs -m command -a "chdir=/data/ cat test" 查詢test文件內容
192.168.34.102 | CHANGED | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 96G 913M 91G 1% /
tmpfs 743M 0 743M 0% /dev/shm
/dev/sda1 976M 33M 892M 4% /boot
/dev/sda3 48G 52M 46G 1% /data
192.168.34.103 | CHANGED | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 100G 1.2G 99G 2% /
devtmpfs 791M 0 791M 0% /dev
tmpfs 802M 0 802M 0% /dev/shm
tmpfs 802M 9.6M 792M 2% /run
tmpfs 802M 0 802M 0% /sys/fs/cgroup
/dev/sda3 50G 33M 50G 1% /data
/dev/sda1 1014M 127M 888M 13% /boot
tmpfs 161M 0 161M 0% /run/user/0
6、copy模塊
copy:復制文件到遠程主機,可以改權限等
(1)用法:
① 復制文件
-a "src= dest= "
② 給定內容生成文件
-a "content= dest= "
(2)相關選項如下:
src:源,被復制到遠程主機的本地文件,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞歸復制。在這種情況下,如果路徑使用“/”來結尾,則只復制目錄里的內容,如果沒有使用“/”來結尾,則包含目錄在內的整個內容全部復制,類似於rsync。 dest:目標,必選項。要將源文件復制到的遠程主機的絕對路徑,如果源文件是一個目錄,那么該路徑也必須是個目錄 backup:被管理的遠程主機已經有文件了,在覆蓋之前,將源文件備份,備份文件包含時間信息。有兩個選項:yes|no content:用於替代“src”,可以直接設定指定文件的值 directory_mode:遞歸設定目錄的權限,默認為系統默認權限 force:如果目標主機包含該文件,但內容不同,如果設置為yes,則強制覆蓋,如果為no,則只有當目標主機的目標位置不存在該文件時,才復制。默認為yes others:所有的file模塊里的選項都可以在這里使用
示例:
[root@ansibaledata]#ansible all -m copy -a "src=/etc/issue dest=/data/fstab owner=nobody mode=600 backup=yes" 將src(源)/etc/issue文件復制到dest(目標)的data目錄下,起名叫fstab,所有者為nobody,權限為600,如果有此文件,進行備份。
192.168.34.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/data/fstab.23704.2019-11-04@15:19:19~",
"changed": true,
"checksum": "5c76e3b565c91e21bee303f15c728c71e6b39540",
"dest": "/data/fstab",
"gid": 0,
"group": "root",
"md5sum": "f078fe086dfc22f64b5dca2e1b95de2c",
"mode": "0600",
"owner": "nobody",
"size": 23,
"src": "/root/.ansible/tmp/ansible-tmp-1572851957.62-86571596767189/source",
"state": "file",
"uid": 99
}
192.168.34.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/data/fstab.21512.2019-11-04@23:19:19~",
"changed": true,
"checksum": "5c76e3b565c91e21bee303f15c728c71e6b39540",
"dest": "/data/fstab",
"gid": 0,
"group": "root",
"md5sum": "f078fe086dfc22f64b5dca2e1b95de2c",
"mode": "0600",
"owner": "nobody",
"size": 23,
"src": "/root/.ansible/tmp/ansible-tmp-1572851957.67-211672525698804/source",
"state": "file",
"uid": 99
}
192.168.34.105 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/data/fstab.5430.2019-11-04@15:19:17~",
"changed": true,
"checksum": "5c76e3b565c91e21bee303f15c728c71e6b39540",
"dest": "/data/fstab",
"gid": 0,
"group": "root",
"md5sum": "f078fe086dfc22f64b5dca2e1b95de2c",
"mode": "0600",
"owner": "nobody",
"size": 23,
"src": "/root/.ansible/tmp/ansible-tmp-1572851957.69-65920362365645/source",
"state": "file",
"uid": 99
}
[root@ansibaledata]#ansible all -m shell -a "ls -l /data/" 查看復制后的結果。
192.168.34.102 | CHANGED | rc=0 >>
total 12
-rw-r--r-- 1 root root 0 Nov 4 14:35 f1
-rw-r--r-- 1 root root 0 Nov 4 14:35 f2
-rw------- 1 nobody root 23 Nov 4 15:19 fstab
-rw------- 1 nobody root 595 Nov 4 15:16 fstab.23704.2019-11-04@15:19:19~ 此文件為備份文件
-rw-r--r-- 1 root root 224 Nov 4 14:58 test
192.168.34.105 | CHANGED | rc=0 >>
total 20
-rw------- 1 nobody root 23 Nov 4 15:19 fstab
-rw------- 1 nobody root 595 Nov 4 15:16 fstab.5430.2019-11-04@15:19:17~ 此文件為備份文件
drwxr-xr-x 7 root root 4096 Oct 29 15:51 fulliso
drwxr-xr-x 4 root root 4096 Oct 29 14:17 iso
-rw-r--r-- 1 root root 1400 Oct 30 20:14 ks7_mini.cfg
192.168.34.103 | CHANGED | rc=0 >>
total 12
-rw-r--r-- 1 root root 0 Nov 4 22:35 f1
-rw-r--r-- 1 root root 0 Nov 4 22:35 f2
-rw------- 1 nobody root 23 Nov 4 23:19 fstab
-rw------- 1 nobody root 595 Nov 4 23:16 fstab.21512.2019-11-04@23:19:19~ 此文件為備份文件
-rw-r--r-- 1 root root 413 Nov 4 22:58 test
copy復制目錄:
[root@ansibaledata]#ansible webs -m copy -a "src=/data dest=/data/newdata" 復制/data/下的目錄,並起名叫newdata
192.168.34.102 | CHANGED => {
"changed": true,
"dest": "/data/newdata/",
"src": "/data"
}
192.168.34.103 | CHANGED => {
"changed": true,
"dest": "/data/newdata/",
"src": "/data"
}
[root@ansibaledata]#ansible webs -m shell -a "ls -l /data/"
192.168.34.102 | CHANGED | rc=0 >>
total 16
drwxr-xr-x 3 root root 4096 Nov 4 15:27 newdata
-rw-r--r-- 1 root root 224 Nov 4 14:58 test
192.168.34.103 | CHANGED | rc=0 >>
total 12
drwxr-xr-x 3 root root 18 Nov 4 23:27 newdata
-rw-r--r-- 1 root root 413 Nov 4 22:58 test
content用法:
[root@ansibaledata]#ansible all -m copy -a 'content="[test]\nbaseurl=file:///mnt\ngpgcheck=0" dest=/etc/yum.repos.d/test.repo' 對被控制端進行新建yum源,並起名叫test.repo [root@ansibaledata]#ansible all -m shell -a "ls /etc/yum.repos.d/" 查看新建的yum源文件 192.168.34.103 | CHANGED | rc=0 >> test.repo 192.168.34.102 | CHANGED | rc=0 >> test.repo 192.168.34.105 | CHANGED | rc=0 >> base.repo test.repo [root@ansibaledata]#ansible all -m shell -a "cat /etc/yum.repos.d/test.repo" 查詢新建的yum源文件內容 192.168.34.102 | CHANGED | rc=0 >> [test] baseurl=file:///mnt gpgcheck=0 192.168.34.103 | CHANGED | rc=0 >> [test] baseurl=file:///mnt gpgcheck=0 192.168.34.105 | CHANGED | rc=0 >> [test] baseurl=file:///mnt gpgcheck=0
7、fetch 模塊
(1)介紹
從遠程某主機獲取文件到本地:
dest:用來存放文件的目錄,例如存放目錄為backup,源文件名稱為/etc/profile
在主機pythonserver中,那么保存為/backup/pythonserver/etc/profile
Src:在遠程拉取的文件,並且必須是一個file,不能是目錄
注意:從遠程獲取到本地的文件,會保存到以遠程主機的IP 為名的目錄中,且保存目錄結構
示例:
[root@ansibaledata]#ansible webs -m fetch -a "src=/etc/hosts dest=/data" 將遠處的/etc/hosts文件復制到本機的/data/目錄下 [root@ansibaledata]#ll 復制的文件目錄以IP地址形式顯示 total 48 -rw-r---w- 1 root root 90 Nov 3 22:05 1 drwxr-xr-x 3 root root 17 Nov 4 15:43 192.168.34.102 drwxr-xr-x 3 root root 17 Nov 4 15:43 192.168.34.103 [root@ansibaledata]#tree 查看復制過來的文件 . ├── 1 ├── 192.168.34.102 │ └── etc │ └── hosts ├── 192.168.34.103 │ └── etc │ └── hosts
[root@ansibaledata]#ansible webs -m shell -a "tar -cvf /root/data.tar /data" 可以將data目錄下的文件打包到root下起名叫data.tar 打包之后就可以用fetch復制此打包文件。 [WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because unarchive is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. [root@ansibaledata]#ansible webs -m shell -a "ls -l /root/" 查看root下的打包文件 192.168.34.102 | CHANGED | rc=0 >> total 68 -rw-------. 1 root root 1125 Nov 2 23:04 anaconda-ks.cfg -rw-r--r-- 1 root root 30720 Nov 4 15:50 data.tar -rw-r--r--. 1 root root 16911 Nov 2 23:04 install.log -rw-r--r--. 1 root root 5820 Nov 2 23:03 install.log.syslog -rw-r--r-- 1 root root 420 Nov 4 14:56 test 192.168.34.103 | CHANGED | rc=0 >> total 44 -rw-------. 1 root root 1636 Nov 3 07:08 anaconda-ks.cfg -rw-r--r-- 1 root root 30720 Nov 4 23:50 data.tar -rw-------. 1 root root 1385 Nov 3 07:08 original-ks.cfg -rw-r--r-- 1 root root 740 Nov 4 22:56 test
8、file 模塊
設置文件屬性
創建目錄:-a "path= state=directory"
創建鏈接文件:-a "path= src= state=link"
刪除文件:-a "path= state=absent"
(1)選項
(2)實例:
① ansible webs -m file -a "path=/data/f4 state=directory" 在被控制端,創建f4 目錄
force:需要在兩種情況下強制創建軟鏈接,一種是源文件不存在,但之后會建立的情況下;另一種是目標軟鏈接已存在,需要先取消之前的軟鏈,然后創建新的軟鏈,有兩個選項:yes|no group:定義文件/目錄的屬組 mode:定義文件/目錄的權限 owner:定義文件/目錄的屬主 path:必選項,定義文件/目錄的路徑 recurse:遞歸設置文件的屬性,只對目錄有效 src:被鏈接的源文件路徑,只應用於state=link的情況 dest:被鏈接到的路徑,只應用於state=link的情況 state=: directory:如果目錄不存在,就創建目錄 file:即使文件不存在,也不會被創建 link:創建軟鏈接 hard:創建硬鏈接 touch:如果文件不存在,則會創建一個新的文件,如果文件或目錄已存在,則更新其最后修改時間 absent:刪除目錄、文件或者取消鏈接文件
ansible webs -m command -a "chdir=/data ls" 查看/data 目錄
[root@ansibaledata]#ansible webs -m file -a "path=/data/f4 state=directory" 在data目錄下新建f4目錄 [root@ansibaledata]#ansible webs -m command -a "chdir=/data ls -l" 查詢新建的結果 192.168.34.102 | CHANGED | rc=0 >> total 20 -rw-r--r-- 1 root root 0 Nov 4 14:35 f1 -rw-r--r-- 1 root root 0 Nov 4 14:35 f2 drwxr-xr-x 2 root root 4096 Nov 4 16:12 f4 新建的f4目錄 192.168.34.103 | CHANGED | rc=0 >> total 12 -rw-r--r-- 1 root root 0 Nov 4 22:35 f1 -rw-r--r-- 1 root root 0 Nov 4 22:35 f2 drwxr-xr-x 2 root root 6 Nov 5 00:12 f4 新建的f4目錄
(3)示例:
刪除目錄下的文件
ansible webs -m file -a "path=/data/f4 state=absent" 刪除data目錄下的f4
ansible webs -m file -a "path=/data/ state=absent" 刪除data目錄下的文件
[root@ansibaledata]#ansible webs -m file -a "path=/data/f4 state=absent" 刪除data目錄下的f4 [root@ansibaledata]#ansible webs -m command -a "chdir=/data ls -l" 查看此時data目錄下已經沒有f4目錄 192.168.34.102 | CHANGED | rc=0 >> total 16 -rw-r--r-- 1 root root 0 Nov 4 14:35 f1 -rw-r--r-- 1 root root 0 Nov 4 14:35 f2 192.168.34.103 | CHANGED | rc=0 >> total 12 -rw-r--r-- 1 root root 0 Nov 4 22:35 f1 -rw-r--r-- 1 root root 0 Nov 4 22:35 f2
(4)示例;
創建軟鏈接和硬鏈接
ansible webs -m file -a "src=/data/fstab path=/data/fstab.link state=link" 將/data/fstab 創建軟鏈接為/data/fstab.link
ansible webs -m file -a "src=/data/fstab path=/data/fstab1.link state=hard" 將/data/fstab創建硬鏈接為/data/fstab1.link
1、創建軟鏈接:
[root@ansibaledata]#ansible webs -m file -a "src=/data/fstab path=/data/fstab.link state=link"
192.168.34.102 | CHANGED => {
[root@ansibaledata]#ansible webs -m shell -a "ls -l /data/"
192.168.34.102 | CHANGED | rc=0 >>
total 16
lrwxrwxrwx 1 root root 11 Nov 4 16:24 fstab.link -> /data/fstab 創建成功的軟鏈接
192.168.34.103 | CHANGED | rc=0 >>
total 12
lrwxrwxrwx 1 root root 11 Nov 5 00:24 fstab.link -> /data/fstab 創建成功的軟鏈接
2、創建硬鏈接:
[root@ansibaledata]#ansible webs -m file -a "src=/data/fstab path=/data/fstab1.link state=hard" [root@ansibaledata]#ansible webs -m shell -a "ls -l /data/" 192.168.34.102 | CHANGED | rc=0 >> total 20 -rw------- 2 nobody root 23 Nov 4 15:19 fstab -rw------- 2 nobody root 23 Nov 4 15:19 fstab1.link 192.168.34.103 | CHANGED | rc=0 >> total 16 -rw------- 2 nobody root 23 Nov 4 23:19 fstab -rw------- 2 nobody root 23 Nov 4 23:19 fstab1.link
9、hostname:管理主機名
示例:
ansible 192.168.34.102 -m hostname -a "name=centos102" 修改為centos102
ansible 192.168.34.102 -a "hostname" 查看當前修改后的主機名
[root@ansibaledata]#ansible 192.168.34.102 -m hostname -a "name=centos102"
192.168.34.102 | CHANGED => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "centos102",
"ansible_hostname": "centos102",
"ansible_nodename": "centos102",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "centos102"
}
[root@ansibaledata]#ansible 192.168.34.102 -a "hostname"
192.168.34.102 | CHANGED | rc=0 >>
centos102
10、cron 模塊
管理cron計划任務;-a "": 設置管理節點生成定時任務
(1)選項:
① action: cron backup= #如果設置,創建一個crontab備份 【yes|no】 cron_file= #如果指定, 使用這個文件cron.d,而不是單個用戶 ② crontab day= #日應該運行的工作( 1-31, *, */2, ) hour= # 小時 ( 0-23, *, */2, ) minute= #分鍾( 0-59, *, */2, ) month= #月( 1-12, *, /2, ) weekday # 周 ( 0-6 for Sunday-Saturday,, ) job= #指明運行的命令是什么 name= #定時任務描述 reboot # 任務在重啟時運行,不建議使用,建議使用special_time special_time #特殊的時間范圍,參數:reboot(重啟時),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小時) state #指定狀態,present表示添加定時任務,也是默認設置,absent表示刪除定時任務 user #以哪個用戶的身份執行
(1)示例:
開啟計划任務:
[root@ansibaledata]#ansible webs -m cron -a "minute=*/5 weekday=0,6 job="/usr/sbin/update 192.168.34.101 &> /dev/null" name=synctime" 只在周六周日每五分鍾將時間與192.168.34.101進行同步,起名叫synctime [root@ansibaledata]#ansible webs -a "crontab -l"查詢當前執行的任務結果。
禁用計划任務:
[root@ansibaledata]#ansible webs -m cron -a "minute=*/5 weekday=0,6 job="/usr/sbin/update 192.168.34.101 &> /dev/null" name=synctime disabled=ture" 只在周六周日每五分鍾將時間與192.168.34.101進行同步計划任務進行禁用 [root@ansibaledata]#ansible webs -a "crontab -l"查詢當前執行的任務結果。
(2)示例:
在遠程主機上,定義每5分鍾,清空一次防火牆
① ansible web -m cron -a "name='Clear the iptable' minute=*/5 job='/sbin/iptables -F'"
ansible web -m shell -a "crontab -l" 查看
[root@ansibaledata]#ansible webs -m cron -a "name='Clean the iptable' minute=*/5 job='/sbin/iptables -F &> /dev/full'"
192.168.34.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"Clean the iptable"
]
}
192.168.34.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"Clean the iptable"
]
}
[root@ansibaledata]#ansible webs -a "crontab -l"
192.168.34.102 | CHANGED | rc=0 >>
#Ansible: Clean the iptable
*/5 * * * * /sbin/iptables -F
192.168.34.103 | CHANGED | rc=0 >>
#Ansible: Clean the iptable
*/5 * * * * /sbin/iptables -F
(3)啟動當前的計划任務
[root@ansibaledata]#ansible webs -m cron -a "name='Clean the iptable' minute=*/5 job='/sbin/iptables -F disabled=false'" 開啟當前的計划任務,起名叫Clean the iptable
192.168.34.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"Clean the iptable"
]
}
192.168.34.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"Clean the iptable"
]
}
[root@ansibaledata]#ansible webs -a "crontab -l"
192.168.34.102 | CHANGED | rc=0 >>
#Ansible: Clean the iptable
*/5 * * * * /sbin/iptables -F disabled=false 開啟結果
192.168.34.103 | CHANGED | rc=0 >>
#Ansible: Clean the iptable
*/5 * * * * /sbin/iptables -F disabled=false
(4)刪除計划任務:
[root@ansibaledata]#ansible webs -m cron -a "name='Clean the iptable' state=absent" 刪除計划任務,只需要將對應的計划任務名稱刪掉即可。
192.168.34.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
192.168.34.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
[root@ansibaledata]#ansible webs -a "crontab -l" 查詢結果,此時已經沒有計划任務
192.168.34.102 | CHANGED | rc=0 >>
192.168.34.103 | CHANGED | rc=0 >>
11、yum 模塊
(1)選項
conf_file #設定遠程yum安裝時所依賴的配置文件。如配置文件沒有在默認的位置。 disable_gpg_check #是否禁止GPG checking,只用於`present‘ or `latest’。 disablerepo #臨時禁止使用yum庫。 只用於安裝或更新時。 enablerepo #臨時使用的yum庫。只用於安裝或更新時。 name= #所安裝的包的名稱 state= #present安裝, latest安裝最新的, absent 卸載軟件。 update_cache #強制更新yum的緩存。
(2)示例
①i安裝dstat 包,忽略gpg_check
ansible webs -m yum -a "name=dstat "
卸載dstat 包
ansible webs -m yum -a "name=dstat state=absent"
安裝多個包:
ansible webs -m yum -a "name=httpd,vsftpd,memacahe"
卸載多個包;
ansible webs -m yum -a "name=httpd,vsftpd,memacahe,state=absent"
[root@ansibaledata]#ansible webs -m yum -a "name=dstat" 安裝dstat包
192.168.34.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"dstat"
]
},
"msg": "Repository 'base' is missing name in configuration, using id\n",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package dstat.noarch 0:0.7.0-3.el6 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n dstat noarch 0.7.0-3.el6 base 146 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package(s)\n\nTotal download size: 146 k\nInstalled size: 665 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Installing : dstat-0.7.0-3.el6.noarch 1/1 \n\r Verifying : dstat-0.7.0-3.el6.noarch 1/1 \n\nInstalled:\n dstat.noarch 0:0.7.0-3.el6 \n\nComplete!\n"
]
}
192.168.34.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"dstat"
]
},
"msg": "Repository 'base' is missing name in configuration, using id\n",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package dstat.noarch 0:0.7.2-12.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n dstat noarch 0.7.2-12.el7 base 163 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 163 k\nInstalled size: 752 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : dstat-0.7.2-12.el7.noarch 1/1 \n Verifying : dstat-0.7.2-12.el7.noarch 1/1 \n\nInstalled:\n dstat.noarch 0:0.7.2-12.el7 \n\nComplete!\n"
]
}
[root@ansibaledata]#ansible webs -a "rpm -q dstat" 查看此包是否安裝成功
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.34.102 | CHANGED | rc=0 >>
dstat-0.7.0-3.el6.noarch
192.168.34.103 | CHANGED | rc=0 >>
dstat-0.7.2-12.el7.noarch
[root@ansibaledata]#ansible webs -m yum -a "name=dstat state=absent" 卸載dstat包
[root@ansibaledata]#ansible webs -a "rpm -q dstat" 查看當前的包是否還存在
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.34.102 | FAILED | rc=1 >>
package dstat is not installednon-zero return code
192.168.34.103 | FAILED | rc=1 >>
package dstat is not installednon-zero return code
(3)示例:
ansible webs -m yum -a "name=dstat update_cache=yes" 更新緩存
12、service 模塊
服務程序管理
(1)選項
arguments #命令行提供額外的參數 enabled #設置開機啟動。 name= #服務名稱 runlevel #開機啟動的級別,一般不用指定。 sleep #在重啟服務的過程中,是否等待。如在服務關閉以后等待2秒再啟動。 state #started啟動服務, stopped停止服務, restarted重啟服務, reloaded重載配置
(2)實例
1、遠程安裝httpd服務
ansible all -m yum -a "name=httpd"
2、遠程開啟httpd服務:
ansible all -m service -a "name=httpd state=started" 遠程操作開啟服務
ansible all -m service -a "name=httpd state=enabled" 開機設置啟動服務
[root@ansibaledata]#ansible all -m yum -a "name=httpd" 安裝http服務 [root@ansibaledata]#ansible all -m service -a "name=httpd state=started" 打開http服務端口 [root@ansibaledata]#ansible all -a "ss -nlt" 查看當前的服務端口 192.168.34.102 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:* 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* 192.168.34.105 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:6010 *:* LISTEN 0 128 ::1:6010 :::* LISTEN 0 128 :::111 :::* LISTEN 0 128 *:111 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 *:44404 *:* LISTEN 0 128 :::58453 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 64 :::23 :::* LISTEN 0 128 127.0.0.1:631 *:* LISTEN 0 128 ::1:631 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:*
(3)遠程關閉服務:
ansible all -m service -a "name=httpd state=stopped"
[root@ansibaledata]#ansible all -m service -a "name=httpd state=stopped" 關閉http服務 [root@ansibaledata]#ansible all -a "ss -nlt" 查此時的80端口已經沒有了 192.168.34.102 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:* 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* 192.168.34.105 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:6010 *:* LISTEN 0 128 ::1:6010 :::* LISTEN 0 128 :::111 :::* LISTEN 0 128 *:111 *:* LISTEN 0 128 *:44404 *:* LISTEN 0 128 :::58453 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 64 :::23 :::* LISTEN 0 128 127.0.0.1:631 *:* LISTEN 0 128 ::1:631 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:*
13、user 模塊
用戶模塊,管理用戶帳號
(1)選項
comment # 用戶的描述信息 createhome # 是否創建家目錄 force # 在使用state=absent是, 行為與userdel -force一致. group # 指定基本組 groups # 指定附加組,如果指定為(groups=)表示刪除所有組 home # 指定用戶家目錄 move_home # 如果設置為home=時, 試圖將用戶主目錄移動到指定的目錄 name # 指定用戶名 non_unique # 該選項允許改變非唯一的用戶ID值 password # 指定用戶密碼,若指定的是明文密碼,是不能用的,需用md5加密過后的密碼 remove # 在使用state=absent時, 行為是與userdel -remove一致 shell # 指定默認shell state # 設置帳號狀態,不指定為創建,指定值為absent表示刪除 system # 當創建一個用戶,設置這個用戶是系統用戶。這個設置不能更改現有用戶 uid # 指定用戶的uid update_password # 更新用戶密碼
示例:
ansible all -m user -a 'name=test comment="test user" uid=200 home=/data/testhome group=root groups=bin,nobody shell=/sbin/nologin' 創建一個test用戶的詳細信息
ansible all -m user -a "name=test state=absent" 刪除用戶信息,但是不會刪除用戶家目錄的文件信息
ansible all -a "getent passwd test" 查看當前創建的用戶信息
ansiable all -a "name=test state=absent remove=yes" 跟上后面的remove=yes就會刪除家目錄信息
[root@ansibaledata]#ansible all -m user -a 'name=test comment="test user" uid=200 home=/data/testhome group=root groups=bin,nobody shell=/sbin/nologin' 創建一個test用戶的詳細信息 [root@ansibaledata]#ansible all -a "getent passwd test" 192.168.34.102 | CHANGED | rc=0 >> test:x:200:0:test user:/data/testhome:/sbin/nologin 192.168.34.103 | CHANGED | rc=0 >> test:x:200:0:test user:/data/testhome:/sbin/nologin 192.168.34.105 | CHANGED | rc=0 >> test:x:200:0:test user:/data/testhome:/sbin/nologin [root@ansibaledata]#ansible all -m user -a "name=test state=absent" 刪除用戶文件信息 [root@ansibaledata]#ansible all -a "getent passwd test" 查看用戶文件信息 192.168.34.102 | FAILED | rc=2 >> non-zero return code 192.168.34.103 | FAILED | rc=2 >> non-zero return code 192.168.34.105 | FAILED | rc=2 >> non-zero return code
14、group模塊
(1)選項
gid # 設置組的GID號
name= # 管理組的名稱
state # 指定組狀態,默認為創建,設置值為absent為刪除
system # 設置值為yes,表示為創建系統組
(2)示例:
ansible webs -m group -a "name=testgroup system=yes“ 創建系統組
ansible webs -m group -a "name=testgroup state=absent" 刪除組
15、setup 模塊
查機器的所有facts信息
(1)介紹
① facts 組件是Ansible 用於采集被管機器設備信息的一個功能,我們可以使用setup 模塊查機器的所有facts信息,可以使用filter來查看指定信息。整個facts信息被包裝在一個JSON格式的數據結構中,ansible_facts是最上層的值。
② facts就是變量,內建變量 。每個主機的各種信息,cpu顆數、內存大小等。會存在facts中的某個變量中。調用后返回很多對應主機的信息,在后面的操作中可以根據不同的信息來做不同的操作。如redhat系列用yum安裝,而debian系列用apt來安裝軟件。
③ setup模塊,主要用於獲取主機信息,在playbooks里經常會用到的一個參數gather_facts就與該模塊相關。
④ setup模塊下經常使用的一個參數是filter 參數,查詢的是全部信息,很多,filter 相當於匹配篩選。
示例:
(1)查詢當前機器的全部信息:
ansible 192.168.34.103 -m setup

(2) 查看當前主機的總內存大小:
ansible all -m setup -a "filter=ansible_memtotal_mb" 其中filter是過濾的含義。

(3)查看每個主機的centos版本號
ansible all -m setup -a "filter=ansible_distribution_major_version"

實驗三:Ansible playbook 的使用
1、介紹
(1)理解
① playbook是ansible用於配置,部署,和管理被控節點的劇本。
② 通過playbook的詳細描述,執行其中的一系列tasks,可以讓遠端主機達到預期的狀態。playbook就像Ansible控制器給被控節點列出的的一系列to-do-list,而被控節點必須要完成。
③ 也可以這么理解,playbook 字面意思,即劇本,現實中由演員按照劇本表演,在Ansible中,這次由計算機進行表演,由計算機安裝,部署應用,提供對外服務,以及組織計算機處理各種各樣的事情
(2)Ansible playbook 使用場景
① 執行一些簡單的任務,使用ad-hoc命令可以方便的解決問題,但是有時一個設施過於復雜,需要大量的操作時候,執行的ad-hoc命令是不適合的,這時最好使用playbook。
② 就像執行shell命令與寫shell腳本一樣,也可以理解為批處理任務,不過playbook有自己的語法格式。
③ 使用playbook你可以方便的重用這些代碼,可以移植到不同的機器上面,像函數一樣,最大化的利用代碼。在你使用Ansible的過程中,你也會發現,你所處理的大部分操作都是編寫playbook。可以把常見的應用都編寫成playbook,之后管理服務器會變得十分簡單。(2)
(2)特性
YAML的可讀性好 YAML和腳本語言的交互性好 YAML使用實現語言的數據類型 YAML有一個一致的信息模型 YAML易於實現 YAML可以基於流來處理 YAML表達能力強,擴展性好
2、Ansible playbook 格式
(1)介紹
① playbook由YMAL語言編寫。YAML( /ˈjæməl/ )參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822,Clark Evans在2001年5月在首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。
② YMAL格式是類似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。首先學習了解一下YMAL的格式,對我們后面書寫playbook很有幫助。以下為playbook常用到的YMAL格式。
(2)語法介紹
1、在單一檔案中,可用連續三個連字號(---)區分多個檔案。另外,還有選擇性的連續三個點號( ... )用來表示檔案結尾 2、次行開始正常寫Playbook的內容,一般建議寫明該Playbook的功能 3、使用#號注釋代碼 4、縮進必須是統一的,不能空格和tab混用 5、縮進的級別也必須是一致的,同樣的縮進代表同樣的級別,程序判別配置的級別是通過縮進結合換行來實現的 6、YAML文件內容是區別大小寫的,k/v的值均需大小寫敏感 7、k/v的值可同行寫也可換行寫。同行使用:分隔 8、v可是個字符串,也可是另一個列表 9、一個完整的代碼塊功能需最少元素需包括 name: task 10、一個name只能包括一個task 11、YAML文件擴展名通常為yml或yaml
(3)Playbooks 配置文件的基礎組件
① hosts:運行指定任務的目標主機;使用hosts指示使用哪個主機或主機組來運行下面的tasks,每個playbook都必須指定hosts,hosts也可以使用通配符格式。主機或主機組在inventory清單中指定,可以使用系統默認的/etc/ansible/hosts,也可以自己編輯,在運行的時候加上-i選項,指定清單的位置即可。在運行清單文件的時候,-list-hosts選項會顯示那些主機將會參與執行task的過程中。
② remoute_user: 在遠程主機上執行任務的用戶;指定遠端主機中的哪個用戶來登錄遠端系統,在遠端系統執行task的用戶,可以任意指定,也可以使用sudo,但是用戶必須要有執行相應task的權限。
③ sudo_user:
④ tasks:任務列表;指定遠端主機將要執行的一系列動作。tasks的核心為ansible的模塊,前面已經提到模塊的用法。
tasks:包含name和要執行的模塊,name是可選的,只是為了便於用戶閱讀,不過還是建議加上去,模塊是必須的,同時也要給予模塊相應的參數。
⑤ templates:包含了模板語法的文本文件;
⑥ variables 變量
⑦ handlers:由特定條件觸發的任務;
(4)注意:shell和command模塊后面直接跟命令,而非key=value類的參數列表;
① 某任務的狀態在運行后為changed時,可通過"notify"通知給相應的handlers,兩個文件名稱要一致;
② 任務可以通過"tags"打標簽,而后可在ansible-playbook命令上使用-t 標簽名,指定進行調用;
(5)variables 變量的定義:
① facts:可直接調用;
注意:可使用setup模塊直接獲取目標主機的facters;
② 用戶自定義變量:
(a) ansible-playbook命令的命令行中的
-e VARS, --extra-vars=VARS
(b) 在playbook中定義變量的方法:
vars:
- var1: value1
var2: value2
(6)執行playbook劇本
使用ansible-playbook運行playbook文件,得到如下輸出信息,輸出內容為JSON格式。並且由不同顏色組成,便於識別。一般而言
綠色代表執行成功,系統保持原樣
黃色代表系統代表系統狀態發生改變
紅色代表執行失敗,顯示錯誤輸出。
3、playbook劇本書寫及運行方式
ansible-playbook <filename.yml> ... [options]
常見選項
--check -C 只檢測可能會發生的改變,但不真正執行操作 --list-hosts 列出運行任務的主機 --list-tags 列出tag --list-tasks 列出task --limit 主機列表 只針對主機列表中的主機執行 -v -vv -vvv 顯示過程
示例
ansible-playbook file.yml --check 只檢測 ansible-playbook file.yml ansible-playbook file.yml --limit websrvs
ansible-playbook示例:
注意:復制的httpd.conf配置文件只能適用於同一版本的httpd配置文件,centos6和centos7不能共用:
---
- hosts: webs
remote_user: root
tasks:
- name: create group
group: name=apache system=yes gid=80
- name: create user
user: name=apache group=apache uid=80 shell=/sbin/nonlogin home=/usr/share/httpd system=yes password=$1$TGp21j8c$L3Q8BYFXsCBFt53nmw0t.0
- name: install package
yum: name=httpd
- name: config file
copy: src=/root/playbook/httpd.conf dest=/etc/httpd/conf/ backup=yes
- name: service
service: name=httpd state=started enabled=yes
執行結果:
[root@ansibledata]#ansible-playbook install_httpd.yml 執行此playbook [root@ansibledata]#ansible webs -a "ss -nlt" 查詢當前端口已經開啟80端口 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@ansibledata]#ansible webs -a "getent passwd apache" 查詢用戶賬號,已經創建 192.168.34.103 | CHANGED | rc=0 >> apache:x:80:80:Apache:/usr/share/httpd:/sbin/nonlogin
(2)在劇本中加入handlers 觸發任務
前提背景:如playbook 中有一系列tasks,但有時只需改動少個tasks 就要觸發另一個操作;若再把劇本執行一遍,浪費資源和時間;此時可以設置handlers 觸發任務
注意:如果執行killall 命令,需要其他機器有該命令才能執行。
vim /data/install_httpd.yml
---
- hosts: webs
remote_user: root
tasks:
- name: create group
group: name=apache system=yes gid=80
- name: create user
user: name=apache group=apache uid=80 shell=/sbin/nonlogin home=/usr/share/httpd system=yes password=$1$TGp21j8c$L3Q8BYFXsCBFt53nmw0t.0
- name: install package
yum: name=httpd
- name: config file
copy: src=/root/playbook/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: - restart service - check httpd
- name: service
service: name=httpd state=started enabled=yes
handlers: - name: restart service
service: name=httpd state=restarted
- name: check httpd
- shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log
修改要復制的/data/http.conf配置文件的端口號為81,執行playbook后,就會重啟httpd服務,查看當前的端口號就是81
[root@ansibledata]#vim httpd.conf 將data下要復制的配置文件端口改為81 # prevent Apache from glomming onto all bound IP addresses. # #Listen 12.34.56.78:80 Listen 81 [root@ansibledata]#ansible-playbook install_httpd.yml 此時執行playbook,復制過去的端口就是81 [root@ansibledata]#ansible webs -a "ss -nlt" 查看到重啟的端口httpd就是81端口 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::81 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
查看當前檢測的信號里放置的臨時文件沒有任何內容,說明執行成功,如果有錯誤,就會在里邊顯示錯誤內容。

(2)tags 標簽在playbook中使用:
一個動作可以執行多個標簽,也可以多個動作執行多個標簽,執行標簽動作需要加上-t選項:
ansible-playbook -t config insall.yml 觸發一個標簽
ansible-playbook -t "config,service" install.yml 觸發兩個標簽
---
- hosts: webs
remote_user: root
tasks:
- name: create group
group: name=apache system=yes gid=80
- name: create user
user: name=apache group=apache uid=80 shell=/sbin/nonlogin home=/usr/share/httpd system=yes password=$1$TGp21j8c$L3Q8BYFXsCBFt53nmw0t.0
- name: install package
yum: name=httpd
- name: config file
copy: src=/data/httpd.conf dest=/etc/httpd/conf/ backup=yes
tags: config,copy 其中一個動作可以標注多個標簽,執行config和copy都可以
notify:
- restart service
- check httpd
- name: service
tags: service service標簽
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
- name: check httpd
shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log
我們將要復制的httpd.conf配置文件的端口號改為82,用copy標簽執行下面的內容,只會執行下面一個動作,也會執行觸發器里邊的動作,即nodity和handlers動作

可以看到當前httpd服務啟動后的端口號變為82端口。

我們也可以執行多個標簽的動作,具體如下操作:
ansible-playbook -t ""config,service" install.yml

vars變量使用:
(1)變量可以不定義在playbook 中,直接在命令行給出
[root@ansibledata]#vim install_httpd.yml
---
- hosts: webs
remote_user: root
tasks:
- name: install package
yum: name={{ servername }} 使用name變量
- name: service
service: name={{ servername }} state=started enabled=yes
給變量servername賦值,就可以執行相應的動作:其中-e servername=vsftpd 指定當前變量的為vsftpd
ansible-playbook -e servername=vsftpd install_httpd.yml 將servername賦值為vsftpd,就可以安裝此服務,此服務端口為21,已經打開.
執行結果如下:
[root@ansibledata]#ansible-playbook -e name=vsftpd install_httpd.yml [WARNING]: Found variable using reserved name: name PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [install package] *********************************************************************************************** ok: [192.168.34.103] TASK [service] ******************************************************************************************************* changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansibledata]#ansible webs -a "ss -nlt" 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::82 :::* LISTEN 0 32 :::21 21端口打開 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
(2)賦予兩個不同的變量名,servername1為包名,servername2為服務名
[root@ansibledata]#vim install_httpd.yml
---
- hosts: webs
remote_user: root
tasks:
- name: install package
yum: name={{ servername1 }} 賦予一個變量name1,作為包名
- name: service
service: name={{ servername2 }} state=started enabled=yes 啟動name2,服務名
將servername1賦予包名,servername2賦予服務名
ansible-playbook -e "servername1=samba servername2=smb' install_httpd.yml
執行結果如下:
[root@ansibledata]#ansible-playbook -e "servername1=samba servername2=smb" install_httpd.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [install package] *********************************************************************************************** changed: [192.168.34.103] TASK [service] ******************************************************************************************************* changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
(3)也可以直接定義在playbook 中:
---
- hosts: webs
remote_user: root
vars:
- servername1: samba 定義在playbook內容中
- servername2: smb
tasks:
- name: install package
yum: name={{ servername1 }}
- name: service
service: name={{ servername2 }} state=started enabled=yes
執行成功結果:

(4)在獨立的變量YAML文件中定義(推薦使用此方法)
新建一個vars.yml文件,指定存放要執行的變量,servername: httpd
[root@ansibleplaybook]#vim vars.yml servername: httpd
將寫好的變量文件賦予到此playbook內容中
---
- hosts: webs
remote_user: root
vars_files: 定義一個vars.yml文件 - vars.yml
tasks:
- name: install package
yum: name={{ servername }}
- name:
service: name={{ servername }} state=started enabled=yes
執行結果:
[root@ansibleplaybook]#ansible-playbook test.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.102] ok: [192.168.34.103] TASK [install] ******************************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.102] TASK [config file] *************************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.102] TASK [service] ******************************************************************************************************* ok: [192.168.34.102] ok: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.102 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.34.103 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible webs -a "ss -nlt" 可以查看到當前的80端口已經安裝好
[root@ansibleplaybook]#ansible webs -a "ss -nlt" 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:139 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 50 *:445 *:* LISTEN 0 50 :::139 :::* LISTEN 0 128 :::80 :::* LISTEN 0 32 :::21 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 50 :::445 :::*
(5) 在 在/etc/ansible/hosts中定義變量
1)普通變量:此時在webs組的IP后面追加命名nodename=centos7_1,可以將遠程的機器的名稱改為centos7_1.
[root@ansibleplaybook]#vim /etc/ansible/hosts [webs] 192.168.34.103 nodename=centos7_1
定義yml內容,將hosts的文件名定義到變量中:
---
- hosts: webs
remote_user: root
tasks:
- name: hostname
hostname: name={{ nodename }}
此時執行ansible-playbook test.yml ,就會將遠程的主機名稱修改,具體如下:
[root@ansibleplaybook]#ansible-playbook test.yml 執行此playbook變量內容
PLAY [webs] **********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.34.103]
TASK [hostname] ******************************************************************************************************
changed: [192.168.34.103]
PLAY RECAP ***********************************************************************************************************
192.168.34.103 : ok=2 changed=1
[root@ansibleplaybook]#ansible webs -a "hostname" 查詢遠程主機的主機名為centos7_1
192.168.34.103 | CHANGED | rc=0 >>
centos7_1
2)定義組變量:將主機名之前的內容統一追加一個相同的內容:
vim /etc/ansible/hosts [webs] 192.168.34.103 nodename=centos7_1 主機名 [webs:vars] name=baidu.com 添加后綴名
將后綴的變量名稱放到后面:
---
- hosts: webs
remote_user: root
tasks:
- name: hostname
hostname: name={{ nodename }}.{{ name }} #定義的變量追加的內容
執行結果如下:
ansible-playbook test.yml
[root@ansibleplaybook]#ansible-playbook test.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [hostname] ****************************************************************************************************** changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansibleplaybook]#ansible webs -a "hostname" 192.168.34.103 | CHANGED | rc=0 >> centos7_1.baidu.com # 此時的主機名后綴有baidu.com
4、在劇本中加入模板 templates
(1)介紹
template模板為我們提供了動態配置服務,使用jinja2語言,里面支持多種條件判斷、循環、邏輯運算、比較操作等。其實說白了也就是一個文件,和之前配置文件使用copy一樣,只是使用copy,不能根據服務器配置不一樣進行不同動態的配置。這樣就不利於管理。
說明:
1、多數情況下都將template文件放在和playbook文件同級的templates目錄下(手動創建),這樣playbook文件中可以直接引用,會自動去找這個文件。如果放在別的地方,也可以通過絕對路徑去指定。
支持:
字符串:使用單引號或雙引號;
數字:整數,浮點數;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false
算術運算:+, -, *, /, //, %, **
比較操作:==, !=, >, >=, <, <=
邏輯運算:and, or, not
(2)先創建一個模板文件,以.j2 結尾
cp /etc/nginx/nginx.conf /playbook/nginx.conf.j2
vim /playbook/nginx.conf.j2
worker_processes {{ ansible_processor_count*2 }}; #該變量是setup 模塊查看CPU核數的變量,此時將CPU核數乘以2
listen {{ nginx_port}}; #自定義在playbook 中的變量
yum install nginx #安裝nginx
"ansible_processor_count": 1 查看當前的CPU核數有幾個
(1)書寫當前的模板,將本機的源文件復制到目標地址,將CPU個數成倍增漲,並將端口號改為82:
[root@ansibleplaybook]#vim test1.yml
---
- hosts: webs
remote_user: root
tasks:
- name: install
yum: name=nginx
- name: template 定制模板 template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 將源文件復制到目標地址
notify: restart
- name: service
service: name=nginx state=started enabled=yes
handlers:
- name: restart
service: name=nginx state=restarted enabled=yes
(2)修改templates目錄下的nginx.confj2配置文件,將當前的CPU核數乘以四,並將端口號定義變量{{nginx_port}}:
[root@ansibleplaybook]#vim templates/nginx.conf.j2
worker_processes {{ansible_processor_count*4}}; CPU乘以4倍
server {
listen {{nginx_port}} default_server; 將此IPV4的端口號定義為變量
listen [::]:80 default_server; 下面的是IPV6的端口號
(3)修改/etc/ansible/hosts配置文件的端口號,定義變量,可以修改當前的nginx的端口號:
vim /etc/ansible/hosts [webs] 192.168.34.103 nodename=centos7_1 nginx_port=82
執行nginx.yml的劇本:
[root@ansibleplaybook]#ansible-playbook nginx.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [install] ******************************************************************************************************* ok: [192.168.34.103] TASK [template] ****************************************************************************************************** ok: [192.168.34.103] TASK [service] ******************************************************************************************************* ok: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(4)查詢執行結果,此時已有四個CPU運行。
[root@ansibleplaybook]#ansible webs -m shell -a "ps aux | grep nginx" 查詢單簽的nginx的運行情況
192.168.34.103 | CHANGED | rc=0 >>
root 29927 0.0 0.1 120796 2252 ? Ss 01:51 0:00 nginx: master process /usr/sbin/nginx
nginx 29928 0.0 0.2 121180 3332 ? S 01:51 0:00 nginx: worker process 此時可以查看到有四個CPU nginx 29929 0.0 0.2 121180 3332 ? S 01:51 0:00 nginx: worker process nginx 29930 0.0 0.2 121180 3332 ? S 01:51 0:00 nginx: worker process nginx 29931 0.0 0.1 121180 3128 ? S 01:51 0:00 nginx: worker process
root 29996 0.0 0.0 113176 1216 pts/1 S+ 01:51 0:00 /bin/sh -c ps aux | grep nginx
root 29998 0.0 0.0 112708 956 pts/1 S+ 01:51 0:00 grep nginx
(5)查看82端口號運行情況:
[root@ansibleplaybook]#ansible webs -a "ss -nlt"
192.168.34.103 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:139 *:*
LISTEN 0 128 *:82 *:* 此時查看到82端口已經打開
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 50 *:445 *:*
LISTEN 0 50 :::139 :::*
LISTEN 0 128 :::80 :::*
LISTEN 0 32 :::21 :::*
LISTEN 0 128 :::86 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 50 :::445 :::*
5、templates之when
條件測試:如果需要根據變量、facts或此前任務的執行結果來做為某task執行與否的前提時要用到條件測試,通過when語句執行,在task中使用jinja2的語法格式、
when語句:
在task后添加when子句即可使用條件測試;when語句支持jinja2表達式語法。
"ansible_distribution_major_version": "7"查看當前的系統版本號
1) 將/etc/ansible/hosts配置文件的端口號改為http_port
vim /etc/ansible/hosts [apps] 192.168.34.103 http_port=86 192.168.34.105 http_port=87
2) 將centos6的httpd的配置文件復制到centos7的templates目錄下,起名為httpd6.conf.j2 ,准備的是centos6的配置文件
3) 將centos7的httpd的配置文件復制到templates目錄下,起名叫httpd7.conf.j2,准備的是centos7的配置文件
[root@centos6~]#scp /etc/httpd/conf/httpd.conf 192.168.34.101:/root/playbook/templates/httpd6.conf.j2 [root@ansibleplaybook]#cp /etc/httpd/conf/httpd.conf templates/httpd7.conf.j2
4) 修改復制后的httpd6.conf.j2和httpd7.conf.j2配置文件的端口:
vim httpd6.conf.j2
Listen {{http_port}}
vim httpd7.conf.j2
Listen {{http_port}}
5)書寫template模板內的when可以將centos6和centos7的httpd版本不同問題解決,針對不同的系統版本,安裝不同版本的系統:
---
- hosts: apps
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: template1
template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="6" #判斷當前的操作系統是6版本,安裝版本6的httpd服務
notify: restart
- name: template2
template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="7"
notify: restart
- name: service
service: name=httpd state=started enabled=yes
handlers:
- name: restart
service: name=httpd state=restarted
6) 查看httpd安裝后的結果,此時的86和87端口都已經打開
[root@ansibleplaybook]#ansible apps -a "ss -nlt" 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:139 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 50 *:445 *:* LISTEN 0 50 :::139 :::* LISTEN 0 128 :::80 :::* LISTEN 0 32 :::21 :::* LISTEN 0 128 :::86 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 50 :::445 :::* 192.168.34.105 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:6010 *:* LISTEN 0 128 ::1:6010 :::* LISTEN 0 128 :::55642 :::* LISTEN 0 128 :::111 :::* LISTEN 0 128 *:111 *:* LISTEN 0 128 *:57810 *:* LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 128 :::87 :::* LISTEN 0 64 :::23 :::* LISTEN 0 128 127.0.0.1:631 *:* LISTEN 0 128 ::1:631 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:*
6、template之with_items
with_items迭代,當有需要重復性執行的任務時,可以使用迭代機制。
對迭代項的引用,固定變量名為“item”,要在task中使用with_items給定要迭代的元素列表。
列表格式:
字符串
字典
示例一:
在本機新建十個文件,然后將本機的文件復制到其他文件中
[root@ansibleplaybook]#mkdir files
[root@ansibleplaybook]#touch files/file{1..10}
將本地的三個文件復制到對方主機的data目錄下,編寫playbook:
[root@ansibleplaybook]#vim test_temp.yml
---
- hosts: webs
remote_user: root
tasks:
- name: copy files
copy: src={{item}} dest=/data/ mode=600
with_items:
- file1
- file2
- file3
執行playbook命令,查看執行結果:
[root@ansibleplaybook]#ansible-playbook test_temp.yml 執行命令 PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [copy files] **************************************************************************************************** changed: [192.168.34.103] => (item=file1) changed: [192.168.34.103] => (item=file2) changed: [192.168.34.103] => (item=file3) PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansibleplaybook]#ansible webs -a "ls /data/ -l" 查看對方的主機已經有600權限的三個文件 192.168.34.103 | CHANGED | rc=0 >> total 0 -rw------- 1 root root 0 Nov 6 04:14 file1 -rw------- 1 root root 0 Nov 6 04:14 file2 -rw------- 1 root root 0 Nov 6 04:14 file3
示例二:通過嵌套子變量創建用戶並加入不同的組
編寫playbook:
vim test.yml
---
- hosts: webs
remote_user: root
tasks:
- name: create groups
group: name={{item}} state=present(默認,不需要寫)
with_items:
- g1
- g2
- g3
- name: create users state=present(默認,可以不寫)
user: name={{item.name}} group={{item.group}}
with_items:
- {name: 'user1',group: 'g1'}
- {name: 'user2',group: 'g2'}
- {name: 'user3',group: 'g3'}
執行劇本並查看執行結果,此時可以看到對方主機已經創建了三個用戶:
[root@ansibleplaybook]#ansible-playbook test_temp.yml 執行劇本內容
PLAY [webs] **********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.34.103]
TASK [create groups] ************************************************************************************************
changed: [192.168.34.103] => (item=g1)
changed: [192.168.34.103] => (item=g2)
changed: [192.168.34.103] => (item=g3)
TASK [create users] **************************************************************************************************
changed: [192.168.34.103] => (item={u'group': u'g1', u'name': u'user1'})
changed: [192.168.34.103] => (item={u'group': u'g2', u'name': u'user2'})
changed: [192.168.34.103] => (item={u'group': u'g3', u'name': u'user3'})
PLAY RECAP ***********************************************************************************************************
192.168.34.103 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansibleplaybook]#ansible webs -a "id user1" 查看執行后的用戶,核實是否正確
192.168.34.103 | CHANGED | rc=0 >>
uid=1002(user1) gid=1002(g1) groups=1002(g1)
[root@ansibleplaybook]#ansible webs -a "id user2"
192.168.34.103 | CHANGED | rc=0 >>
uid=1003(user2) gid=1003(g2) groups=1003(g2)
[root@ansibleplaybook]#ansible webs -a "id user3"
192.168.34.103 | CHANGED | rc=0 >>
uid=1004(user3) gid=1004(g3) groups=1004(g3)
示例三:
同時安裝多個包:
[root@ansibleplaybook]#vim test.yml
---
- hosts: webs
remote_user: root
tasks:
- name: install
yum: name=httpd,vsftpd,memcached
執行劇本,並查看當前的已經安裝好的包:
[root@ansibleplaybook]#ansible-playbook test.yml 執行劇本 PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [install] ******************************************************************************************************* changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansibleplaybook]#ansible webs -a "rpm -q httpd,vsftp,memcached" 查看此時的包是否被安裝 [WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.34.103 | FAILED | rc=1 >> package httpd,vsftp,memcached is not installednon-zero return code
等同於上面的寫法:也是同時安裝多個軟件
[root@ansibleplaybook]#vim test.yml
---
- hosts: webs
remote_user: root
tasks:
- name: install
yum: name={{item}}
with_items:
- httpd
- vsftpd
- memcached
7、template之for和if
通過使用for,if可以更加靈活的生成配置文件等需求,還可以在里面根據各種條件進行判斷,然后生成不同的配置文件、或者服務器配置相關等。
(1)編寫playbook
[root@ansibleplaybook]#vim for_temp.yml
---
- hosts: webs
remote_user: root
vars:
ports:
- 81
- 82
- 83
tasks:
- name: template
template: src=test_for.conf.j2 dest=/data/test_for.conf
(2)模板文件編寫
vim templates/test_for.conf.j2
{% for i in ports %}
server{
listen {{i}}
}
{% endfor %}
(3)執行劇本並查看復制到對方主機的文件內容:
[root@ansibleplaybook]#ansible-playbook for_temp.yml
PLAY [webs] **********************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [192.168.34.103]
TASK [template] ******************************************************************************************************
changed: [192.168.34.103]
PLAY RECAP ***********************************************************************************************************
192.168.34.103 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansibleplaybook]#ansible webs -a "cat /data/test_for.conf "
192.168.34.103 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
用字典寫法將上面的內容輸出同樣的名稱:
[root@ansibleplaybook]#vim for_temp.yml
---
- hosts: webs
remote_user: root
vars:
ports:
- listen_port: 81
- listen_port: 82
- listen_port: 83
tasks:
- name: template
template: src=test_for.conf.j2 dest=/data/test_for.conf
修改模板內容,和上面的for語句輸出內容一致:
[root@ansibleplaybook]#vim templates/test_for.conf.j2
{% for i in ports %}
server{
listen {{i.lsiten_port}}
}
{% endfor %}
~
示例:
編寫playbook
[root@ansibleplaybook]#vim for_temp.yml
---
- hosts: webs
remote_user: root
vars:
vhosts:
- host1:
listen_port: 81
host_name: www.a.com
dirname: /data/www1
- host2:
listen_port: 82
host_name: www.b.com
dirname: /data/www2
- host3:
listen_port: 83
host_name: www.c.com
dirname: /data/www3
tasks:
- name: template
template: src=test_for.conf.j2 dest=/data/test_for.conf
編寫jianjia2(j.2)文件
[root@ansibleplaybook]#vim templates/test_for.conf.j2
{% for i in vhosts %}
server{
listen {{i.listen_port}}
server_name {{i.host_name}}
root {{i.dirname}}
}
{% endfor %}
執行playbook並查看對方的目錄文件
[root@ansibleplaybook]#ansible-playbook for_temp.yml
[root@ansibleplaybook]#ansible webs -a "cat /data/test_for.conf"
192.168.34.103 | CHANGED | rc=0 >>
server{
listen 81
server_name www.a.com
root /data/www1
}
server{
listen 82
server_name www.b.com
root /data/www2
}
server{
listen 83
server_name www.c.com
root /data/www3
}
示例:在for循環中再嵌套if判斷,讓生成的配置文件更加靈活
編寫playbook
---
- hosts: webs
remote_user: root
vars:
vhosts:
- host1:
listen_port: 81
host_name: www.a.com
dirname: /data/www1
- host2:
listen_port: 82
#host_name: www.b.com 將此行注釋掉
dirname: /data/www2
- host3:
listen_port: 83
host_name: www.c.com
dirname: /data/www3
tasks:
- name: template
template: src=test_for.conf.j2 dest=/data/test_for.conf
編寫jianjia2文件(j.2)
[root@ansibleplaybook]#vim templates/test_for.conf.j2
{% for i in vhosts %}
server{
listen {{i.listen_port}}
{% if i.host_name is defined %}
server_name {{i.host_name}}
{% endif %}
root {{i.dirname}}
}
{% endfor %}
執行playbook並查看執行結果:
[root@ansibleplaybook]#ansible-playbook for_temp.yml
[root@ansibleplaybook]#ansible webs -a "cat /data/test_for.conf"
192.168.34.103 | CHANGED | rc=0 >>
server{
listen 81
server_name www.a.com
root /data/www1
}
server{
listen 82 此時中間就少了server_name定義的值
root /data/www2
}
server{
listen 83
server_name www.c.com
root /data/www3
}
Roles介紹:
ansible自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令引入即可。簡單來講,roles就是通過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並可以便捷的include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。主要使用場景代碼復用度較高的情況下。
roles目錄結構:

roles目錄含義:
roles: <--所有的角色必須放在roles目錄下,這個目錄可以自定義位置,默認的位置在/etc/ansible/roles
project: <---具體的角色項目名稱,比如nginx、tomcat、php
files: <--用來存放由copy模塊或script模塊調用的文件。
templates: <--用來存放jinjia2模板,template模塊會自動在此目錄中尋找jinjia2模板文件。
tasks: <--此目錄應當包含一個main.yml文件,用於定義此角色的任務列表,此文件可以使用include包含其它的位於此目錄的task文件。
main.yml
handlers: <--此目錄應當包含一個main.yml文件,用於定義此角色中觸發條件時執行的動作。
main.yml
vars: <--此目錄應當包含一個main.yml文件,用於定義此角色用到的變量。
main.yml
defaults: <--此目錄應當包含一個main.yml文件,用於為當前角色設定默認變量。
main.yml
meta: <--此目錄應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關系。
main.yml
(1)創建httpd服務的roles(角色):
新建文件夾,具體文件夾如下:
[root@ansibleplaybook]#mkdir roles
[root@ansibleplaybook]#mkdir roles/{httpd,nginx,mysql}
[root@ansibleplaybook]#mkdir roles/{httpd,nginx,mysql}/{tasks,files,templates,handlers,vars}
復制本地的httpd.conf文件,當做實驗備用:
cp /etc/httpd/conf/httpd.conf files/
查看具體的文件結構:
[root@ansibleplaybook]#tree roles/
roles/
├── httpd
│ ├── files
│ │ └── httpd.conf
│ ├── handlers
│ ├── tasks
│ │ ├── config.yml
│ │ ├── group.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── service.yml
│ │ └── user.yml
│ ├── templates
│ └── vars
├── mysql
│ ├── files
│ ├── handlers
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx
├── files
├── handlers
├── tasks
├── templates
└── vars
編寫httpd目錄下tasks目錄文件內容:
創建將文件復制到對方主機上的文件:
[root@ansibletasks]#vim config.yml - name: config file copy: src=httpd.conf dest=/etc/httpd/conf backup=yes
創建用戶:
[root@ansibletasks]#vim group.yml - name: create group group: name=apache system=yes gid=80
創建安裝配置文件:
[root@ansibletasks]#vim install.yml - name: install package yum: name=httpd
創建服務的文件:
[root@ansibletasks]#vim service.yml - name: service service: name=httpd state=started enabled=yes
創建用戶文件:
[root@ansibletasks]#cat user.yml - name: create user user: name=apache group=apache uid=80 shell=/sbin/nologin home=/usr/share/httpd system=yes
將所有的文件關聯起來,並按順序排列:
[root@ansibletasks]#cat main.yml - include: group.yml - include: user.yml - include: install.yml - include: config.yml - include: service.yml
將httpd.conf配置文件的端口修改為9527:
[root@ansibleroles]#vim httpd/files/httpd.conf Listen 9527
編寫playbook劇本,用來調用httpd整個目錄下的內容:
[root@ansibleplaybook]#vim httpd_roles.yml
- hosts: webs
remote_user: root
roles:
- role: httpd
編寫一個網站文件,並在屏幕上顯示,驗證當前的信息:
[root@ansibleroles]#vim httpd/files/index.html <h1>welcome to beijing!</h1>
將創建的index.html數據復制到/var/www/html目錄下,相當於是給頁面准備一個文件:
[root@ansibleroles]#vim httpd/tasks/data.yml - name: data file copy: src=index.html dest=/var/www/html/
將創建的數據放到main.yml文件中,按順序進行執行:
[root@ansibleroles]#vim httpd/tasks/main.yml - include: group.yml - include: user.yml - include: install.yml - include: config.yml - include: service.yml - include: data.yml
查看當前創建的目錄文件結構:
[root@ansibleplaybook]#tree roles/httpd roles/httpd ├── files │ ├── httpd.conf │ └── index.html ├── handlers ├── tasks │ ├── config.yml │ ├── data.yml │ ├── group.yml │ ├── install.yml │ ├── main.yml │ ├── service.yml │ └── user.yml ├── templates └── vars
執行playbook
[root@ansibleplaybook]#ansible-playbook httpd_roles.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : install package] *************************************************************************************** ok: [192.168.34.103] TASK [httpd : config file] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** ok: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看httpd端口開啟情況:
[root@ansibleplaybook]#ansible webs -a "ss -nlt" 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:139 *:* LISTEN 0 128 *:82 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 50 *:445 *:* LISTEN 0 50 :::139 :::* LISTEN 0 128 :::80 :::* LISTEN 0 32 :::21 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 :::9527 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 50 :::445 :::*
查看網頁信息打開情況:

(2)創建nginx服務的roles(角色):
1、將之前httpd做實驗的子目錄文件都復制一份到nginx目錄下:
[root@ansibleplaybook]#cd roles/ [root@ansibleroles]#ls httpd mysql [root@ansibleroles]#rm -rf nginx/ [root@ansibleroles]#cp -r httpd/ nginx
2、將roles/nginx/tasks/main.yml文件順序進行修改:
[root@ansibleplaybook]#vim roles/nginx/tasks/main.yml - include: install.yml - include: config.yml - include: service.yml
3、刪除多余的tasks目錄下的文件:
[root@ansiblenginx]#cd tasks/ [root@ansibletasks]#ls config.yml data.yml group.yml install.yml main.yml service.yml user.yml [root@ansibletasks]#rm -rf group.yml user.yml
4、修改config.yml配置文件,使用template模板形式進行修改:
[root@ansibletasks]#vim config.yml - name: config file template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
5、將本地已安裝好的nginx的nginx.conf配置文件復制到template目錄下,起名叫nginx.conf.j2
[root@ansiblenginx]#yum install nginx -y [root@ansiblenginx]#cp /etc/nginx/nginx.conf templates/nginx.conf.j2
6、修改nginx/templates/nginx.conf.j2配置文件的CPU內核:
[root@ansibletemplates]#vim nginx.conf.j2
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes {{ansible_processor_count**3}};
7、跨角色調用httpd服務文件內容:
[root@ansiblenginx]#vim tasks/data.yml - name: data copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/
8、將data.yml放入到main.yml文件中、安裝的nginx軟件名稱修改,以及要啟動的服務名稱修改:
[root@ansiblenginx]#vim tasks/main.yml
- include: install.yml
- include: config.yml
- include: service.yml
- include: data.yml
[root@ansiblenginx]#vim tasks/install.yml 將安裝的nginx文件名修改
- name: install package
yum: name=nginx
[root@ansiblenginx]#vim tasks/service.yml 將啟動的服務名稱修改
- name: service
service: name=nginx state=started enabled=yes
9、最后在playbook目錄下創建nginx_rolee.yml配置文件(跟roles目錄平級):
[root@ansibleplaybook]#vim nginx_roles.yml
- hosts: webs
remote_user: root
roles:
- role: nginx
- role: httpd
10、執行playbook
[root@ansibleplaybook]#ansible-playbook nginx_roles.yml 執行劇本 [root@ansibleplaybook]#ansible webs -a "ss -nlt" 查看當前的端口執行情況:80和9527端口都已打開 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:139 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 50 *:445 *:* LISTEN 0 50 :::139 :::* LISTEN 0 128 :::80 :::* LISTEN 0 32 :::21 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 :::9527 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 50 :::445 :::*
10、此時用nginx服務默認的80端口已經可以打開網頁,已經實現了跨角色調用文件:

(3)如果觸發notify和handlers兩個角色,可以修改相關文件,具體如下:
[root@ansibleplaybook]#vim roles/nginx/tasks/config.yml - name: config file template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart 此處的名稱要和handlers一致
[root@ansibleplaybook]#vim roles/nginx/handlers/main.yml
- name: restart service: name=nginx state=restarted
為了驗證重啟效果,此時我們可以將nginx.conf.j2配置文件的端口修改為8080:
[root@ansibleplaybook]#vim roles/nginx/templates/nginx.conf.j2
server {
listen 8080 default_server;
執行playbook
[root@ansibleplaybook]#ansible-playbook nginx_roles.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [nginx : install package] *************************************************************************************** ok: [192.168.34.103] TASK [nginx : config file] ******************************************************************************************* changed: [192.168.34.103] TASK [nginx : service] *********************************************************************************************** ok: [192.168.34.103] TASK [nginx : data] ************************************************************************************************** ok: [192.168.34.103] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : install package] *************************************************************************************** ok: [192.168.34.103] TASK [httpd : config file] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** ok: [192.168.34.103] TASK [httpd : data file] ********************************************************************************************* ok: [192.168.34.103] RUNNING HANDLER [nginx : restart] ************************************************************************************ changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=12 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看當前運行結果,此時的控制的機器nginx端口打開的是8080:
[root@ansibleplaybook]#ansible webs -a "ss -nlt"
192.168.34.103 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:139 *:*
LISTEN 0 128 *:8080 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 50 *:445 *:*
LISTEN 0 50 :::139 :::*
LISTEN 0 128 :::80 :::*
LISTEN 0 32 :::21 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 :::9527 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 50 :::445 :::*
下來,我們添加變量格式:
[root@ansibleplaybook]#vim roles/nginx/vars/main.yml username: daemon
將roles/nginx/templates/nginx.conf.j2配置文件的名稱修改:
[root@ansibleplaybook]#vim roles/nginx/templates/nginx.conf.j2
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user {{username}};
執行playbook
[root@ansibleplaybook]#ansible-playbook nginx_roles.yml PLAY [webs] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] TASK [nginx : install package] *************************************************************************************** ok: [192.168.34.103] TASK [nginx : config file] ******************************************************************************************* changed: [192.168.34.103] TASK [nginx : service] *********************************************************************************************** ok: [192.168.34.103] TASK [nginx : data] ************************************************************************************************** ok: [192.168.34.103] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : install package] *************************************************************************************** ok: [192.168.34.103] TASK [httpd : config file] ******************************************************************************************* ok: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** ok: [192.168.34.103] TASK [httpd : data file] ********************************************************************************************* ok: [192.168.34.103] RUNNING HANDLER [nginx : restart] ************************************************************************************ changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=12 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看當前的nginx的名稱,此時已經修改為daemon:
[root@ansibleplaybook]#ansible webs -a "ps aux | grep nginx"
192.168.34.103 | CHANGED | rc=0 >>
root 25536 0.0 0.1 120796 2092 ? Ss 10:47 0:00 nginx: master process /usr/sbin/nginx
daemon 25537 0.0 0.1 121180 3124 ? S 10:47 0:00 nginx: worker process
root 25602 0.0 0.0 113176 1216 pts/1 S+ 10:48 0:00 /bin/sh -c ps aux | grep nginx
root 25604 0.0 0.0 112708 960 pts/1 R+ 10:48 0:00 grep nginx
(4)實現條件判斷調用角色:
[root@ansibleplaybook]#vim roles/httpd/tasks/config.yml - name: config file1 template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf backup=yes when: ansible_distribution_major_version=="6" - name: config file2 template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf backup=yes when: ansible_distribution_major_version=="7"
將安裝好的centos6和centos7的httpd配置文件復制到roles/httpd/templates/目錄下,文件名后綴都是以.j2結尾:
[root@centos6~]#scp /etc/httpd/conf/httpd.conf 192.168.34.101:/root/playbook/roles/httpd/templates/httpd6.conf.j2 root@192.168.34.101's password: httpd.conf 100% 34KB 33.6KB/s 00:00
將centos7的httpd.conf配置文件也放在roles/httpd/templates/目錄下,起名以j2結尾:
[root@ansibleplaybook]#cp /etc/httpd/conf/httpd.conf roles/httpd/templates/httpd7.conf.j2
修改當前的http_roles.yml配置文件,里邊的apps組才有centos6和7的版本:
[root@ansibleplaybook]#vim http_roles.yml
- hosts: apps
remote_user: root
roles:
- role: httpd
執行playbook劇本:
[root@ansibleplaybook]#ansible-playbook http_roles.yml PLAY [apps] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : install package] *************************************************************************************** changed: [192.168.34.105] changed: [192.168.34.103] TASK [httpd : config file1] ****************************************************************************************** skipping: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : config file2] ****************************************************************************************** skipping: [192.168.34.105] changed: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : data file] ********************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.34.105 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
查看安裝好后的httpd運行結果:
[root@ansibleplaybook]#ansible apps -a "ss -nltp"
192.168.34.103 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:139 *:* users:(("smbd",pid=6721,fd=36))
LISTEN 0 128 *:80 *:* users:(("httpd",pid=27209,fd=3),("httpd",pid=27208,fd=3),("httpd",pid=27207,fd=3),("httpd",pid=27206,fd=3),("httpd",pid=27205,fd=3),("httpd",pid=27204,fd=3))
LISTEN 0 128 *:8080 *:* users:(("nginx",pid=25537,fd=6),("nginx",pid=25536,fd=6))
LISTEN 0 128 *:22 *:* users:(("sshd",pid=6719,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=6818,fd=13))
LISTEN 0 50 *:445 *:* users:(("smbd",pid=6721,fd=35))
LISTEN 0 50 :::139 :::* users:(("smbd",pid=6721,fd=34))
LISTEN 0 128 :::80 :::* users:(("nginx",pid=25537,fd=7),("nginx",pid=25536,fd=7))
LISTEN 0 32 :::21 :::* users:(("vsftpd",pid=6718,fd=4))
LISTEN 0 128 :::22 :::* users:(("sshd",pid=6719,fd=4))
LISTEN 0 100 ::1:25 :::* users:(("master",pid=6818,fd=14))
LISTEN 0 50 :::445 :::* users:(("smbd",pid=6721,fd=33))
192.168.34.105 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:6010 *:* users:(("sshd",5804,7))
LISTEN 0 128 ::1:6010 :::* users:(("sshd",5804,6))
LISTEN 0 128 :::43999 :::* users:(("rpc.statd",1781,10))
LISTEN 0 128 :::111 :::* users:(("rpcbind",1674,11))
LISTEN 0 128 *:111 *:* users:(("rpcbind",1674,8))
LISTEN 0 128 *:58740 *:* users:(("rpc.statd",1781,8))
LISTEN 0 128 :::22 :::* users:(("sshd",2079,4))
LISTEN 0 128 *:22 *:* users:(("sshd",2079,3))
LISTEN 0 128 :::87 :::* users:(("httpd",8981,6),("httpd",9097,6),("httpd",9098,6),("httpd",9099,6),("httpd",9100,6),("httpd",9101,6),("httpd",9102,6),("httpd",9103,6),("httpd",9104,6))
LISTEN 0 64 :::23 :::* users:(("xinetd",2103,5))
LISTEN 0 128 127.0.0.1:631 *:* users:(("cupsd",1826,7))
LISTEN 0 128 ::1:631 :::* users:(("cupsd",1826,6))
LISTEN 0 100 ::1:25 :::* users:(("master",2209,13))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",2209,12))
(5)使用標簽實現playbook角色調用:
[root@ansibleplaybook]#vim all_roles.yml
- hosts: all
remote_user: root
roles:
- {role: httpd,tags: ["httpd","web"]} 將兩個服務整體作為一個字典,然后貼上標簽:
- {role: nginx,tags: ["nginx","web"]}
- {role: mysql,tags: db}
執行標簽的其中一個playbook內容:
[root@ansibleplaybook]#ansible-playbook -t httpd all_roles.yml PLAY [all] *********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : install package] *************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : config file1] ****************************************************************************************** skipping: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : config file2] ****************************************************************************************** skipping: [192.168.34.105] changed: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : data file] ********************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.34.105 : ok=7 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
查看執行后的內容:
[root@ansibleplaybook]#ansible all -a "ss -nlt" 192.168.34.103 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:139 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 50 *:445 *:* LISTEN 0 50 :::139 :::* LISTEN 0 128 :::80 :::* LISTEN 0 32 :::21 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 50 :::445 :::* 192.168.34.105 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:6010 *:* LISTEN 0 128 ::1:6010 :::* LISTEN 0 128 :::43999 :::* LISTEN 0 128 :::111 :::* LISTEN 0 128 *:111 *:* LISTEN 0 128 *:58740 *:* LISTEN 0 128 :::22 :::* LISTEN 0 128 *:22 *:* LISTEN 0 128 :::87 :::* LISTEN 0 64 :::23 :::* LISTEN 0 128 127.0.0.1:631 *:* LISTEN 0 128 ::1:631 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 100 127.0.0.1:25 *:*
執行web標簽的playbook,就會將定義標簽的httpd和nginx兩個文件都執行:
[root@ansibleplaybook]#ansible-playbook -t web all_roles.yml PLAY [apps] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create group] ****************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : create user] ******************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] TASK [httpd : install package] *************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : config file1] ****************************************************************************************** skipping: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : config file2] ****************************************************************************************** skipping: [192.168.34.105] changed: [192.168.34.103] TASK [httpd : service] *********************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [httpd : data file] ********************************************************************************************* ok: [192.168.34.103] ok: [192.168.34.105] TASK [nginx : install package] *************************************************************************************** changed: [192.168.34.105] changed: [192.168.34.103] TASK [nginx : config file] ******************************************************************************************* changed: [192.168.34.103] changed: [192.168.34.105] TASK [nginx : service] *********************************************************************************************** changed: [192.168.34.105] changed: [192.168.34.103] TASK [nginx : data] ************************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] RUNNING HANDLER [nginx : restart] ************************************************************************************ changed: [192.168.34.103] changed: [192.168.34.105] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=12 changed=8 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.34.105 : ok=12 changed=8 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
查看執行結果的狀態:
[root@ansibleplaybook]#ansible apps -a "ss -nlpt"
192.168.34.103 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:139 *:* users:(("smbd",pid=6721,fd=36))
LISTEN 0 128 *:8080 *:* users:(("nginx",pid=38028,fd=6),("nginx",pid=38027,fd=6))
LISTEN 0 128 *:22 *:* users:(("sshd",pid=6719,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=6818,fd=13))
LISTEN 0 50 *:445 *:* users:(("smbd",pid=6721,fd=35))
LISTEN 0 50 :::139 :::* users:(("smbd",pid=6721,fd=34))
LISTEN 0 32 :::21 :::* users:(("vsftpd",pid=6718,fd=4))
LISTEN 0 128 :::22 :::* users:(("sshd",pid=6719,fd=4))
LISTEN 0 100 ::1:25 :::* users:(("master",pid=6818,fd=14))
LISTEN 0 128 :::90 :::* users:(("nginx",pid=38028,fd=7),("nginx",pid=38027,fd=7))
LISTEN 0 50 :::445 :::* users:(("smbd",pid=6721,fd=33))
LISTEN 0 128 :::99 :::* users:(("httpd",pid=37535,fd=4),("httpd",pid=37534,fd=4),("httpd",pid=37533,fd=4),("httpd",pid=37532,fd=4),("httpd",pid=37531,fd=4),("httpd",pid=37530,fd=4))
192.168.34.105 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:6010 *:* users:(("sshd",5804,7))
LISTEN 0 128 ::1:6010 :::* users:(("sshd",5804,6))
LISTEN 0 128 :::43999 :::* users:(("rpc.statd",1781,10))
LISTEN 0 128 :::111 :::* users:(("rpcbind",1674,11))
LISTEN 0 128 *:111 *:* users:(("rpcbind",1674,8))
LISTEN 0 128 *:58740 *:* users:(("rpc.statd",1781,8))
LISTEN 0 128 :::8181 :::* users:(("httpd",20990,6),("httpd",21802,6),("httpd",21803,6),("httpd",21804,6),("httpd",21805,6),("httpd",21806,6),("httpd",21807,6),("httpd",21808,6),("httpd",21809,6))
LISTEN 0 128 :::22 :::* users:(("sshd",2079,4))
LISTEN 0 128 *:22 *:* users:(("sshd",2079,3))
LISTEN 0 64 :::23 :::* users:(("xinetd",2103,5))
LISTEN 0 128 127.0.0.1:631 *:* users:(("cupsd",1826,7))
LISTEN 0 128 ::1:631 :::* users:(("cupsd",1826,6))
LISTEN 0 100 ::1:25 :::* users:(("master",2209,13))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",2209,12))
(6)做一個memcached小實驗:
目的:是為了定義當前緩存服務器在內存中占比,應該設置多大?
安裝memcached:
[root@ansibleplaybook]#yum install memcached -y [root@ansibleplaybook]#cat /etc/sysconfig/memcached PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" 當前的緩存大小 OPTIONS=""
定義memcached角色:
[root@ansibleroles]#cd roles [root@ansibleroles]#cp httpd/ memcached -r 將httpd服務復制memcached,在里邊進行修改
刪除之前指定的httpd相關文件:
[root@ansibletasks]#cd roles/memcached/tasks
[root@ansibletasks]#rm -f data.yml user.yml group.yml 刪除不需要的文件
[root@ansiblememcached]#cp /etc/sysconfig/memcached templates/memcached.j2 復制memcached到templates目錄下,起名叫memcached.j2
[root@ansiblememcached]#vim templates/memcache.j2 修改memcached相關配置
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}" 將變量進行整除。
OPTIONS=""
修改配置文件:
[root@ansiblememcached]#vim tasks/config.yml - name: config file1 template: src=memcached.j2 dest=/etc/sysconfig/memcached backup=yes
修改main.yml配置文件:
[root@ansiblememcached]#vim tasks/main.yml - include: install.yml - include: config.yml - include: service.yml
修改安裝配置文件
[root@ansiblememcached]#vim tasks/install.yml - name: install package yum: name=memcached
配置啟動服務文件:
[root@ansiblememcached]#vim tasks/service.yml - name: service service: name=memcached state=started enabled=yes
然后在playbook目錄下創建一個roles角色playbook劇本:
[root@ansibleplaybook]#vim test_memcached.yml
- hosts: apps
remote_user: root
roles:
- role: memcached
然后將centos6和centos7的內存大小分別調整為3G和2G,執行playbook:
[root@ansibleplaybook]#ansible-playbook test_memcached.yml PLAY [apps] ********************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [192.168.34.103] ok: [192.168.34.105] TASK [memcached : install package] *********************************************************************************** ok: [192.168.34.103] changed: [192.168.34.105] TASK [memcached : config file1] ************************************************************************************** changed: [192.168.34.103] changed: [192.168.34.105] TASK [memcached : service] ******************************************************************************************* changed: [192.168.34.105] changed: [192.168.34.103] PLAY RECAP *********************************************************************************************************** 192.168.34.103 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.34.105 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看對方的內存大小情況,可以看到,之前的內存大小默認是64,此時已經有所改變:
[root@ansibleplaybook]#ansible apps -a "cat /etc/sysconfig/memcached" 192.168.34.103 | CHANGED | rc=0 >> PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="496" OPTIONS="" 192.168.34.105 | CHANGED | rc=0 >> PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="244" OPTIONS=""
ansible roles總結
1、編寫任務(task)的時候,里面不需要寫需要執行的主機,單純的寫某個任務是干什么的即可,裝軟件的就是裝軟件的,啟動的就是啟動的。單獨做某一件事即可,最后通過main.yml將這些單獨的任務安裝執行順序include進來即可,這樣方便維護且一目了然。 2、定義變量時候直接安裝k:v格式將變量寫在vars/main.yml文件即可,然后task或者template直接調用即可,會自動去vars/main.yml文件里面去找。 3、定義handlers時候,直接在handlers/main.yml文件中寫需要做什么事情即可,多可的話可以全部寫在該文件里面,也可以像task那樣分開來寫,通過include引入一樣的可以。在task調用notify時直接寫與handlers名字對應即可(二者必須高度一直)。 4、模板文件一樣放在templates目錄下即可,task調用的時候直接寫文件名字即可,會自動去到templates里面找。注意:如果是一個角色調用另外一個角色的單個task時候,那么task中如果有些模板或者文件,就得寫絕對路徑了。
