說明:html
ansible其功能實現基於SSH遠程鏈接服務node
使用ansible須要首先實現ssh密鑰鏈接python
ssh-keygen -t 指定密鑰類型 rsa1 dsa(經常使用) ecdsa 語法: SYNOPSIS ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] [-f output_keyfile] ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] ssh-keygen -i [-f input_keyfile] ssh-keygen -e [-f input_keyfile] ssh-keygen -y [-f input_keyfile] ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] ssh-keygen -l [-f input_keyfile] ssh-keygen -B [-f input_keyfile] ssh-keygen -D pkcs11 ssh-keygen -F hostname [-f known_hosts_file] [-l] ssh-keygen -H [-f known_hosts_file] ssh-keygen -R hostname [-f known_hosts_file] ssh-keygen -r hostname [-f input_keyfile] [-g] ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] ssh-keygen -T output_file -f input_file [-v] [-a num_trials] [-W generator] ssh-keygen [-n] [-D smartcard] ssh-keygen -s ca_key -I certificate_identity [-h] [-Z principals] [-O option] [-V validity_interval] [-z serial_number] file ... ssh-keygen -L [-f input_keyfile]
建立密鑰的過程linux
[root@m01 ~]# ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/root/.ssh/id_dsa): #私鑰建立後保存的路徑 Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): #私鑰需不需進行加密,設置密碼 Enter same passphrase again: #私鑰需不需進行加密,再次輸入密碼確認 Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: 31:4a:4f:9f:97:b0:b6:ca:4c:53:78:70:89:83:5f:16 root@m01 The key's randomart image is: +--[ DSA 1024]----+ | E | | . . o | | o B * | | . = @ + . | | . S B o | | + o | | o . | | + o | | + | +-----------------+
建立出來的文件:web
[root@m01 ~]# ll /root/.ssh/ total 8 -rw------- 1 root root 668 Oct 17 18:55 id_dsa #建立出來的私鑰 -rw-r--r-- 1 root root 598 Oct 17 18:55 id_dsa.pub #建立出來的公鑰
[root@m01 ~]# man ssh-copy-id ssh-copy-id - install your public key in a remote machine’s autho-rized_keys
注意:密鑰分發命令屬於openssh-clients軟件包shell
[root@nfs01 ~]# rpm -qf `which ssh-copy-id` openssh-clients-5.3p1-122.el6.x86_64
語法格式vim
ssh-copy-id [-i [identity_file]] [user@]machine -i 指定要分發的公鑰文件以及路徑信息 [user@] 以什麼用戶身份進行分發 machine 將公鑰分發到哪臺主機上,遠程主機IP地址 [root@m01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@172.16.1.41 The authenticity of host '172.16.1.41 (172.16.1.41)' can't be established. RSA key fingerprint is d3:41:bb:0d:43:88:da:a3:2c:e8:36:91:11:c9:e4:9c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '172.16.1.41' (RSA) to the list of known hosts. root@172.16.1.41's password: Now try logging into the machine, with "ssh 'root@172.16.1.41'", and check in .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
[root@m01 ~]# ssh 172.16.1.41 Last login: Tue Oct 17 18:38:47 2017 from 10.0.0.1 [root@backup ~]#
基於密鑰登錄方式成功↑api
[root@m01 ~]# ssh root@172.16.1.41 "hostname -i" 172.16.1.41
不用的登錄到遠程主機直接執行命令,返回輸出結果↑bash
說明:服務器
管理主機一旦建立好祕鑰對文件,給多個主機分發公鑰時,公鑰文件相同
①. 管理服務器建立私鑰和公鑰(密鑰對)
②. 將公鑰文件遠程傳送複製到被管理服務器相應用戶~/.ssh/id_dsa.pub下,並修改.ssh目錄權限爲700
③. 修改公鑰文件文件名稱爲authorized_keys,受權權限爲600
④. 利用ssh服務配置文件的配置參數,進行識別公鑰文件authorized_keys
⑤. 進而實現基於密鑰遠程登陸服務器(免密碼登陸/非交互方式登陸)
[root@m01 ~]# file `which ssh-copy-id ` /usr/bin/ssh-copy-id: POSIX shell script text executable
看看腳本內容發現傳輸方式
[root@m01 ~]# cat `which ssh-copy-id`|grep ssh ssh $1 "exec sh -c 'cd; umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon .ssh .ssh/authorized_keys >/dev/null 2>&1 || true)'" || exit 1
說明:
一、切換用戶到家目錄下,臨時設置umask值
二、判斷客戶端相應用戶中有沒有.ssh目錄,若是沒有.ssh 目錄就進行建立
三、將管理端公鑰文件內容添加到客戶端~./ssh/authorized_keys, 默認authorized_keys文件不存在,須要建立,文件權限600
方法一: 修改腳本內容
ssh -p52113 $1 "exec sh -c 'cd; umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon .ssh .ssh/authorized_keys >/dev/null 2>&1 || true)'" || exit 1
說明:根據命令腳本,修改$1傳參信息,從而實現根據ssh不一樣端口傳送公鑰文件
方法二:將傳入的參數上添加上端口信息(推薦)
[root@m01 scripts]# ssh-copy-id -i /root/.ssh/id_dsa.pub "-p 52113 znix@172.16.1.250" Now try logging into the machine, with "ssh '-p 52113 znix@172.16.1.250'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
[root@m01 scripts]# cat shift.sh #!/bin/bash until [ $# -eq 0 ] do echo $* shift done
測試
[root@m01 scripts]# sh shift.sh 1 2 3 4 5 6 1 2 3 4 5 6 2 3 4 5 6 3 4 5 6 4 5 6 5 6 6
說明:
shift命令用於對參數的移動(左移),一般用於在不知道傳入參數個數的狀況下依次遍歷每一個參數而後進行相應處理(常見於Linux中各類程序的啓動腳本)。
ssh-copy-id -i /root/.ssh/id_dsa.pub "-p 52113 znix@172.16.1.250"
因爲/usr/bin/ssh-copy-id 腳本中前面使用了兩個shift 全部本來該爲$3的參數變爲了$1.
if [ "-i" = "$1" ]; then shift # check if we have 2 parameters left, if so the first is the new ID file if [ -n "$2" ]; then if expr "$1" : ".*\.pub" > /dev/null ; then ID_FILE="$1" else ID_FILE="$1.pub" fi shift # and this should leave $1 as the target name fi else
#for 循環 for n in (1..100) do xxx done #while循環:循環條件爲真時,一直循環;爲假時,中止循環 while [ture] do xxx done #until 循環: 循環條件爲假時,一直循環;爲真時,中止循環 until [ture] do xxx done
01.建立祕鑰對須要進行交互
a.須要確認祕鑰保存路徑
b.須要確認密碼信息
02.分發公鑰時須要進行交互
a.須要進行確認yes|no
b.第一次分發公鑰須要進行密碼認證
1.自動保存路徑,而且不密碼
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q
參數說明:
-f filename Specifies the filename of the key file. 指定密鑰文件保存的路徑信息(免交互) -P passphrase Provides the (old) passphrase. 提供一個密碼信息 -N new_passphrase Provides the new passphrase. -P -N 都是免交互方式指定密碼信息 -q 安靜的 不輸出信息,減小信息輸出
2.解決分發公鑰時須要進行的交互
sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub " root@172.16.1.$ip -o StrictHostKeyChecking=no "
參數說明:
-o option 選擇 (man 手冊中能夠查到有不少選項) StrictHostKeyChecking=no 對詢問的迴應(不進行對密鑰檢查)
要實現免密碼,須要一款軟件 sshpass 該軟件就是爲ssh提供密碼使用的
[root@m01 ~]# yum install sshpass -y
注意:密碼與 -p之間不能有空格
[root@m01 scripts]# vim ssh-key.sh #!/bin/bash . /etc/rc.d/init.d/functions # 建立密鑰 \rm ~/.ssh/id_rsa* -f ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q # 分發公鑰 for ip in 31 41 8 do sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub " root@172.16.1.$ip -o StrictHostKeyChecking=no " &>/dev/null if [ $? -eq 0 ];then action "fenfa 172.16.1.$ip" /bin/true else action "fenfa 172.16.1.$ip" /bin/false fi echo "" done
腳本執行效果:
[root@m01 scripts]# sh ssh-key.sh fenfa 172.16.1.31 [ OK ] fenfa 172.16.1.41 [ OK ] fenfa 172.16.1.8 [ OK ]
說明:
腳本中引用 . /etc/rc.d/init.d/functions 函數,能夠顯示執行結果的判斷。
使用if語句進行判斷,action 執行相應的動做。true/false
[root@m01 scripts]# vim piliang_guanli.sh #!/bin/bash CMD=$1 for ip in 8 31 41 do echo ========host 172.16.1.$ip======= ssh root@172.16.1.$ip "$CMD" echo ============END=============== echo "" done
腳本執行效果:
[root@m01 scripts]# sh piliang_guanli.sh date ======172.16.1.8====== Thu Oct 19 16:25:08 CST 2017 =========END============= ======172.16.1.31====== Thu Oct 19 16:25:08 CST 2017 =========END============= ======172.16.1.41====== Thu Oct 19 16:25:08 CST 2017 =========END=============
基於密鑰登錄方式,分發的公鑰文件會識別用戶信息,因此可以實現免密碼批量管理。
除了ansible以外,還有saltstack 等批量管理軟件
免密碼登陸驗證是單向的,方向從私鑰(鑰匙) >==> 公鑰(鎖)
SSH免密碼登陸基於用戶的,最好不要跨不一樣的用戶
SSH鏈接慢解決;即修改sshd_config配罝文件參數信息
批量分發1000臺初始都須要輸入一次密碼,而且第一次鏈接要確認(expect/sshpass)
expect批量管理服務器參考 http://oldboy.blog.51cto.com/2561410/1206238
①.最簡單/最經常使用/最強大的選擇是ssh key+shell/pssh方案,通常中小型企業會用(50-100臺如下規模企業)
a.利用ssh key執行命令,並將命令放在腳本里面
b.利用ssh key執行命令,將命令放在腳本里面,並加上相應循環語句或判斷語句
②.sina cfengine/puppet較早的批量管理工具;如今基本上沒有企業用
③.門戶級別比較流行的,puppet批量管理工具(複雜/笨重)
④.saltstack批量管理工具;特色:簡單,功能強大(配罝複雜>---趕集網/小米/一些CDN公司 批量管理路線:ssh key-->cfengine-->puppet-->saltstack/ansible
PS:使用ansible軟件的前提是ssh key公鑰分發充成
①.1臺服務器先配置好(kickstart,cobbler無人值守安裝)。高級實現雲計算(按需分配,動態調整)(openstack,kvm)
②.linux基本優化,包括ssh服務(能夠自動化實現)。
建立密鑰信息(自動化免交互建立)
ssh-keygen -t dsa -P "" -f ~/.ssh/id_dsa >/dev/null 2>&1
進行批量分發密鑰(sshpass,expect自動化實現)
⑤.ansible軟件安裝(能夠自動化實現)
⑥.網絡服務自動化安裝(ansible實現)
(搭建yum倉庫,定製rpm包)
l 不須要單獨安裝客戶端(no agents),基於系統自帶的sshd服務,sshd就至關於ansible的客戶端
l 不須要服務端(no sever)
l 須要依靠大量的模塊實現批量管理
l 配置文件 /etc/ansible/ansible.cfg (前期不用配置)
ansible軟件相關參考連接信息
http://docs.ansible.com/ansible/intro_installation.html
http://www.ansible.com.cn/
http://docs.ansible.com/modules_by_category.html
http://www.ansible.cn/docs/
[root@m01 ~]# ansible-doc -l 列出全部模塊信息 [root@m01 ~]# ansible-doc -s cron 參看指定模塊的幫助
[root@m01 ~]# yum install libselinux-python -y
該軟件是用來對selinux進行設置的,確保即便服務器selinux服務開啓,依舊可以經過ansible 軟件管理。
[root@m01 ~]# yum install ansible -y
軟件安裝完成,進行修改ansible下的hosts文件,注意文件的路徑
[root@m01 ~]# vim /etc/ansible/hosts [clsn] 172.16.1.31 172.16.1.41 172.16.1.8
文件信息說明:
1.中括號中的名字表明組名
2.主機(hosts)部分可使用域名、主機名、IP地址表示;通常此類配置中多使用IP地址;
3.組名下的主機地址就是ansible能夠管理的地址
至此ansible 服務就部署完成 ↑
服務器名稱 |
網卡eth0 |
網卡eth1 |
用途說明 |
m01 |
10.0.0.61 |
172.16.1.61 |
批量管理服務器 |
nfs01 |
10.0.0.31 |
172.16.1.31 |
nfs共享儲存服務器 |
backup |
10.0.0.41 |
172.16.1.41 |
rsync備份服務器 |
web01 |
10.0.0.8 |
172.16.1.8 |
web服務器 |
說明:無特殊狀況,子網掩碼爲255.255.255.0 |
[root@m01 ~]# ansible --version ansible 2.3.2.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]
[root@m01 ~]# rpm -ql ansible /etc/ansible/hosts #定義anisble軟件能夠管理的主機信息 /usr/bin/ansible #ansible執行命令 /usr/bin/ansible-playboot # ansible執行劇本命令
[root@m01 ansible]# ll total 28 -rw-r--r-- 1 root root 18066 Sep 6 06:38 ansible.cfg #ansible配置文件 -rw-r--r-- 1 root root 1016 Sep 6 06:38 hosts #定義ansible能夠管理的主機信息 drwxr-xr-x 2 root root 4096 Sep 6 06:38 roles #主要在自動化的時候部署多臺主機時使用
語法:
ansible clsn -a "uptime" ansible clsn -m command -a "uptime" ansible 定義的組/單個ip/域名/all -m command -a "uptime"
說明:-m 指定使用的模塊
-a 指定使用模塊中相應的命令參數
命令參數只能是基本命令,並不支持管道操做
all 爲hosts文件中的組所有管理
圖2-1 ansible命令語法格式示意圖
配置hosts文件時配置上密碼
vim /etc/ansible/hosts [clsn] 172.16.1.31:52113 ansible_ssh_user=root ansible_ssh_pass=123456 172.16.1.41 172.16.1.8
IP:端口 用戶 密碼
[znix] www.znix.top:52113 ansible_ssh_user=znix
指定端口 用戶名
測試修改端口後的結果 使用ping 模塊
[root@m01 ~]# ansible znix -m ping www.znix.top | SUCCESS => { "changed": false, "ping": "pong" }
命令參數 |
參數說明 |
-m MODULE_NAME |
-module-name=MODULE_NAME module name to execute (default=command) 相應名稱的模塊被執行(默認模塊爲command ); -m後邊是模塊的名宇 |
-a MODULE_ARGS |
-args=MODULE_ARGS module arguments 模塊參數信息 -a後面是要執行的命令;也能夠寫個ip ,針對臺機器來執行命令 |
-C, -checks |
don't make any changes, instead, try to predict some of the changes that may occurs 不作任何改變;反而,只是嘗試預言些可能出現的改變 |
-syntax-checks |
perform a syntax check on the playbook, but do not execute ii*> 執行語法檢查在劇本上,可是並不執行劇本 |
綠色:表示沒有發生任何改變
紅色:執行命令操做出現異常
黃色:執行命令後,對受控主機產生影響,發生了配置改變
[root@m01 ~]# ansible all -m ping 172.16.1.8 | SUCCESS => { "changed": false, "ping": "pong" } 172.16.1.41 | SUCCESS => { "changed": false, "ping": "pong" } 172.16.1.31 | SUCCESS => { "changed": false, "ping": "pong" }
鏈接正常返回 pong 經過幫助信息能夠得到 ↓
經過 ansible-doc -v ping 能夠得到該模塊的說明
ansible-doc -s file 參看模塊的具體信息
[root@m01 ~]# ansible-doc -v ping Using /etc/ansible/ansible.cfg as config file > PING (/usr/lib/python2.6/site-packages/ansible/modules/system/ping.py) A trivial test module, this module always returns `pong' on successful contact. It does not make sense in playbooks, but it is useful from `/usr/bin/ansible' to verify the ability to login and that a usable python is configured. This is NOT ICMP ping, this is just a trivial test module.
參數 |
參數說明 |
chdir |
在執行命令以前,經過cd命令進入到指定目錄中 # ansible clsn -m command -a "chdir=/tmp ls" |
create |
定義一個文件是否存在,若是不存在運行相應命令;若是存在跳過此步驟 |
executable |
改變shell使用command進行執行,而且執行時要使用絕對路徑 |
free_form |
命令模塊採用自由形式命令運行;便可以輸入任意linux命令 |
removes |
定義一個文件是否存在,若是存在運行相應命令;若是不存在跳過此步驟 |
warn (added in 1.8) |
若是ansible配置文件中定義了命令警告,若是參數設置了no/false,將不會警告此行命令 |
不指定模塊的時候默認使用的模塊就是command ↓
[root@m01 ~]# ansible all -a "date" 172.16.1.41 | SUCCESS | rc=0 >> Thu Oct 19 17:12:15 CST 2017 172.16.1.31 | SUCCESS | rc=0 >> Thu Oct 19 17:12:15 CST 2017 172.16.1.8 | SUCCESS | rc=0 >> Thu Oct 19 17:12:15 CST 2017
使用ansible自帶模塊執行命令 若是要用 > < | & ' ' 使用shell模塊
[root@m01 ~]# ansible all -m command -a "date" 172.16.1.8 | SUCCESS | rc=0 >> Thu Oct 19 17:12:27 CST 2017 172.16.1.31 | SUCCESS | rc=0 >> Thu Oct 19 17:12:28 CST 2017 172.16.1.41 | SUCCESS | rc=0 >> Thu Oct 19 17:12:27 CST 2017
chdir參數的使用:
[root@m01 ~]# ansible clsn -m command -a "chdir=/tmp pwd" 172.16.1.31 | SUCCESS | rc=0 >> /tmp 172.16.1.8 | SUCCESS | rc=0 >> /tmp 172.16.1.41 | SUCCESS | rc=0 >> /tmp
creates 文件是否存在,不存在就執行命令
[root@m01 ~]# ansible clsn -m command -a "creates=/etc/hosts date" 172.16.1.31 | SUCCESS | rc=0 >> skipped, since /etc/hosts exists
removes 文件是否存在,不存在就不執行命令,
[root@m01 ~]# ansible clsn -m command -a "removes=/etc/hosts date" 172.16.1.31 | SUCCESS | rc=0 >> Fri Oct 20 13:32:40 CST 2017
執行linux命令時能夠用
遠程節點執行命令
說明: shell 模塊在遠程執行腳本時,遠程主機上必定要有相應的腳本
[root@m01 ~]# ansible clsn -m shell -a "/bin/sh /server/scripts/ssh-key.sh" 172.16.1.31 | SUCCESS | rc=0 >> fenfa 172.16.1.31 [ OK ] fenfa 172.16.1.41 [ OK ] fenfa 172.16.1.8 [ OK ]
在本地執行腳本時,將腳本中的內容傳輸到遠程節點上運行
[root@m01 ~]# ansible all -m script -a "/server/scripts/free.sh" 172.16.1.8 | SUCCESS => { "changed": true, "rc": 0, "stderr": "Shared connection to 172.16.1.8 closed.\r\n", "stdout": " total used free shared buffers cached\r\nMem: 474M 377M 97M 532K 54M 202M\r\n-/+ buffers/cache: 120M 354M\r\nSwap: 767M 0B 767M\r\n", "stdout_lines": [ " total used free shared buffers cached", "Mem: 474M 377M 97M 532K 54M 202M", "-/+ buffers/cache: 120M 354M", "Swap: 767M 0B 767M" ] }
說明:
使用scripts模塊,不用將腳本傳輸到遠程節點,腳本自己不用進行受權,便可利用script模塊執行。直接執行腳本便可,不須要使用sh
選項參數 |
選項說明 |
backup(重要參數) |
在覆蓋遠端服務器文件以前,將遠端服務器源文件備份,備份文件包含時間信息。有兩個選項:yes|no |
content |
用於替代"src」,能夠直接設定指定文件的值 |
dest |
必選項。要將源文件複製到的遠程主機的絕對路徑,若是源文件是一個目錄,那麼該路徑也必須是個目錄 |
directory_mode |
遞歸設定目錄的權限,默認爲系統默認權限 |
forces |
若是目標主機包含該文件,但內容不一樣,若是設置爲yes,則強制覆蓋。 若是爲no,則只有當目標主機的目標位置不存在該文件時,才複製。默認爲yes。別名:thirsty |
others |
全部的file模塊裏的選項均可以在這裏使用 |
src |
被複制到遠程主機的本地文件,能夠是絕對路徑,也能夠是相對路徑。若是路徑是一個目錄,它將遞歸複製。在這種狀況下,若是路徑使用"/"來結尾,則只複製目錄裏的內容,若是沒有使用"/"來結尾,則包含目錄在內的整個內容所有複製,相似於rsync。 |
mode |
定義文件或目錄的權限;注意:是4位 |
owner |
修改屬主 |
group |
修改屬組 |
說明: src和content不能同時使用
使用copy 模塊,將/etc/hosts 文件 傳輸到各個服務器送,權限修改成0600 屬主屬組爲clsn
[root@m01 ~]# ansible clsn -m copy -a "src=/etc/hosts dest=/tmp/ mode=0600 owner=clsn group=clsn " 172.16.1.8 | SUCCESS => { "changed": true, "checksum": "b3c1ab140a1265cd7f6de9175a962988d93c629b", "dest": "/tmp/hosts", "gid": 500, "group": "clsn", "md5sum": "8c2b120b4742a806dcfdc8cfff6b6308", "mode": "0600", "owner": "clsn", "size": 357, "src": "/root/.ansible/tmp/ansible-tmp-1508410846.63-224022812989166/source", "state": "file", "uid": 500 }
……
檢查結果
[root@m01 ~]# ansible all -m shell -a "ls -l /tmp/hosts" 172.16.1.31 | SUCCESS | rc=0 >> -rw------- 1 clsn clsn 357 Oct 19 19:00 /tmp/hosts 172.16.1.41 | SUCCESS | rc=0 >> -rw------- 1 clsn clsn 357 Oct 11 15:12 /tmp/hosts 172.16.1.8 | SUCCESS | rc=0 >> -rw------- 1 clsn clsn 357 Oct 19 19:00 /tmp/hosts
移動遠程主機上的文件 remote_src=true 參數
[root@m01 ~]# ansible clsn -m copy -a " src=/server/scripts/ssh-key.sh dest=/tmp/ remote_src=true" 172.16.1.41 | SUCCESS => { "changed": true, "checksum": "d27bd683bd37e15992d2493b50c9410e0f667c9c", "dest": "/tmp/ssh-key.sh", "gid": 0, "group": "root", "md5sum": "dc88a3a419e3657bae7d3ef31925cbde", "mode": "0644", "owner": "root", "size": 397, "src": "/server/scripts/ssh-key.sh", "state": "file", "uid": 0 }
定義文件中的內容 content=clsnedu.com 默認沒有換行
[root@m01 ~]# ansible clsn -m copy -a "content=clsnedu.com dest=/tmp/clsn666.txt" 172.16.1.8 | SUCCESS => { "changed": true, "checksum": "291694840cd9f9c464263ea9b13421d8e74b7d00", "dest": "/tmp/clsn666.txt", "gid": 0, "group": "root", "md5sum": "0a6bb40847793839366d0ac014616d69", "mode": "0644", "owner": "root", "size": 13, "src": "/root/.ansible/tmp/ansible-tmp-1508466752.1-24733562369639/source", "state": "file", "uid": 0 }
參數 |
參數說明 |
|
owner |
設置複製傳輸後的數據屬主信息 |
|
group |
設置複製傳輸後的數據屬組信息 |
|
mode |
設置文件數據權限信息 |
|
dest |
要建立的文件或目錄命令,以及路徑信息 |
|
src |
指定要建立軟連接的文件信息 |
|
state |
state參數信息 |
|
directory |
建立目錄 |
|
file |
建立文件 |
|
link |
建立軟連接 |
|
hard |
建立出硬連接 |
|
absent |
目錄將被遞歸刪除以及文件,而連接將被取消連接 |
|
touch |
建立文件;若是路徑不存在將建立一個空文件 |
注意:重命名和建立多級目錄不能同時實現
建立目錄
[root@m01 ~]# ansible clsn -m file -a "dest=/tmp/clsn_dir state=directory" 172.16.1.41 | SUCCESS => { "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/clsn_dir", "size": 4096, "state": "directory", "uid": 0 }
建立文件
[root@m01 ~]# ansible clsn -m file -a "dest=/tmp/clsn_file state=touch" 172.16.1.8 | SUCCESS => { "changed": true, "dest": "/tmp/clsn_file", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 }
建立軟鏈接
[root@m01 ~]# ansible clsn -m file -a "src=/tmp/clsn_file dest=/tmp/clsn_file_link state=link" 172.16.1.41 | SUCCESS => { "changed": true, "dest": "/tmp/clsn_file_link", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "size": 16, "src": "/tmp/clsn_file", "state": "link", "uid": 0 }
刪除目錄文件信息
[root@m01 ~]# ansible clsn -m file -a "dest=/tmp/clsn_dir state=absent" 172.16.1.41 | SUCCESS => { "changed": true, "path": "/tmp/clsn_dir", "state": "absent" [root@m01 ~]# ansible clsn -m file -a "dest=/tmp/clsn_file state=absent" 172.16.1.31 | SUCCESS => { "changed": true, "path": "/tmp/clsn_file", "state": "absent"
建立多級目錄
[root@m01 ~]# ansible clsn -m copy -a "src=/etc/hosts dest=/tmp/01/0/0/0/0/0/0/0/" 172.16.1.31 | SUCCESS => { "changed": true, "checksum": "b3c1ab140a1265cd7f6de9175a962988d93c629b", "dest": "/tmp/01/0/0/0/0/0/0/0/hosts", "gid": 0, "group": "root", "md5sum": "8c2b120b4742a806dcfdc8cfff6b6308", "mode": "0644", "owner": "root", "size": 357, "src": "/root/.ansible/tmp/ansible-tmp-1508466973.39-99676412390473/source", "state": "file", "uid": 0 }
注意:重命名和建立多級目錄不能同時實現
參數 |
參數說明 |
dest |
將遠程主機拉取過來的文件保存在本地的路徑信息 |
src |
指定從遠程主機要拉取的文件信息,只能拉取文件 |
flat |
默認設置爲no,若是設置爲yes,將不顯示172.16.1.8/etc/信息 |
從遠程拉取出來文件
[root@m01 cp]# ansible clsn -m fetch -a "dest=/tmp/backup src=/etc/hosts" 172.16.1.8 | SUCCESS => { "changed": true, "checksum": "b3c1ab140a1265cd7f6de9175a962988d93c629b", "dest": "/tmp/backup/172.16.1.8/etc/hosts", "md5sum": "8c2b120b4742a806dcfdc8cfff6b6308", "remote_checksum": "b3c1ab140a1265cd7f6de9175a962988d93c629b", "remote_md5sum": null } [root@m01 cp]# tree /tmp/backup/ /tmp/backup/ ├── 172.16.1.31 │ └── etc │ └── hosts ├── 172.16.1.41 │ └── etc │ └── hosts └── 172.16.1.8 └── etc └── hosts
flat 參數,拉去的時候不建立目錄(同名文件會覆蓋)
[root@m01 tmp]# ansible clsn -m fetch -a "dest=/tmp/backup/ src=/etc/hosts flat=yes" 172.16.1.8 | SUCCESS => { "changed": false, "checksum": "b3c1ab140a1265cd7f6de9175a962988d93c629b", "dest": "/tmp/backup/hosts", "file": "/etc/hosts", "md5sum": "8c2b120b4742a806dcfdc8cfff6b6308"
參數 |
參數說明 |
|
fstype |
指定掛載文件類型 -t nfs == fstype=nfs |
|
opts |
設定掛載的參數選項信息 -o ro == opts=ro |
|
path |
掛載點路徑 path=/mnt |
|
src |
要被掛載的目錄信息 src=172.16.1.31:/data |
|
state |
state狀態參數 |
|
unmounted |
加載/etc/fstab文件 實現卸載 |
|
absent |
在fstab文件中刪除掛載配置 |
|
present |
在fstab文件中添加掛載配置 |
|
mounted |
1.將掛載信息添加到/etc/fstab文件中 2.加載配置文件掛載 |
掛載
[root@m01 tmp]# ansible 172.16.1.8 -m mount -a "fstype=nfs opts=rw path=/mnt/ src=172.16.1.31:/data/ state=mounted" 172.16.1.8 | SUCCESS => { "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "nfs", "name": "/mnt/", "opts": "rw", "passno": "0", "src": "172.16.1.31:/data/" }
卸載
[root@m01 tmp]# ansible 172.16.1.8 -m mount -a "fstype=nfs opts=rw path=/mnt/ src=172.16.1.31:/data/ state=unmounted" 172.16.1.8 | SUCCESS => { "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "nfs", "name": "/mnt/", "opts": "rw", "passno": "0", "src": "172.16.1.31:/data/" }
參數 |
參數說明 |
|
minute 分 |
Minute when the job should run ( 0-59, *, */2, etc ) |
|
hour 時 |
Hour when the job should run ( 0-23, *, */2, etc ) |
|
day 日 |
Day of the month the job should run ( 1-31, *, */2, etc ) |
|
month 月 |
Month of the year the job should run ( 1-12, *, */2, etc ) |
|
weekday 周 |
Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc ) |
|
job |
工做 ;要作的事情 |
|
name |
定義定時任務的描述信息 |
|
disabled |
註釋定時任務 |
|
state |
state 狀態參數 |
|
absent |
刪除定時任務 |
|
present |
建立定時任務 |
|
默認爲present |
添加定時任務
[root@m01 ~]# ansible clsn -m cron -a "minute=0 hour=0 job='/bin/sh /server/scripts/hostname.sh &>/dev/null' name=clsn01" 172.16.1.8 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "clsn01" ] }
刪除定時任務
[root@m01 ~]# ansible clsn -m cron -a "minute=00 hour=00 job='/bin/sh /server/scripts/hostname.sh &>/dev/null' name=clsn01 state=absent" 172.16.1.8 | SUCCESS => { "changed": true, "envs": [], "jobs": [] }
只用名字就能夠刪除
[root@m01 ~]# ansible clsn -m cron -a "name=clsn01 state=absent" 172.16.1.31 | SUCCESS => { "changed": true, "envs": [], "jobs": [] }
註釋定時任務
注意: 註釋定時任務的時候必須有job的參數
[root@m01 ~]# ansible clsn -m cron -a "name=clsn01 job='/bin/sh /server/scripts/hostname.sh &>/dev/null' disabled=yes" 172.16.1.31 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "clsn01" ] }
取消註釋
[root@m01 ~]# ansible clsn -m cron -a "name=clsn01 job='/bin/sh /server/scripts/hostname.sh &>/dev/null' disabled=no" 172.16.1.41 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "clsn01" ] }
3.10 yum 模塊
參數 |
參數說明 |
name=name |
指定安裝的軟件 |
state=installed |
安裝 |
[root@m01 ~]# ansible clsn -m yum -a "name=nmap state=installed " 172.16.1.31 | SUCCESS => { "changed": true, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package nmap.x86_64 2:5.51-6.el6 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n nmap x86_64 2:5.51-6.el6 base 2.8 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package(s)\n\nTotal download size: 2.8 M\nInstalled size: 9.7 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Installing : 2:nmap-5.51-6.el6.x86_64 1/1 \n\r Verifying : 2:nmap-5.51-6.el6.x86_64 1/1 \n\nInstalled:\n nmap.x86_64 2:5.51-6.el6 \n\nComplete!\n" ] }
參數 |
參數說明 |
name=service name |
服務的名稱 |
state=參數 |
中止服務 服務狀態信息爲過去時 stared/stoped/restarted/reloaded |
enabled=yes |
設置開機自啓動 |
說明 :service 管理的服務必須存在在/etc/init.d/下有的服務腳本
重啓定時任務
[root@m01 ~]# ansible clsn -m service -a "name=crond state=restarted" 172.16.1.8 | SUCCESS => { "changed": true, "name": "crond", "state": "started" }
經常使用模塊 |
模塊說明 |
command (重要模塊) |
執行命令模塊,ansible命令執行默認模塊 |
shell (重要模塊) |
行shell腳本模塊 |
script (重要模塊) |
把腳本發到客戶端,而後執行;執行腳本命令在遠端服務器上 |
copy (重要模塊) |
把本地文件發送到遠端 |
file |
設定文件屬性模塊 |
services |
系統服務管理模塊 |
cron |
計劃任務管理模塊 |
yum |
yum軟件包安裝管理模塊 |
synchronize |
使用rsync同步文件模塊 |
mount |
掛載模塊 |
[root@m01 ~]# ansible 172.16.1.8 -m hostname -a "name=web01" 172.16.1.8 | SUCCESS => { "ansible_facts": { "ansible_domain": "etiantian.org", "ansible_fqdn": "www.etiantian.org", "ansible_hostname": "web01", "ansible_nodename": "web01" }, "changed": false, "name": "web01" }
[root@m01 ~]# ansible 172.16.1.8 -m selinux -a "state=disabled" 172.16.1.8 | SUCCESS => { "changed": false, "configfile": "/etc/selinux/config", "msg": "", "policy": "targeted", "state": "disabled" }
[root@m01 ~]# ansible 172.16.1.8 -m get_url -a "url=http://lan.znix.top/RDPWrap-v1.6.1.zip dest=/tmp/" 172.16.1.8 | SUCCESS => { "changed": true, "checksum_dest": null, "checksum_src": "ad402705624d06a6ff4b5a6a98c55fc2453b3a70", "dest": "/tmp/RDPWrap-v1.6.1.zip", "gid": 0, "group": "root", "md5sum": "b04dde546293ade71287071d187ed92d", "mode": "0644", "msg": "OK (1567232 bytes)", "owner": "root", "size": 1567232, "src": "/tmp/tmp4X4Von", "state": "file", "status_code": 200, "uid": 0, "url": "http://lan.znix.top/RDPWrap-v1.6.1.zip" }
url= 下載文件的地址 dest 下載到哪裏
timeout 超時時間
url_password 密碼
url_username 用戶名
· 能夠實現批量管理
· 能夠實現批量部署
· ad-hoc(批量執行命令)---針對臨時性的操做
ansible clsn -m command -a "hostname" <- 批量執行命令舉例
· 編寫劇本-腳本(playbook)---針對重複性的操做
pyYAML-----用於ansible編寫劇本所使用的語言格式(saltstack---python)
rsync-ini語法 sersync-xml語法 ansible-pyYAML語法
paramiko---遠程鏈接與數據傳輸
Jinja2-----用於編寫ansible的模板信息
規則一:縮進
yaml使用一個固定的縮進風格表示數據層結構關係,Saltstack須要每一個縮進級別由兩個空格組成。必定不能使用tab鍵
注意:編寫yaml文件,就忘記鍵盤有tab
規則二:冒號
CMD="echo"
yaml:
mykey:
每一個冒號後面必定要有一個空格(以冒號結尾不須要空格,表示文件路徑的模版能夠不須要空格)
規則三:短橫線
想要表示列表項,使用一個短橫槓加一個空格。多個項使用一樣的縮進級別做爲同一個列表的一部分
核心規則:有效的利用空格進行劇本的編寫,劇本編寫是不支持tab的
### 劇本的開頭,能夠不寫 - hosts: all <- 處理全部服務器,找到全部服務器; -(空格)hosts:(空格)all tasks: <- 劇本所要乾的事情; (空格)(空格)task: - command: echo hello clsn linux. (空格)(空格)空格)(空格)-(空格)模塊名稱:(空格)模塊中對應的功能
ansible all -m command -a "echo hello clsn linux"
劇本編寫內容擴展:劇本任務定義名稱
- hosts: 172.16.1.7 <- 處理指定服務器 -(空格)hosts:(空格)all task: <- 劇本所要乾的事情; (空格)(空格)task: - name: command: echo hello clsn linux. (空格)(空格)空格)(空格)-(空格)模塊名稱:(空格)模塊中對應的功能
[root@m01 ansible-playbook]# vim rsync_sever.yml - hosts: 172.16.1.41 tasks: - name: install rsync yum: name=rsync state=installed
01:ansible-playbook --syntax-check 01.yml
--- 進行劇本配置信息語法檢查
02:ansible-playbook -C 01.yml
--- 模擬劇本執行(彩排)
[root@m01 ansible-playbook]# ansible-playbook --syntax-check 01.yml playbook: 01.yml
[root@m01 ansible-playbook]# ansible-playbook -C 01.yml PLAY [all] **************************************************************** TASK [Gathering Facts] **************************************************** ok: [172.16.1.41] ok: [172.16.1.8] ok: [172.16.1.31] TASK [cron] *************************************************************** ok: [172.16.1.8] ok: [172.16.1.41] ok: [172.16.1.31] PLAY RECAP **************************************************************** 172.16.1.31 : ok=2 changed=0 unreachable=0 failed=0 172.16.1.41 : ok=2 changed=0 unreachable=0 failed=0 172.16.1.8 : ok=2 changed=0 unreachable=0 failed=0
- hosts: all tasks: - name: restart-network cron: name='restart network' minute=00 hour=00 job='/usr/sbin/ntpdate time.nist.gov >/dev/null 2>&1' - name: sync time cron: name='sync time' minute=*/5 job="/usr/sbin/ntpdate pool.ntp.com >/dev/null 2>&1"
- hosts: 172.16.1.7 tasks: - name: restart-network cron: name='restart network' minute=00 hour=00 job='/usr/sbin/ntpdate time.nist.gov >/dev/null 2>&1' - name: sync time cron: name='sync time' minute=*/5 job="/usr/sbin/ntpdate pool.ntp.com >/dev/null 2>&1" - hosts: 172.16.1.31 tasks: - name: show ip addr to file shell: echo $(hostname -i) >> /tmp/ip.txt
01 多主機單任務編寫方式
02 多主機多任務編寫方式
03 不一樣主機多任務編寫方式
1. ansible-playbook編寫完,檢査語法和模擬測試運行
2. 打開劇本,定位異常問題緣由,將劇本中的內容轉換命令執行一次
cron: name=clsn64 minute=ee hour=03 job='/bin/sh /server/scripts/test.sh &>/dev/null' ansible clsn -m cron -a "name=clsn64 minute=00 hour=03 job='/bin/sh /server/scripts/test.sh &>/dev/null
3. 將參數中的腳本文件推送到遠程屎務器,在遠程服務器本地執行腳本 sh -x test.sh
說明:ansible執行時,加1上-vvvv顯示ansible詳細執行過程,也能夠定位異常緣由!
01. 劇本執行中的錯誤
02. 把劇本中的內容轉換爲ansible命令執行
ansible clsn -m yum -a "name=rsync state=installed"
03. 把ansible服務器上執行的命令放在被管理主機上執行
yum install -y rsync
[root@backup ~]# ps -ef|grep sshd root 35274 1 0 15:25 ? 00:00:00 /usr/sbin/sshd root 37004 35274 0 16:23 ? 00:00:00 sshd: root@pts/2 root 37062 35274 0 16:55 ? 00:00:00 sshd: root@notty root 37154 37006 0 16:55 pts/2 00:00:00 grep --color=auto sshd
首先,將該進程幹掉
kill pid
Loading callback plugin minimal of type stdout, v2.0 from /usr/lib/python2.6/site-packages/ansible/plugins/callback/__init__.pyc META: ran handlers Using module file /usr/lib/python2.6/site-packages/ansible/modules/system/ping.py <172.16.1.8> ESTABLISH SSH CONNECTION FOR USER: None <172.16.1.8> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/923ebeb605 172.16.1.8 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"'' ……
找到在哪裏出錯。
在 /etc/ssh/sshd_config 文件中的第132行爲空,致使sftp 沒法鏈接,出錯~
133 Subsystem sftp /usr/libexec/openssh/sftp-server
[root@m01 ~]# ansible -k 172.16.1.51 -m ping SSH password: [WARNING]: No hosts matched, nothing to do
緣由分析:
在ansible的hosts文件中,沒有配置相應主機地址信息
# ansible -k 172.16.1.51 -m ping SSH password: 172.16.1.51|FAILED! => { "failed": true, "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host." }
緣由分析:
由於沒有受控端的指紋信息,在known_hosts文件中