天天看點

python自動化運維工具執行個體_自動化運維工具——ansible詳解(一)

ansible 簡介

ansible 是什麼?

ansible是新出現的自動化運維工具,基于Python開發,集合了衆多運維工具(puppet、chef、func、fabric)的優點,實作了批量系統配置、批量程式部署、批量運作指令等功能。

ansible是基于 paramiko 開發的,并且基于子產品化工作,本身沒有批量部署的能力。真正具有批量部署的是ansible所運作的子產品,ansible隻是提供一種架構。ansible不需要在遠端主機上安裝client/agents,因為它們是基于ssh來和遠

程主機通訊的。ansible目前已經已經被紅帽官方收購,是自動化運維工具中大家認可度最高的,并且上手容易,學習簡單。是每位運維工程師必須掌握的技能之一。

ansible 特點

部署簡單,隻需在主要端部署Ansible環境,被控端無需做任何操作;

預設使用SSH協定對裝置進行管理;

有大量正常運維操作子產品,可實作日常絕大部分操作;

配置簡單、功能強大、擴充性強;

支援API及自定義子產品,可通過Python輕松擴充;

通過Playbooks來定制強大的配置、狀态管理;

輕量級,無需在用戶端安裝agent,更新時,隻需在操作機上進行一次更新即可;

提供一個功能強大、操作性強的Web管理界面和REST API接口——AWX平台。

ansible 架構圖

python自動化運維工具執行個體_自動化運維工具——ansible詳解(一)

上圖中我們看到的主要子產品如下:

Ansible:Ansible核心程式。

HostInventory:記錄由Ansible管理的主機資訊,包括端口、密碼、ip等。

Playbooks:“劇本”YAML格式檔案,多個任務定義在一個檔案中,定義主機需要調用哪些子產品來完成的功能。

CoreModules:核心子產品,主要操作是通過調用核心子產品來完成管理任務。

CustomModules:自定義子產品,完成核心子產品無法完成的功能,支援多種語言。

ConnectionPlugins:連接配接插件,Ansible和Host通信使用

ansible 任務執行

ansible 任務執行模式

Ansible 系統由控制主機對被管節點的操作方式可分為兩類,即adhoc和playbook:

ad-hoc模式(點對點模式)

使用單個子產品,支援批量執行單條指令。ad-hoc 指令是一種可以快速輸入的指令,而且不需要儲存起來的指令。就相當于bash中的一句話shell。

playbook模式(劇本模式)

是Ansible主要管理方式,也是Ansible功能強大的關鍵所在。playbook通過多個task集合完成一類功能,如Web服務的安裝部署、資料庫伺服器的批量備份等。可以簡單地把playbook了解為通過組合多條ad-hoc操作的配置檔案。

ansible 執行流程

python自動化運維工具執行個體_自動化運維工具——ansible詳解(一)

簡單了解就是Ansible在運作時, 首先讀取ansible.cfg中的配置, 根據規則擷取Inventory中的管理主機清單, 并行的在這些主機中執行配置的任務, 最後等待執行傳回的結果。

ansible 指令執行過程

加載自己的配置檔案,預設/etc/ansible/ansible.cfg;

查找對應的主機配置檔案,找到要執行的主機或者組;

加載自己對應的子產品檔案,如 command;

通過ansible将子產品或指令生成對應的臨時py檔案(python腳本), 并将該檔案傳輸至遠端伺服器;

對應執行使用者的家目錄的.ansible/tmp/XXX/XXX.PY檔案;

給檔案 +x 執行權限;

執行并傳回結果;

删除臨時py檔案,sleep 0退出;

ansible 配置詳解

ansible 安裝方式

ansible安裝常用兩種方式,yum安裝和pip程式安裝。下面我們來詳細介紹一下這兩種安裝方式。

使用 pip(python的包管理子產品)安裝

首先,我們需要安裝一個python-pip包,安裝完成以後,則直接使用pip指令來安裝我們的包,具體操作過程如下:

yum install python-pip

pip install ansible

使用 yum 安裝

yum 安裝是我們很熟悉的安裝方式了。我們需要先安裝一個epel-release包,然後再安裝我們的 ansible 即可。

yum install epel-release -y

yum install ansible –y

ansible 程式結構

安裝目錄如下(yum安裝):

配置檔案目錄:/etc/ansible/

執行檔案目錄:/usr/bin/

Lib庫依賴目錄:/usr/lib/pythonX.X/site-packages/ansible/

Help文檔目錄:/usr/share/doc/ansible-X.X.X/

Man文檔目錄:/usr/share/man/man1/

ansible配置檔案查找順序

ansible與我們其他的服務在這一點上有很大不同,這裡的配置檔案查找是從多個地方找的,順序如下:

檢查環境變量ANSIBLE_CONFIG指向的路徑檔案(export ANSIBLE_CONFIG=/etc/ansible.cfg);

~/.ansible.cfg,檢查目前目錄下的ansible.cfg配置檔案;

/etc/ansible.cfg檢查etc目錄的配置檔案。

ansible配置檔案

ansible 的配置檔案為/etc/ansible/ansible.cfg,ansible 有許多參數,下面我們列出一些常見的參數:

inventory = /etc/ansible/hosts#這個參數表示資源清單inventory檔案的位置

library = /usr/share/ansible#指向存放Ansible子產品的目錄,支援多個目錄方式,隻要用冒号(:)隔開就可以

