使用ansible遠程執行命令

使用ansible遠程執行命令

1.ansible簡介

ansible的官方定義:“Ansible is Simple IT Automation”——簡單的自動化IT工具。這個工具的目標:

  • 自動化部署APP

  • 自動化管理配置項

  • 自動化的持續交付

  • 自動化的(AWS)雲服務管理。

其本質上就是在遠程在多臺服務器執行一系列命令和文件同步,和以前的介紹的使用並行ssh提高工作效率功能類似,他們都是使用ssh協議進行遠程操作,但ansible比pssh功能更強大,比如支持主機列表分組、支持playbook模板文件等。本文僅僅介紹ansible的Ad-Hoc用法,即默認的command模塊,直接在shell執行命令。

2.安裝

ubuntu14.04直接使用apt-get安裝:

sudo apt-get install -y ansible

也可以使用pip命令安裝:

sudo pip install ansible

爲了支持輸入遠程主機用戶密碼,還需要安裝sshpass工具:

sudo apt-get install -y sshpass

安裝完成後創建~/.hosts文件,內容如下:

[local]ceph-0[mon]ceph-1[osd]ceph-2ceph-3

以上配置文件定義了三個主機組,分別爲localmonosdceph-x是主機名。ansible執行需要指定主機列表文件,默認爲/etc/hosts,用戶也可以通過-i hosts_file指定,我們修改默認文件爲我們剛剛創建的新文件,創建~/.ansible.cfg,增加以下內容:

[defaults]hostfile=~/.hosts

3.使用ansible

ansible的簡單語法爲:

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

其中host-pattern指定主機組,比如上面的osdlocal等,-f指定並行數,默認爲5-m指定模塊名,比如ping表示探測遠程主機是否可訪問,command表示執行shell命令,copy表示傳輸文件等,默認爲command-a是指定選項參數,不同的模塊具有不同的參數,比如ping不需要選項,command需要指定執行的命令,copy需要指定srcdest等。另外還有以上提到的-i指定主機列表文件、-u指定遠程執行用戶名等。
在所有的osd節點執行uptime操作,遠程主機必須有一樣的用戶名和密碼,如果不指定用戶名,則默認使用當前登錄主機的用戶名,否則如果和登錄主機用戶名不一樣,必須通過-u username指定遠程主機:

ansible osd -a 'uptime'

輸出:

ceph-3 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
ceph-2 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue

命令執行失敗,我們使用-vvvv選項查看詳細信息:

ansible -vvvv osd -a 'uptime'

輸出:

ebug1: Trying private key: /home/fgp/.ssh/id_rsadebug3: no such identity: /home/fgp/.ssh/id_rsa: No such file or directorydebug1: Trying private key: /home/fgp/.ssh/id_dsadebug3: no such identity: /home/fgp/.ssh/id_dsa: No such file or directorydebug1: Trying private key: /home/fgp/.ssh/id_ecdsadebug3: no such identity: /home/fgp/.ssh/id_ecdsa: No such file or directorydebug1: Trying private key: /home/fgp/.ssh/id_ed25519debug3: no such identity: /home/fgp/.ssh/id_ed25519: No such file or directorydebug2: we did not send a packet, disable methoddebug1: No more authentication methods to try.
Permission denied (publickey,password).

說明我們既沒有密鑰文件也沒有輸入用戶密碼,因此無法通過ssh認證,需要輸入密碼,使用-k選項:

  ~ ansible  osd -a 'uptime' -k
SSH password:ceph-2 | success | rc=0 >> 11:01:17 up 1 day, 6 min,  5 users,  load average: 0.02, 0.02, 0.05ceph-3 | success | rc=0 >> 11:01:17 up 1 day, 6 min,  5 users,  load average: 0.03, 0.03, 0.05

執行成功了,輸入一次密碼後,ansible會保存認證session,在session有效期內,不需要重複輸入密碼,即在執行了以上命令後,不需要再傳遞-k參數:

  ~ ansible  osd -a 'uptime'ceph-2 | success | rc=0 >> 11:02:14 up 1 day, 7 min,  5 users,  load average: 0.01, 0.02, 0.05ceph-3 | success | rc=0 >> 11:02:14 up 1 day, 7 min,  5 users,  load average: 0.01, 0.02, 0.05

有效期只有幾分鐘時間,爲了避免每次輸入密碼,建議還是通過設置密鑰來實現免密碼登錄,若本地還沒有生成密鑰文件,則先使用ssh-keygen命令生成密鑰文件:

  ~ ssh-keygen                                                                                                                                                              [1/1877]
