ansible入門與playbook實戰
1、關於Ansible
Ansilbe是一個部署一群遠程主機的工具;Ansilbe通過SSH協議實現遠程節點和管理節點之間的通信。理論上說,只要管理員通過ssh登錄到一臺遠程主機上能做的操作,Ansible都可以做到。Ansible是python開發的,故依賴一些python庫和組件,如:paramiko,PyYaml和jinja三個關鍵組件;
2、ansible架構:
右邊綠色部分是被管理的主機(虛擬機,物理機,雲主機等)從以上架構圖中可以看出
ansible是由主機清單(配置),playbook(配置),以及各模塊插件組成;
簡單的說就是,用戶(管理員)通過ansible的主機清單配置或Playbook配置(一組任務),調用ansible的各種模塊及參數來對
3、測試環境
本次測試環境:
ansible: CentOS7.4_x64 172.16.3.167 epel yum安裝ansible
node1: 172.16.3.152 CenOS7.2_x64
node2: 172.16.3.216 CentOS7.2_x64
從ansible上生成ssh私鑰同步到兩臺node主機上,實現無密鑰登錄管理(推薦)[root@ansible ~]# ssh-keygen -t rsa
直接回車生成私鑰;
同步到到兩臺node上
[root@ansible ~]# ssh-copy-id -i ~/.ssh/id_rsa 172.16.3.216 [root@ansible ~]# ssh-copy-id -i ~/.ssh/id_rsa 172.16.3.152
註意同步過程需要輸入yes和各自的root密碼即可;此進可直接ssh [email protected] 就無密碼登錄上去啦!
配置ansible的主機清單,即把node1與node2主機添加到管理清單中
[root@ansible ~]# egrep -v ‘(^$|^#)‘ /etc/ansible/hosts
[websrvs]
172.16.3.152
172.16.3.216
到此處配置的環境完成!
4、安裝
目前,只要機器上安裝了 Python 2.6 或 Python 2.7 (windows系統不可以做控制主機),都可以運行Ansible.
安裝ansible很簡單,可通過git從githu上直接獲取代碼,也可以像redhat/CentOS上通過yum進行安裝,
[root@ansible ~]# yum install epel-release -y
[root@ansible ~]# yum install ansible -y
#查看版本
[root@ansible ~]# ansible --version
ansible 2.4.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u‘/root/.ansible/plugins/modules‘, u‘/usr/share/ansible/plugins/modules‘]
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
二、配置及獲取幫助說明
通過rpm -ql ansible可以看到有很多文件,主要是配置文件和和可執行文件,以及所依賴的python庫文件
1、配置與執行文件說明
ansible的主配置文件
/etc/ansible/ansible.cfg
這個文件主要定義了roles_path路徑,主機清單路徑,連接清單中的主機方式等配置,這些大部的默認配置已經足夠我們平時使用,如需要特別配置可以自行去修改;
/etc/ansible/hosts
這個配置文件就是默認主機清單配置文件,可通過ansible.cfg重新定義的;
如定義一組主機:
[root@ansible ~]# egrep -v ‘(^$|^#)‘ /etc/ansible/hosts
[websrvs]
172.16.3.152
172.16.3.216
除了以上兩個重要的配置文件還有三個重要的可執行文件分別是:
ansible 主執行程序,一般用於命令行下執行
ansible-playbook 執行playbook中的任務
ansible-doc 獲取各模塊的幫助信息
2、ansible 使用格式
ansible
HOST-PATTERN #匹配主機模式,如all表示所有主機
-m MOD_NAME #模塊名 如:ping
-a MOD_ARGS #模塊執行的參數
-f FORKS #生成幾個子進行程執行
-C #(不執行,模擬跑)
-u Username #某主機的用戶名
-c CONNection #連接方式(default smart)
完整示例:
[root@ansible ~]# ansible all -m shell -a "ifconfig|grep enp0s3"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
3、ansible-doc 獲取幫助信息
ansible模塊比較多,可以通過ansible-doc --help 顯示幫助信息
ansible doc -l 獲取所有當前版本下的可用模塊及簡要信息
ansible-doc -s 模塊名 獲取指定模塊幫助信息說明``
三、ansible常用模塊
1、copy模塊
從本地copy文件分發到目錄主機路徑
參數說明:
src= 源文件路徑
dest= 目標路徑
註意src= 路徑後面帶/ 表示帶裏面的所有內容復制到目標目錄下,不帶/是目錄遞歸復制過去
content= 自行填充的文件內容
owner 屬主
group 屬組
mode權限
示例:
ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
ansible all -m copy -a "content=‘hi there\n‘ dest=/tmp/hi.txt"
到node1上查看
[root@node1 tmp]# ll
-rw------- 1 root root 465 2月 9 14:59 fstab.ansible
-rw-r--r-- 1 root root 9 2月 9 14:58 hi.txt
2、fetch模塊
從遠程主機拉取文件到本地
示例
[root@ansible ~]# ansible all -m fetch -a "src=/tmp/hi.txt dest=/tmp"
172.16.3.152 | SUCCESS => {
"changed": true,
"checksum": "279d9035886d4c0427549863c4c2101e4a63e041",
"dest": "/tmp/172.16.3.152/tmp/hi.txt",
"md5sum": "12f6bb1941df66b8f138a446d4e8670c",
"remote_checksum": "279d9035886d4c0427549863c4c2101e4a63e041",
"remote_md5sum": null
}
.......省略
說明:fetch使用很簡單,src和dest,dest只要指定一個接收目錄,默認會在後面加上遠程主機及src的路徑
3、command模塊
在遠程主機上執行命令,屬於裸執行,非鍵值對顯示;不進行shell解析;
示例1:
[root@ansible ~]# ansible all -m command -a "ifconfig"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.3.152 netmask 255.255.255.0 broadcast 172.16.3.255
.....省略.....
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.3.216 netmask 255.255.255.0 broadcast 172.16.3.255
.....省略.....
示例2:
[root@ansible ~]# ansible all -m command -a "ifconfig|grep lo"
172.16.3.152 | FAILED | rc=2 >>
[Errno 2] 沒有那個文件或目錄
172.16.3.216 | FAILED | rc=2 >>
[Errno 2] 沒有那個文件或目錄
這就是因為command模塊不是shell解析屬於裸執行導致的
為了能達成以上類似shell中的解析,ansible有一個shell模塊;
4、shell模塊
由於commnad只能執行裸命令(即系統環境中有支持的命令),至於管道之類的功能不支持,
shell模塊可以做到
示例:
[root@ansible ~]# ansible all -m shell -a "ifconfig|grep lo"
172.16.3.152 | SUCCESS | rc=0 >>
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
loop txqueuelen 0 (Local Loopback)
172.16.3.216 | SUCCESS | rc=0 >>
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
loop txqueuelen 0 (Local Loopback)
5、file模塊
設置文件屬性(創建文件)
常用參數:
path目標路徑
state directory為目錄,link為軟件鏈接
group 目錄屬組
owner 屬主
等,其他參數通過ansible-doc -s file 獲取
示例1:創建目錄
[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"
172.16.3.152 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/var/tmp/hello.dir",
"size": 6,
"state": "directory",
"uid": 0
}
172.16.3.216 | SUCCESS => {
"changed": true,
.....省略.....
示例2:創建軟件鏈接
[root@ansible ~]# ansible all -m file -a "src=/tmp/hi.txt path=/var/tmp/hi.link state=link"
172.16.3.152 | SUCCESS => {
"changed": true,
"dest": "/var/tmp/hi.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 11,
"src": "/tmp/hi.txt",
"state": "link",
"uid": 0
}
172.16.3.216 | SUCCESS => {
"changed": true,
.....省略.....
6、cron模塊
通過cron模塊對目標主機生成計劃任務
常用參數:
除了分(minute)時(hour)日(day)月(month)周(week)外
name: 本次計劃任務的名稱
state: present 生成(默認) |absent 刪除 (基於name)
示例:對各主機添加每隔3分鐘從time.windows.com同步時間
[root@ansible ~]# ansible all -m cron -a "minute=*/3 job=‘/usr/sbin/update time.windows.com &>/dev/null‘ name=update_time"
172.16.3.152 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"update_time"
]
}
172.16.3.216 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"update_time"
]
}
#到node1上查看
[root@node1 tmp]# crontab -l
#Ansible: update_time
*/3 * * * * /usr/sbin/update time.windows.com &>/dev/null
示例2:刪除計劃任務
[root@ansible ~]# ansible all -m cron -a "name=update_time state=absent"
172.16.3.152 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
172.16.3.216 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
#node1上查看
[root@node1 tmp]# crontab -l
會發現已經被刪除了
7、yum模塊
故名思義就是yum安裝軟件包的模塊;
常用參數說明:
enablerepo,disablerepo表示啟用與禁用某repo庫
name 安裝包名
state (present‘ or
installed‘, latest‘)表示安裝, (
absent‘ or `removed‘) 表示刪除
示例:通過安裝epel擴展源並安裝nginx
[root@ansible ~]# ansible all -m yum -a "name=epel-release state=installed"
[root@ansible ~]# ansible all -m yum -a "name=nginx state=installed"
8、service模塊
服務管理模塊
常用參數:
name:服務名
state:服務狀態
enabled: 是否開機啟動 true|false
runlevel: 啟動級別 (systemed方式忽略)
示例:
[root@ansible ~]# ansible all -m service -a "name=nginx state=started enabled=true"
到node1上查看
[root@node1 tmp]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since 五 2018-02-09 15:54:29 CST; 1min 49s ago
Main PID: 10462 (nginx)
CGroup: /system.slice/nginx.service
├─10462 nginx: master process /usr/sbin/nginx
└─10463 nginx: worker process
......省略......
9、script模塊
把本地的腳本傳到遠端執行;前提是到遠端可以執行,不要把Linux下的腳本同步到windows下執行;
直接上示例:
本地ansible上的腳本:
[root@ansible ~]# cat test.sh
#!/bin/bash
echo "ansible script test!" > /tmp/ansible.txt
[root@ansible ~]# ansible all -m script -a "/root/test.sh"
172.16.3.152 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.3.152 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
172.16.3.216 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.3.216 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
到node1上查看
[root@node1 tmp]# ls
ansible.txt fstab.ansible hi.txt
[root@node1 tmp]# cat ansible.txt
ansible script test!
script模塊這個功能可以做很多事,就看你怎麽用了~
以上是常用模塊,至於其他模塊的使用可通過官方模塊列表獲得~
四、Playbook實戰
playbook是Ansible的配置,部署和編排的語言。他們可以描述你所希望的遠程系統強制執行的政策,或者在一般的IT流程的一組步驟;形象點的說就是:如果ansible的各模塊(能實現各種功能)是車間裏的各工具;playbook就是指導手冊,目標遠程主機就是庫存和原料對象.
playbook是基於YAML語言格式配置,關於YAML
更多playbook官方說明參考
1、playbook的核心元素
hosts : playbook配置文件作用的主機
tasks: 任務列表
variables: 變量
templates:包含模板語法的文本文件
handlers :由特定條件觸發的任務
roles :用於層次性、結構化地組織playbook。roles 能夠根據層次型結構自動裝載變量文件、tasks以及handlers等
2、playbook運行方式
ansible-playbook --check 只檢測可能會發生的改變,但不真執行操作
ansible-playbook --list-hosts 列出運行任務的主機
ansible-playbook --syntax-check playbook.yaml 語法檢測
ansible-playbook -t TAGS_NAME playbook.yaml 只執行TAGS_NAME任務
ansible-playbook playbook.yaml 運行
3、通過playbook安裝管理redis服務
#在家目錄下創建playbooks
[root@ansible ~]# mkidr playbooks
[root@ansible ~]# cd playbooks
[root@ansible playbooks]# cat redis_first.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=latest
- name: start redis
service: name=redis state=started
語法檢測:
[root@ansible playbooks]# ansible-playbook --syntax-check redis_first.yaml
playbook: redis_first.yaml
說明語法沒有 問題
將要執行的主機:
[root@ansible playbooks]# ansible-playbook --list-hosts redis_first.yaml
playbook: redis_first.yaml
play #1 (all): all TAGS: []
pattern: [u‘all‘]
hosts (2):
172.16.3.216
172.16.3.152
執行
[root@ansible playbooks]# ansible-playbook redis_first.yaml
PLAY [all] *****************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [install redis] *******************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
TASK [start redis] *********************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP *****************************************************************************************************************
172.16.3.152 : ok=3 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=3 changed=2 unreachable=0 failed=0
說明:
自上而下列出了三個任務,分別是[Gathering Facts] , [install redis], [start redis],其中各主機上成功為ok=3,有兩項任務執行結果是changed
不可達 和失敗的任務均為0;
由於上面的操作是直接安裝redis服務並啟動,並沒有配置文件,這還不能往生產環境中使用,生產環境中的redis肯定有不同的配置項,因此需要在安裝時提供配置文件
4、帶配置文件的安裝管理redis
首先復制一個redis.conf到本地並進行修改
[root@ansible ~]# ansible 172.16.3.152 -m fetch -a "src=/etc/redis.conf dest=./"
[root@ansible ~]# mv /root/172.16.3.152/etc/redis.conf /root/playbooks/redis.conf
修改bind 0.0.0.0
cat redis_second.yaml
- hosts: all #所有遠程主機
remote_user: root #以遠程主機上root用戶執行
tasks: #任務
- name: install redis #任務之安裝
yum: name=redis state=latest #動作調用yum模塊安裝
- name: copy config file #任務之復制同步配置文件到遠程目標主機
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis #動作copy模塊執行
notify: restart redis #觸發的動作
tags: configfile #任務標記名configfile
- name: start redis #任務之啟動redis
service: name=redis state=started #動作調用sevice模塊
handlers: #特定情況下,接收到其他任務的通知時被觸發
- name: restart redis
service: name=redis state=restarted
再次測試並執行
[root@ansible playbooks]# ansible-playbook redis_second.yaml
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [install redis] ******************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
TASK [start redis] ********************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152 : ok=5 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=5 changed=2 unreachable=0 failed=0
可以發現只是加了一個配置文件,所有的任務都執行了,可否只應用新添加的任務?當然可以
這裏就要通過
ansible-playbook -t TAGS_NAME 來執行了
可以把redis.conf中添加一個登錄密碼再執行測試下:
[root@ansible playbooks]# ansible-playbook -t configfile redis_second.yaml
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152 : ok=3 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=3 changed=2 unreachable=0 failed=0
以上執行結果就沒有 了安裝與啟動的步驟~只有更新和重啟!
更多playbook使用示例請添加鏈接描述
總結:
ansible通過常用模塊在命令行就可以針對主機清單來管理配置遠程主機,無需要代理客戶端程序,但需要目標主機有ssh和python2.4+;基於
ssh協議既可以通過用戶名和密碼,也可以通過私鑰,推薦使用私鑰;
windows上需要安裝powershell及winrm服務也可以做到,關於這方面 可以參考我之前的博客 ansible自動化管理windows
通過ansib-doc來獲取模塊信息及指定模塊幫助信息;
ansible-playbook 基於YAML語法配置;可以對playbook文件進行測試,解析並執行應用於指定無端主機;非常方便我們統一編排分發管理遠程主機;
本文如有不當之處歡迎留言交流,當前只是入門,後續更強大功能後續再更新!
ansible入門與playbook實戰