forks = 5#并發連接配接數,預設為5

sudo_user = root#設定預設執行指令的使用者

remote_port = 22#指定連接配接被管節點的管理端口,預設為22端口,建議修改,能夠更加安全

host_key_checking = False#設定是否檢查SSH主機的密鑰,值為True/False。關閉後第一次連接配接不會提示配置執行個體

timeout = 60#設定SSH連接配接的逾時時間,機關為秒

log_path = /var/log/ansible.log#指定一個存儲ansible日志的檔案(預設不記錄日志)

ansuble主機清單

在配置檔案中,我們提到了資源清單,這個清單就是我們的主機清單,裡面儲存的是一些 ansible 需要連接配接管理的主機清單。我們可以來看看他的定義方式:

1、 直接指明主機位址或主機名:

## green.example.com#

# blue.example.com#

# 192.168.100.1

# 192.168.100.10

2、 定義一個主機組[組名]把位址或主機名加進去

[mysql_test]

192.168.253.159

192.168.253.160

192.168.253.153

需要注意的是,這裡的組成員可以使用通配符來比對,這樣對于一些标準化的管理來說就很輕松友善了。

我們可以根據實際情況來配置我們的主機清單,具體操作如下:

[[email protected] ~]# vim /etc/ansible/hosts

[web]

192.168.37.122

192.168.37.133

ansible 常用指令

ansible 指令集

/usr/bin/ansible  Ansibe AD-Hoc 臨時指令執行工具,常用于臨時指令的執行

/usr/bin/ansible-doc   Ansible 子產品功能檢視工具

/usr/bin/ansible-galaxy  下載下傳/上傳優秀代碼或Roles子產品 的官網平台,基于網絡的

/usr/bin/ansible-playbook  Ansible 定制自動化的任務集編排工具

/usr/bin/ansible-pull  Ansible遠端執行指令的工具,拉取配置而非推送配置(使用較少,海量機器時使用,對運維的架構能力要求較高)

/usr/bin/ansible-vault  Ansible 檔案加密工具

/usr/bin/ansible-console  Ansible基于Linux Consoble界面可與使用者互動的指令執行工具

其中,我們比較常用的是/usr/bin/ansible和/usr/bin/ansible-playbook。

ansible-doc 指令

ansible-doc 指令常用于擷取子產品資訊及其使用幫助,一般用法如下:

ansible-doc -l#擷取全部子產品的資訊

ansible-doc -s MOD_NAME#擷取指定子產品的使用幫助

我們也可以檢視一下ansible-doc的全部用法:

[[email protected] ~]# ansible-doc

Usage: ansible-doc [options] [module...]

Options:

-h, --help show this help message and exit  # 顯示指令參數API文檔

-l, --list List available modules  #列出可用的子產品

-M MODULE_PATH, --module-path=MODULE_PATH  #指定子產品的路徑

specify path(s) to module library (default=None)

-s, --snippet Show playbook snippet for specified module(s)  #顯示playbook制定子產品的用法

-v, --verbose verbose mode (-vvv for more, -vvvv to enable  # 顯示ansible-doc的版本号檢視子產品清單:

connection debugging)

--version show program's version number and exit

我們可以來看一下,以mysql相關的為例:

[[email protected] ~]# ansible-doc -l |grep mysql

mysql_db Add or remove MySQL databases from a remote...

mysql_replication Manage MySQL replication

mysql_user Adds or removes a user from a MySQL databas...

mysql_variables Manage MySQL global variables

[[email protected] ~]# ansible-doc -s mysql_user

python自動化運維工具執行個體_自動化運維工具——ansible詳解(一)

ansible 指令詳解

指令的具體格式如下:

ansible [-f forks] [-m module_name] [-a args]

也可以通過ansible -h來檢視幫助,下面我們列出一些比較常用的選項,并解釋其含義:

-a MODULE_ARGS   #子產品的參數,如果執行預設COMMAND的子產品,即是指令參數,如: “date”,“pwd”等等

-k,--ask-pass#ask for SSH password。登入密碼,提示輸入SSH密碼而不是假設基于密鑰的驗證

--ask-su-pass#ask for su password。su切換密碼

-K,--ask-sudo-pass#ask for sudo password。提示密碼使用sudo,sudo表示提權操作

--ask-vault-pass#ask for vault password。假設我們設定了加密的密碼,則用該選項進行通路

-B SECONDS#背景運作逾時時間

-C#模拟運作環境并進行預運作,可以進行查錯測試

-c CONNECTION#連接配接類型使用

-f FORKS#并行任務數,預設為5

-i INVENTORY#指定主機清單的路徑,預設為/etc/ansible/hosts

--list-hosts#檢視有哪些主機組

-m MODULE_NAME#執行子產品的名字,預設使用 command 子產品,是以如果是隻執行單一指令可以不用 -m參數

-o#壓縮輸出,嘗試将所有結果在一行輸出,一般針對收集工具使用

-S#用 su 指令

-R SU_USER#指定 su 的使用者,預設為 root 使用者

-s#用 sudo 指令

-U SUDO_USER#指定 sudo 到哪個使用者,預設為 root 使用者

-T TIMEOUT#指定 ssh 預設逾時時間,預設為10s,也可在配置檔案中修改

-u REMOTE_USER#遠端使用者,預設為 root 使用者

-v#檢視詳細資訊,同時支援-vvv,-vvvv可檢視更詳細資訊