Generating public/private rsa key pair.
Enter file in which to save the key (/home/fgp/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/fgp/.ssh/id_rsa.
Your public key has been saved in /home/fgp/.ssh/id_rsa.pub.
The key fingerprint is:49:8b:d0:a0:29:69:c8:32:50:3d:fc:8a:0a:4e:c8:1d fgp@ceph-0The key's randomart image is:+--[ RSA 2048]----+
|...o.            |
|+. o+o           |
|*oo .o. .        |
|oo E ..o o       |
|o ..... S        |
|oo...            |
|+.               |
|..               |
|                 |
+-----------------+

我們把~/.ssh/id_rsa.pub文件拷貝到所有的主機,拷貝文件需要指定-m模塊名爲copy,指定所有的主機的host-patternall:

ansible all -m copy -a 'src=~/.ssh/id_rsa.pub dest=~/.ssh/' -kansible all -a 'ls' -k # 查看是否傳輸成功

接下來把公鑰追加到~/.ssh/authorized_keys中,我們需要執行cat ~/id_rsa.pub >> ~/.ssh/命令,但默認的command模塊是不支持重定向和管道的,爲了使用重定向和管道,我們使用shell模塊:

ansible all -m shell -a 'mkdir -p .ssh' # assure ~/.ssh exist!ansible all -m shell -a 'cat ~/.ssh/id_rsa.pub >  ~/.ssh/authorized_keys' -k

>>如果之前存在rsakey則會出現ssh錯誤!

驗證下是否工作,注意下面的命令沒有指定-k選項:

ansible all -m shell -a 'cat .ssh/authorized_keys'

輸出:

  ~ ansible all -m shell -a 'cat .ssh/authorized_keys'                                                                                                                      [1/1839]
ceph-0 | success | rc=0 >>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxjl++nrmghoRVQnnJALR8Ia6eD87hdewZ9XZP9Ay3ZU1eU9F5MF0A7I7UY08kY7az7+14YJeP0T+zhEl8trc6NDV47LJnMG8ONVePokCeCvFgukUa8QpAhMWXSRSyUFA3Q4LpVmRu2nat$lSrwhu0W7uazq9OA5YxSCZRV/lb6bTsrrywBT4s9Crr5DWKUeZ1uKeUVghz0KmxH/ICWyFGE3v3OsqTMvtWM/R5m6FIgb86bd3CsM4UAP4v5I4FEx4+iqsbtvww3qOkY3Qj91AGOuYq8yNhFmQVN7VZZ9OR/8Vc0iI1wOG+vylbEJjr0/pjX$pPzPrOtW0Q6PjTKZXL fgp@ceph-0ceph-3 | success | rc=0 >>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxjl++nrmghoRVQnnJALR8Ia6eD87hdewZ9XZP9Ay3ZU1eU9F5MF0A7I7UY08kY7az7+14YJeP0T+zhEl8trc6NDV47LJnMG8ONVePokCeCvFgukUa8QpAhMWXSRSyUFA3Q4LpVmRu2nat$lSrwhu0W7uazq9OA5YxSCZRV/lb6bTsrrywBT4s9Crr5DWKUeZ1uKeUVghz0KmxH/ICWyFGE3v3OsqTMvtWM/R5m6FIgb86bd3CsM4UAP4v5I4FEx4+iqsbtvww3qOkY3Qj91AGOuYq8yNhFmQVN7VZZ9OR/8Vc0iI1wOG+vylbEJjr0/pjX$pPzPrOtW0Q6PjTKZXL fgp@ceph-0ceph-2 | success | rc=0 >>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxjl++nrmghoRVQnnJALR8Ia6eD87hdewZ9XZP9Ay3ZU1eU9F5MF0A7I7UY08kY7az7+14YJeP0T+zhEl8trc6NDV47LJnMG8ONVePokCeCvFgukUa8QpAhMWXSRSyUFA3Q4LpVmRu2nat$lSrwhu0W7uazq9OA5YxSCZRV/lb6bTsrrywBT4s9Crr5DWKUeZ1uKeUVghz0KmxH/ICWyFGE3v3OsqTMvtWM/R5m6FIgb86bd3CsM4UAP4v5I4FEx4+iqsbtvww3qOkY3Qj91AGOuYq8yNhFmQVN7VZZ9OR/8Vc0iI1wOG+vylbEJjr0/pjX$pPzPrOtW0Q6PjTKZXL fgp@ceph-0ceph-1 | success | rc=0 >>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxjl++nrmghoRVQnnJALR8Ia6eD87hdewZ9XZP9Ay3ZU1eU9F5MF0A7I7UY08kY7az7+14YJeP0T+zhEl8trc6NDV47LJnMG8ONVePokCeCvFgukUa8QpAhMWXSRSyUFA3Q4LpVmRu2nat$lSrwhu0W7uazq9OA5YxSCZRV/lb6bTsrrywBT4s9Crr5DWKUeZ1uKeUVghz0KmxH/ICWyFGE3v3OsqTMvtWM/R5m6FIgb86bd3CsM4UAP4v5I4FEx4+iqsbtvww3qOkY3Qj91AGOuYq8yNhFmQVN7VZZ9OR/8Vc0iI1wOG+vylbEJjr0/pjX$pPzPrOtW0Q6PjTKZXL fgp@ceph-0

可見我們免密碼執行遠程命令,並且驗證了公鑰已經追加到~/.ssh/authorized_keys中。
下面我們執行一下更新操作,命令爲apt-get update -y:

ansible all -m shell -a 'apt-get update -y'

輸出結果:

ceph-1 | FAILED | rc=100 >>E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)E: Unable to lock directory /var/lib/apt/lists/E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

ceph-2 | FAILED | rc=100 >>E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)E: Unable to lock directory /var/lib/apt/lists/E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

ceph-3 | FAILED | rc=100 >>E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)E: Unable to lock directory /var/lib/apt/lists/E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

執行失敗了,顯然是由於沒有root權限,需要使用sudo執行命令,需要`--sudo``選項:

ansible all --sudo -m shell -a 'apt-get update -y'

如果沒有密鑰,需要輸入sudo密碼,需要指定-K選項(大寫的K)。

4.總結

ansible的功能非常強大,以上只介紹瞭如何在命令行遠程執行命令,ansible還有更強大的playbook功能,playbook通過yaml文件定義,類似puppet的模板文件,具體可以參考官方文檔。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章