本文首發於 我的博客 - Ansible 常用使用場景 ,歡迎大家訪問原文查看。
給 Ansible 下一個完整的定義很難,官方的宣傳是 Ansible is Simple IT Automation
看出來還是主打自動化。
Ansible delivers simple IT automation that ends repetitive tasks and frees up DevOps teams for more strategic work.
也有資料介紹 Ansible 是模型驅動的配置管理器,個人覺得這個描述不是很恰當。從 Ansible 的使用方式來看,默認使用 push 的方式更像自動化。而 Puppet 默認使用 pull 的方式,則更像是配置驅動。
Ansible 的使用有兩種模式,一種是直接在命令行調用模塊批量執行單個命令,這種稱為 AD HOC 模式。
$ ansible [host_inventory] -m command -a 'hostname'
也可以通過編寫 yaml 文件,來編排一組操作,這種方式稱為 playbook 模式。看一個簡單的配置。
# test.yaml
---
- hosts: 192.168.1.31
remote_user: root
tasks:
- name: run df -h
remote_user: test
shell: name=df -h
使用方式是這樣,AD HOC 模式無法持久化,playbook 方式可以通過 yaml 文件實現持久化和重復執行。
$ ansible-playbook test.yaml
今天我們來熟悉幾個最常用的模塊:
command 模塊
在遠程節點上執行命令,使用方式如下:
$ ansible [host_list] -m command -a "hostname"
但這種方式並不是調用 shell 環境去執行命令,所以無法獲取環境變量,也不能使用管道符、重定向等。
支持 chdir
參數,即執行命令前先切換到指定目錄。
$ ansible [host_list] -m command -a "ls -l chdir=/etc/yum.repos.d"
# command 是 ansible 的默認模塊,可以省略
$ ansible [host_list] -a "ls -l chdir=/etc/yum.repos.d"
shell 模塊
如果需要在遠程的 shell 下執行命令,則需要使用 shell 模塊。使用方法與 command 相同,但是命令執行時調用的 /bin/sh
$ ansible [host_list] -m command -a 'echo $LOGNAME'
# 該命令可以打印當前登錄的用戶名
$ ansible [host_list] -m command -a 'ps -ef | grep java | wc -l'
# 該命令可以統計服務器上運行的 java 程序數量
copy 模塊
復制文件,支持從本地復制到服務端。
# 從服務端向被管機拷貝文件
$ ansible [host_list] -m copy -a 'src=/etc/hosts dest=/tmp owner=root mode=0755'
# 將內容存為遠端文件
$ ansible [host_list] -m copy -a 'content=Hello World! desc/tmp/test.txt owner=root force=yes mode=0755'
fetch 模塊
從遠端獲取文件,如果 dest
指定為文件夾時,默認為以每台服務器的IP為名稱創建文件夾,相關的文件保存在對應的文件夾下。
# 從遠端服務器獲取文件
$ ansible [host_list] -m fetch -a 'src=/etc/hosts dest=/home/path owner=root mode=0755'
參數列表:
dest
:存儲目標的目錄。如果獲取/etc/hosts
目標存放在/home
下,最終保存路徑是/home/host.example.com/etc/hosts
,主機名的依據是/etc/ansible/hosts
的配置。src
:目前只能是文件。
普通用戶執行 Ansible 遇到的問題
場景如下,管理機的 root 賬號被上收了,我只能使用普通用戶 shiqiang
執行 ansible 命令。此時,如果主機列表配置如下:
$ cat /etc/ansible/hosts
[testhost]
128.128.128.128
$ ansible testhost -m ping
會報 Permission Denied
的錯誤。原因是使用 shiqiang
這個賬號執行 ansible 命令時,默認會使用當前用戶嘗試免密登錄目標主機。因為 testhost 主機與管理機做了 root 賬號的互信,,這時需要在配置文件中明確指明使用 root 用戶,同時需要把管理機 shiqiang
用戶的 id_rsa.pub 拷貝到testhost 的 .ssh/authorized_keys
文件中。
$ cat /etc/ansible/hosts
[testhost]
128.128.128.128 ansible_ssh_user=root