ansible 配置公私鑰

上面我們已經提到過 ansible 是基于 ssh 協定實作的,是以其配置公私鑰的方式與 ssh 協定的方式相同,具體操作步驟如下:

#1.生成私鑰

[[email protected] ~]# ssh-keygen

#2.向主機分發私鑰

[[email protected]r ~]# ssh-copy-id [email protected]

[[email protected] ~]# ssh-copy-id [email protected]

這樣的話,就可以實作無密碼登入,我們的實驗過程也會順暢很多。

注意,如果出現了一下報錯:

-bash: ssh-copy-id: command not found

那麼就證明我們需要安裝一個包:

yum -y install openssh-clientsansible

把包安裝上即可。

ansible 常用子產品

1)主機連通性測試

我們使用ansible web -m ping指令來進行主機連通性測試,效果如下:

[[email protected] ~]# ansible web -m ping

192.168.37.122 | SUCCESS => {

"changed": false,

"ping": "pong"

}

192.168.37.133 | SUCCESS => {

"changed": false,

"ping": "pong"

}

這樣就說明我們的主機是連通狀态的。接下來的操作才可以正常進行。

2)command 子產品

這個子產品可以直接在遠端主機上執行指令,并将結果傳回本主機。

舉例如下:

[[email protected] ~]# ansible web -m command -a 'ss -ntl'

192.168.37.122 | SUCCESS | rc=0 >>

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:111 *:*

LISTEN 0 5 192.168.122.1:53 *:*

LISTEN 0 128 *:22 *:*

LISTEN 0 128 127.0.0.1:631 *:*

LISTEN 0 128 *:23000 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 :::111 :::*

LISTEN 0 128 :::22 :::*

LISTEN 0 128 ::1:631 :::*

LISTEN 0 100 ::1:25 :::*

192.168.37.133 | SUCCESS | rc=0 >>

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:111 *:*

LISTEN 0 128 *:22 *:*

LISTEN 0 128 127.0.0.1:631 *:*

LISTEN 0 128 *:23000 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 :::111 :::*

LISTEN 0 128 :::22 :::*

LISTEN 0 128 ::1:631 :::*

LISTEN 0 100 ::1:25 :::*

指令子產品接受指令名稱,後面是空格分隔的清單參數。給定的指令将在所有標明的節點上執行。它不會通過shell進行處理,比如$HOME和操作如"","|",";","&" 工作(需要使用(shell)子產品實作這些功能)。注意,該指令不支援| 管道指令。

下面來看一看該子產品下常用的幾個指令:

chdir       # 在執行指令之前,先切換到該目錄

executable # 切換shell來執行指令,需要使用指令的絕對路徑

free_form  # 要執行的Linux指令,一般使用Ansible的-a參數代替。

creates  # 一個檔案名,當這個檔案存在,則該指令不執行,可以

用來做判斷

removes # 一個檔案名,這個檔案不存在,則該指令不執行

下面我們來看看這些指令的執行效果:

[[email protected] ~]# ansible web -m command -a 'chdir=/data/ ls'#先切換到/data/ 目錄,再執行“ls”指令

192.168.37.122 | SUCCESS | rc=0 >>

aaa.jpg

fastdfs

mogdata

tmp

web

wKgleloeYoCAMLtZAAAWEekAtkc497.jpg

192.168.37.133 | SUCCESS | rc=0 >>

aaa.jpg

fastdfs

mogdata

tmp

web

wKgleloeYoCAMLtZAAAWEekAtkc497.jpg

[[email protected] ~]# ansible web -m command -a 'creates=/data/aaa.jpg ls'#如果/data/aaa.jpg存在,則不執行“ls”指令

192.168.37.122 | SUCCESS | rc=0 >>

skipped, since /data/aaa.jpg exists

192.168.37.133 | SUCCESS | rc=0 >>

skipped, since /data/aaa.jpg exists

[[email protected] ~]# ansible web -m command -a 'removes=/data/aaa.jpg cat /data/a'#如果/data/aaa.jpg存在,則執行“cat /data/a”指令

192.168.37.122 | SUCCESS | rc=0 >>

hello

192.168.37.133 | SUCCESS | rc=0 >>

hello

3)shell 子產品

shell子產品可以在遠端主機上調用shell解釋器運作指令,支援shell的各種功能,例如管道等。

[[email protected] ~]# ansible web -m shell -a 'cat /etc/passwd |grep "keer"'

192.168.37.122 | SUCCESS | rc=0 >>

keer:x:10001:1000:keer:/home/keer:/bin/sh

192.168.37.133 | SUCCESS | rc=0 >>

keer:x:10001:10001::/home/keer:/bin/sh

隻要是我們的shell指令,都可以通過這個子產品在遠端主機上運作,這裡就不一一舉例了。

4)copy 子產品

這個子產品用于将檔案複制到遠端主機,同時支援給定内容生成檔案和修改權限等。

其相關選項如下:

src    #被複制到遠端主機的本地檔案。可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,則會遞歸複制,用法類似于"rsync"

content   #用于替換"src",可以直接指定檔案的值

dest    #必選項,将源檔案複制到的遠端主機的絕對路徑

backup   #當檔案内容發生改變後,在覆寫之前把源檔案備份,備份檔案包含時間資訊

directory_mode    #遞歸設定目錄的權限,預設為系統預設權限

force    #當目标主機包含該檔案,但内容不同時,設為"yes",表示強制覆寫;設為"no",表示目标主機的目标位置不存在該檔案才複制。預設為"yes"

others    #所有的 file 子產品中的選項可以在這裡使用

用法舉例如下:

① 複制檔案:

[[email protected] ~]# ansible web -m copy -a 'src=~/hello dest=/data/hello'

192.168.37.122 | SUCCESS => {

"changed": true,

"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"dest": "/data/hello",

"gid": 0,

"group": "root",

"md5sum": "6f5902ac237024bdd0c176cb93063dc4",

"mode": "0644",

"owner": "root",

"size": 12,

"src": "/root/.ansible/tmp/ansible-tmp-1512437093.55-228281064292921/source",

"state": "file",

"uid": 0

}

192.168.37.133 | SUCCESS => {

"changed": true,

"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"dest": "/data/hello",

"gid": 0,

"group": "root",

"md5sum": "6f5902ac237024bdd0c176cb93063dc4",

"mode": "0644",

"owner": "root",

"size": 12,

"src": "/root/.ansible/tmp/ansible-tmp-1512437093.74-44694985235189/source",

"state": "file",

"uid": 0

}

② 給定内容生成檔案,并制定權限

[[email protected] ~]# ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'

192.168.37.122 | SUCCESS => {

"changed": true,

"checksum": "0421570938940ea784f9d8598dab87f07685b968",

"dest": "/data/name",

"gid": 0,

"group": "root",

"md5sum": "497fa8386590a5fc89090725b07f175c",

"mode": "0666",

"owner": "root",

"size": 10,

"src": "/root/.ansible/tmp/ansible-tmp-1512437327.37-199512601767687/source",

"state": "file",

"uid": 0

}

192.168.37.133 | SUCCESS => {

"changed": true,

"checksum": "0421570938940ea784f9d8598dab87f07685b968",

"dest": "/data/name",

"gid": 0,

"group": "root",

"md5sum": "497fa8386590a5fc89090725b07f175c",

"mode": "0666",

"owner": "root",

"size": 10,

"src": "/root/.ansible/tmp/ansible-tmp-1512437327.55-218104039503110/source",

"state": "file",

"uid": 0

}

我們現在可以去檢視一下我們生成的檔案及其權限:

[[email protected] ~]# ansible web -m shell -a 'ls -l /data/'

192.168.37.122 | SUCCESS | rc=0 >>

total 28

-rw-rw-rw- 1 root root 12 Dec 6 09:45 name

192.168.37.133 | SUCCESS | rc=0 >>

total 40

-rw-rw-rw- 1 root root 12 Dec 5 09:45 name

可以看出我們的name檔案已經生成,并且權限為666。

③ 關于覆寫

我們把檔案的内容修改一下,然後選擇覆寫備份:

[[email protected] ~]# ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'

192.168.37.122 | SUCCESS => {

"backup_file": "/data/[email protected]:46:25~",

"changed": true,

"checksum": "064a68908ab9971ee85dbc08ea038387598e3778",

"dest": "/data/name",

"gid": 0,

"group": "root",

"md5sum": "8ca7c11385856155af52e560f608891c",

"mode": "0666",

"owner": "root",

"size": 12,

"src": "/root/.ansible/tmp/ansible-tmp-1512438383.78-228128616784888/source",

"state": "file",

"uid": 0

}

192.168.37.133 | SUCCESS => {

"backup_file": "/data/[email protected]:46:24~",

"changed": true,

"checksum": "064a68908ab9971ee85dbc08ea038387598e3778",

"dest": "/data/name",

"gid": 0,

"group": "root",

"md5sum": "8ca7c11385856155af52e560f608891c",

"mode": "0666",

"owner": "root",

"size": 12,

"src": "/root/.ansible/tmp/ansible-tmp-1512438384.0-170718946740009/source",

"state": "file",

"uid": 0

}

現在我們可以去檢視一下:

[[email protected] ~]# ansible web -m shell -a 'ls -l /data/'

192.168.37.122 | SUCCESS | rc=0 >>

total 28

-rw-rw-rw- 1 root root 12 Dec 6 09:46 name

-rw-rw-rw- 1 root root 10 Dec 6 09:45 [email protected]:46:25~

192.168.37.133 | SUCCESS | rc=0 >>

total 40

-rw-rw-rw- 1 root root 12 Dec 5 09:46 name

-rw-rw-rw- 1 root root 10 Dec 5 09:45 [email protected]:46:24~

可以看出,我們的源檔案已經被備份,我們還可以檢視一下name檔案的内容:

[[email protected] ~]# ansible web -m shell -a 'cat /data/name'

192.168.37.122 | SUCCESS | rc=0 >>

I am keerya

192.168.37.133 | SUCCESS | rc=0 >>

I am keerya

證明,這正是我們新導入的檔案的内容。

5)file 子產品

該子產品主要用于設定檔案的屬性,比如建立檔案、建立連結檔案、删除檔案等。

下面是一些常見的指令:

force  #需要在兩種情況下強制建立軟連結,一種是源檔案不存在,但之後會建立的情況下;另一種是目标軟連結已存在,需要先取消之前的軟鍊,然後建立新的軟鍊,有兩個選項:yes|no

group  #定義檔案/目錄的屬組。後面可以加上mode:定義檔案/目錄的權限

owner  #定義檔案/目錄的屬主。後面必須跟上path:定義檔案/目錄的路徑

recurse  #遞歸設定檔案的屬性,隻對目錄有效,後面跟上src:被連結的源檔案路徑,隻應用于state=link的情況

dest  #被連結到的路徑,隻應用于state=link的情況

state  #狀态,有以下選項:

directory:如果目錄不存在,就建立目錄

file:即使檔案不存在,也不會被建立

link:建立軟連結

hard:建立硬連結

touch:如果檔案不存在,則會建立一個新的檔案,如果檔案或目錄已存在,則更新其最後修改時間

absent:删除目錄、檔案或者取消連結檔案

用法舉例如下:

① 建立目錄:

[[email protected] ~]# ansible web -m file -a 'path=/data/app state=directory'

192.168.37.122 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/data/app",

"size": 6,

"state": "directory",

"uid": 0

}

192.168.37.133 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/data/app",

"size": 4096,

"state": "directory",

"uid": 0

}

我們可以檢視一下:

[[email protected] ~]# ansible web -m shell -a 'ls -l /data'

192.168.37.122 | SUCCESS | rc=0 >>

total 28

drwxr-xr-x 2 root root 6 Dec 6 10:21 app

192.168.37.133 | SUCCESS | rc=0 >>

total 44

drwxr-xr-x 2 root root 4096 Dec 5 10:21 app

可以看出,我們的目錄已經建立完成。

② 建立連結檔案

[[email protected] ~]# ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'

192.168.37.122 | SUCCESS => {

"changed": true,

"dest": "/data/bbb.jpg",

"gid": 0,

"group": "root",

"mode": "0777",

"owner": "root",

"size": 7,

"src": "aaa.jpg",

"state": "link",

"uid": 0

}

192.168.37.133 | SUCCESS => {

"changed": true,

"dest": "/data/bbb.jpg",

"gid": 0,

"group": "root",

"mode": "0777",

"owner": "root",

"size": 7,

"src": "aaa.jpg",

"state": "link",

"uid": 0

}

我們可以去檢視一下:

[[email protected] ~]# ansible web -m shell -a 'ls -l /data'

192.168.37.122 | SUCCESS | rc=0 >>

total 28

-rw-r--r-- 1 root root 5649 Dec 5 13:49 aaa.jpg

lrwxrwxrwx 1 root root 7 Dec 6 10:25 bbb.jpg -> aaa.jpg

192.168.37.133 | SUCCESS | rc=0 >>

total 44

-rw-r--r-- 1 root root 5649 Dec 4 14:44 aaa.jpg

lrwxrwxrwx 1 root root 7 Dec 5 10:25 bbb.jpg -> aaa.jpg

我們的連結檔案已經建立成功。

③ 删除檔案

[[email protected] ~]# ansible web -m file -a 'path=/data/a state=absent'

192.168.37.122 | SUCCESS => {

"changed": true,

"path": "/data/a",

"state": "absent"

}

192.168.37.133 | SUCCESS => {

"changed": true,

"path": "/data/a",

"state": "absent"

}

我們可以檢視一下:

[[email protected] ~]# ansible web -m shell -a 'ls /data/a'

192.168.37.122 | FAILED | rc=2 >>

ls: cannot access /data/a: No such file or directory

192.168.37.133 | FAILED | rc=2 >>

ls: cannot access /data/a: No such file or directory

發現已經沒有這個檔案了。

6)fetch 子產品

該子產品用于從遠端某主機擷取(複制)檔案到本地。

有兩個選項:

dest:用來存放檔案的目錄

src:在遠端拉取的檔案,并且必須是一個file,不能是目錄

具體舉例如下:

[[email protected] ~]# ansible web -m fetch -a 'src=/data/hello dest=/data'

192.168.37.122 | SUCCESS => {

"changed": true,

"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"dest": "/data/192.168.37.122/data/hello",

"md5sum": "6f5902ac237024bdd0c176cb93063dc4",

"remote_checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"remote_md5sum": null

}

192.168.37.133 | SUCCESS => {

"changed": true,

"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"dest": "/data/192.168.37.133/data/hello",

"md5sum": "6f5902ac237024bdd0c176cb93063dc4",

"remote_checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",

"remote_md5sum": null

}

我們可以在本機上檢視一下檔案是否複制成功。要注意,檔案儲存的路徑是我們設定的接收目錄下的被管制主機ip目錄下:

[[email protected] ~]# cd /data/

[[email protected] data]# ls

1 192.168.37.122 192.168.37.133 fastdfs web

[[email protected] data]# cd 192.168.37.122

[[email protected] 192.168.37.122]# ls

data

[[email protected] 192.168.37.122]# cd data/

[[email protected] data]# ls

hello

[[email protected] data]# pwd

/data/192.168.37.122/data

7)cron 子產品

該子產品适用于管理cron計劃任務的。

其使用的文法跟我們的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 # 以哪個使用者的身份執行

舉例如下:

① 添加計劃任務

[[email protected] ~]# ansible web -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'

192.168.37.122 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"ntp update every 5 min"

]

}

192.168.37.133 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"ntp update every 5 min"

]

}

我們可以去檢視一下:

[[email protected] ~]# ansible web -m shell -a 'crontab -l'

192.168.37.122 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

192.168.37.133 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

可以看出,我們的計劃任務已經設定成功了。

② 删除計劃任務

如果我們的計劃任務添加錯誤,想要删除的話,則執行以下操作:

首先我們檢視一下現有的計劃任務:

[[email protected] ~]# ansible web -m shell -a 'crontab -l'

192.168.37.122 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

#Ansible: df everyday

* 15 * * * df -lh >> /tmp/disk_total &> /dev/null

192.168.37.133 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

#Ansible: df everyday

* 15 * * * df -lh >> /tmp/disk_total &> /dev/null

然後執行删除操作:

[[email protected] ~]# ansible web -m cron -a 'name="df everyday" hour=15 job="df -lh >> /tmp/disk_total &> /dev/null" state=absent'

192.168.37.122 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"ntp update every 5 min"

]

}

192.168.37.133 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"ntp update every 5 min"

]

}

删除完成後,我們再檢視一下現有的計劃任務确認一下:

[[email protected] ~]# ansible web -m shell -a 'crontab -l'

192.168.37.122 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

192.168.37.133 | SUCCESS | rc=0 >>

#Ansible: ntp update every 5 min

*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

我們的删除操作已經成功。

8)yum 子產品

顧名思義,該子產品主要用于軟體的安裝。

其選項如下:

name=  #所安裝的包的名稱

state=  #present--->安裝, latest--->安裝最新的, absent---> 解除安裝軟體。

update_cache  #強制更新yum的緩存

conf_file  #指定遠端yum安裝時所依賴的配置檔案(安裝本地已有的包)。

disable_pgp_check  #是否禁止GPG checking,隻用于presentor latest。

disablerepo  #臨時禁止使用yum庫。 隻用于安裝或更新時。

enablerepo  #臨時使用的yum庫。隻用于安裝或更新時。

下面我們就來安裝一個包試試看:

[[email protected] ~]# ansible web -m yum -a 'name=htop state=present'

192.168.37.122 | SUCCESS => {

"changed": true,

"msg": "",

"rc": 0,

"results": [

"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:2.0.2-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n htop x86_64 2.0.2-1.el7 epel 98 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 98 k\nInstalled size: 207 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : htop-2.0.2-1.el7.x86_64 1/1 \n Verifying : htop-2.0.2-1.el7.x86_64 1/1 \n\nInstalled:\n htop.x86_64 0:2.0.2-1.el7 \n\nComplete!\n"

]

}

192.168.37.133 | SUCCESS => {

"changed": true,

"msg": "Warning: RPMDB altered outside of yum.\n** Found 3 pre-existing rpmdb problem(s), 'yum check' output follows:\nipa-client-4.4.0-12.el7.centos.x86_64 has installed conflicts freeipa-client: ipa-client-4.4.0-12.el7.centos.x86_64\nipa-client-common-4.4.0-12.el7.centos.noarch has installed conflicts freeipa-client-common: ipa-client-common-4.4.0-12.el7.centos.noarch\nipa-common-4.4.0-12.el7.centos.noarch has installed conflicts freeipa-common: ipa-common-4.4.0-12.el7.centos.noarch\n",

"rc": 0,

"results": [

"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:2.0.2-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n htop x86_64 2.0.2-1.el7 epel 98 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 98 k\nInstalled size: 207 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : htop-2.0.2-1.el7.x86_64 1/1 \n Verifying : htop-2.0.2-1.el7.x86_64 1/1 \n\nInstalled:\n htop.x86_64 0:2.0.2-1.el7 \n\nComplete!\n"

]

}

安裝成功。

9)service 子產品

該子產品用于服務程式的管理。

其主要選項如下:

arguments #指令行提供額外的參數

enabled #設定開機啟動。

name= #服務名稱

runlevel #開機啟動的級别,一般不用指定。

sleep #在重新開機服務的過程中,是否等待。如在服務關閉以後等待2秒再啟動。(定義在劇本中。)

state #有四種狀态,分别為:started--->啟動服務, stopped--->停止服務, restarted--->重新開機服務, reloaded--->重載配置

下面是一些例子:

① 開啟服務并設定自啟動

[[email protected] ~]# ansible web -m service -a 'name=nginx state=started enabled=true'

192.168.37.122 | SUCCESS => {

"changed": true,

"enabled": true,

"name": "nginx",

"state": "started",

……

}

192.168.37.133 | SUCCESS => {

"changed": true,

"enabled": true,

"name": "nginx",

"state": "started",

……

}

我們可以去檢視一下端口是否打開:

[[email protected] ~]# ansible web -m shell -a 'ss -ntl'

192.168.37.122 | SUCCESS | rc=0 >>

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:80 *:*

192.168.37.133 | SUCCESS | rc=0 >>

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:80 *:*

可以看出我們的80端口已經打開。

② 關閉服務

我們也可以通過該子產品來關閉我們的服務:

[[email protected] ~]# ansible web -m service -a 'name=nginx state=stopped'

192.168.37.122 | SUCCESS => {

"changed": true,

"name": "nginx",

"state": "stopped",

……

}

192.168.37.133 | SUCCESS => {

"changed": true,

"name": "nginx",

"state": "stopped",

……

}

一樣的,我們來檢視一下端口:

[[email protected] ~]# ansible web -m shell -a 'ss -ntl | grep 80'

192.168.37.122 | FAILED | rc=1 >>

192.168.37.133 | FAILED | rc=1 >>

可以看出,我們已經沒有80端口了,說明我們的nginx服務已經關閉了。

10)user 子產品

該子產品主要是用來管理使用者賬号。

其主要選項如下:

comment  # 使用者的描述資訊

createhome  # 是否建立家目錄

force  # 在使用state=absent時, 行為與userdel –force一緻.

group  # 指定基本組

groups  # 指定附加組,如果指定為(groups=)表示删除所有組

home  # 指定使用者家目錄

move_home  # 如果設定為home=時, 試圖将使用者主目錄移動到指定的目錄

name  # 指定使用者名

non_unique  # 該選項允許改變非唯一的使用者ID值

password  # 指定使用者密碼

remove  # 在使用state=absent時, 行為是與userdel –remove一緻

shell  # 指定預設shell

state  # 設定帳号狀态,不指定為建立,指定值為absent表示删除

system  # 當建立一個使用者,設定這個使用者是系統使用者。這個設定不能更改現有使用者

uid  # 指定使用者的uid

舉例如下:

① 添加一個使用者并指定其 uid

[[email protected] ~]# ansible web -m user -a 'name=keer uid=11111'

192.168.37.122 | SUCCESS => {

"changed": true,

"comment": "",

"createhome": true,

"group": 11111,

"home": "/home/keer",

"name": "keer",

"shell": "/bin/bash",

"state": "present",

"stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\nCreating mailbox file: File exists\n",

"system": false,

"uid": 11111

}

192.168.37.133 | SUCCESS => {

"changed": true,

"comment": "",

"createhome": true,

"group": 11111,

"home": "/home/keer",

"name": "keer",

"shell": "/bin/bash",

"state": "present",

"stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\nCreating mailbox file: File exists\n",

"system": false,

"uid": 11111

}

添加完成,我們可以去檢視一下:

[[email protected] ~]# ansible web -m shell -a 'cat /etc/passwd |grep keer'

192.168.37.122 | SUCCESS | rc=0 >>

keer:x:11111:11111::/home/keer:/bin/bash

192.168.37.133 | SUCCESS | rc=0 >>

keer:x:11111:11111::/home/keer:/bin/bash

② 删除使用者

[[email protected] ~]# ansible web -m user -a 'name=keer state=absent'

192.168.37.122 | SUCCESS => {

"changed": true,

"force": false,

"name": "keer",

"remove": false,

"state": "absent"

}

192.168.37.133 | SUCCESS => {

"changed": true,

"force": false,

"name": "keer",

"remove": false,

"state": "absent"

}

一樣的,删除之後,我們去看一下:

[[email protected] ~]# ansible web -m shell -a 'cat /etc/passwd |grep keer'

192.168.37.122 | FAILED | rc=1 >>

192.168.37.133 | FAILED | rc=1 >>

發現已經沒有這個使用者了。

11)group 子產品

該子產品主要用于添加或删除組。

常用的選項如下:

gid=  #設定組的GID号

name=  #指定組的名稱

state=  #指定組的狀态,預設為建立,設定值為absent為删除

system=  #設定值為yes,表示建立為系統組

舉例如下:

① 建立組

[[email protected]server ~]# ansible web -m group -a 'name=sanguo gid=12222'

192.168.37.122 | SUCCESS => {

"changed": true,

"gid": 12222,

"name": "sanguo",

"state": "present",

"system": false

}

192.168.37.133 | SUCCESS => {

"changed": true,

"gid": 12222,

"name": "sanguo",

"state": "present",

"system": false

}

建立過後,我們來檢視一下:

[[email protected] ~]# ansible web -m shell -a 'cat /etc/group | grep 12222'

192.168.37.122 | SUCCESS | rc=0 >>

sanguo:x:12222:

192.168.37.133 | SUCCESS | rc=0 >>

sanguo:x:12222:

可以看出,我們的組已經建立成功了。

② 删除組

[[email protected] ~]# ansible web -m group -a 'name=sanguo state=absent'

192.168.37.122 | SUCCESS => {

"changed": true,

"name": "sanguo",

"state": "absent"

}

192.168.37.133 | SUCCESS => {

"changed": true,

"name": "sanguo",

"state": "absent"

}

照例檢視一下:

[[email protected] ~]# ansible web -m shell -a 'cat /etc/group | grep 12222'

192.168.37.122 | FAILED | rc=1 >>

192.168.37.133 | FAILED | rc=1 >>

已經沒有這個組的相關資訊了。

12)script 子產品

該子產品用于将本機的腳本在被管理端的機器上運作。

該子產品直接指定腳本的路徑即可,我們通過例子來看一看到底如何使用的:

首先,我們寫一個腳本,并給其加上執行權限:

[[email protected] ~]# vim /tmp/df.sh

#!/bin/bash

date >> /tmp/disk_total.log

df -lh >> /tmp/disk_total.log

[[email protected] ~]# chmod +x /tmp/df.sh

然後,我們直接運作指令來實作在被管理端執行該腳本:

[[email protected] ~]# ansible web -m script -a '/tmp/df.sh'

192.168.37.122 | SUCCESS => {

"changed": true,

"rc": 0,

"stderr": "Shared connection to 192.168.37.122 closed.\r\n",

"stdout": "",

"stdout_lines": []

}

192.168.37.133 | SUCCESS => {

"changed": true,

"rc": 0,

"stderr": "Shared connection to 192.168.37.133 closed.\r\n",

"stdout": "",

"stdout_lines": []

}

照例檢視一下檔案内容:

[[email protected] ~]# ansible web -m shell -a 'cat /tmp/disk_total.log'

192.168.37.122 | SUCCESS | rc=0 >>

Tue Dec 5 15:58:21 CST 2017

Filesystem Size Used Avail Use% Mounted on

/dev/sda2 47G 4.4G 43G 10% /

devtmpfs 978M 0 978M 0% /dev

tmpfs 993M 84K 993M 1% /dev/shm

tmpfs 993M 9.1M 984M 1% /run

tmpfs 993M 0 993M 0% /sys/fs/cgroup

/dev/sda3 47G 33M 47G 1% /app

/dev/sda1 950M 153M 798M 17% /boot

tmpfs 199M 16K 199M 1% /run/user/42

tmpfs 199M 0 199M 0% /run/user/0

192.168.37.133 | SUCCESS | rc=0 >>

Tue Dec 5 15:58:21 CST 2017

Filesystem Size Used Avail Use% Mounted on

/dev/sda2 46G 4.1G 40G 10% /

devtmpfs 898M 0 898M 0% /dev

tmpfs 912M 84K 912M 1% /dev/shm

tmpfs 912M 9.0M 903M 1% /run

tmpfs 912M 0 912M 0% /sys/fs/cgroup

/dev/sda3 3.7G 15M 3.4G 1% /app

/dev/sda1 1.9G 141M 1.6G 9% /boot

tmpfs 183M 16K 183M 1% /run/user/42

tmpfs 183M 0 183M 0% /run/user/0

可以看出已經執行成功了。

13)setup 子產品

該子產品主要用于收集資訊,是通過調用facts元件來實作的。

facts元件是Ansible用于采集被管機器裝置資訊的一個功能,我們可以使用setup子產品查機器的所有facts資訊,可以使用filter來檢視指定資訊。整個facts資訊被包裝在一個JSON格式的資料結構中,ansible_facts是最上層的值。

facts就是變量,内建變量 。每個主機的各種資訊,cpu顆數、記憶體大小等。會存在facts中的某個變量中。調用後傳回很多對應主機的資訊,在後面的操作中可以根據不同的資訊來做不同的操作。如redhat系列用yum安裝,而debian系列用apt來安裝軟體。

① 檢視資訊

我們可以直接用指令擷取到變量的值,具體我們來看看例子:

[[email protected] ~]# ansible web -m setup -a 'filter="*mem*"'#檢視記憶體

192.168.37.122 | SUCCESS => {

"ansible_facts": {

"ansible_memfree_mb": 1116,

"ansible_memory_mb": {

"nocache": {

"free": 1397,

"used": 587

},

"real": {

"free": 1116,

"total": 1984,

"used": 868

},

"swap": {

"cached": 0,

"free": 3813,

"total": 3813,

"used": 0

}

},

"ansible_memtotal_mb": 1984

},

"changed": false

}

192.168.37.133 | SUCCESS => {

"ansible_facts": {

"ansible_memfree_mb": 1203,

"ansible_memory_mb": {

"nocache": {

"free": 1470,

"used": 353

},

"real": {

"free": 1203,

"total": 1823,

"used": 620

},

"swap": {

"cached": 0,

"free": 3813,

"total": 3813,

"used": 0

}

},

"ansible_memtotal_mb": 1823

},

"changed": false

}

我們可以通過指令檢視一下記憶體的大小以确認一下是否一緻:

[[email protected] ~]# ansible web -m shell -a 'free -m'

192.168.37.122 | SUCCESS | rc=0 >>

total used free shared buff/cache available

Mem: 1984 404 1122 9 457 1346

Swap: 3813 0 3813

192.168.37.133 | SUCCESS | rc=0 >>

total used free shared buff/cache available

Mem: 1823 292 1207 9 323 1351

Swap: 3813 0 3813

可以看出資訊是一緻的。

② 儲存資訊

我們的setup子產品還有一個很好用的功能就是可以儲存我們所篩選的資訊至我們的主機上,同時,檔案名為我們被管制的主機的IP,這樣友善我們知道是哪台機器出的問題。

我們可以看一看例子:

[[email protected] tmp]# ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts

192.168.37.122 | SUCCESS => {

"ansible_facts": {

"ansible_memfree_mb": 1115,

"ansible_memory_mb": {

"nocache": {

"free": 1396,

"used": 588

},

"real": {

"free": 1115,

"total": 1984,

"used": 869

},

"swap": {

"cached": 0,

"free": 3813,

"total": 3813,

"used": 0

}

},

"ansible_memtotal_mb": 1984

},

"changed": false

}

192.168.37.133 | SUCCESS => {

"ansible_facts": {

"ansible_memfree_mb": 1199,

"ansible_memory_mb": {

"nocache": {

"free": 1467,

"used": 356

},

"real": {

"free": 1199,

"total": 1823,

"used": 624

},

"swap": {

"cached": 0,

"free": 3813,

"total": 3813,

"used": 0

}

},

"ansible_memtotal_mb": 1823

},

"changed": false

}

然後我們可以去檢視一下:

[[email protected] ~]# cd /tmp/facts/

[[email protected] facts]# ls

192.168.37.122 192.168.37.133

[[email protected] facts]# cat 192.168.37.122

{"ansible_facts": {"ansible_memfree_mb": 1115, "ansible_memory_mb": {"nocache": {"free": 1396, "used": 588}, "real": {"free": 1115, "total": 1984, "used": 869}, "swap": {"cached": 0, "free": 3813, "total": 3813, "used": 0}}, "ansible_memtotal_mb": 1984}, "changed": false}