Ansible入門與playbook實戰

1、簡要

一、關於Ansible
Ansible是一個部署一羣遠程主機的工具;Ansible經過SSH協議實現遠程節點和管理節點之間的通訊。理論上說,只要管理員經過ssh登陸到一臺遠程主機上能作的操做,Ansible均可以作到。Ansible是python開發的,故依賴一些python庫和組件,如:paramiko,PyYaml和jinja三個關鍵組件;html

二、ansible架構:
Ansible入門與playbook實戰
右邊綠色部分是被管理的主機(虛擬機,物理機,雲主機等)從以上架構圖中能夠看出
ansible是由主機清單(配置),playbook(配置),以及各模塊插件組成;
簡單的說就是,用戶(管理員)經過ansible的主機清單配置或Playbook配置(一組任務),調用ansible的各類模塊及參數來對
清單中的主機進行統一管理;node

三、測試環境
本次測試環境:
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上python

[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 root@172.16.3.152 就無密碼登陸上去啦!
配置ansible的主機清單,即把node1與node2主機添加到管理清單中nginx

[root@ansible ~]# egrep -v '(^$|^#)' /etc/ansible/hosts
[websrvs]
172.16.3.152
172.16.3.216

到此處配置的環境完成!git

四、安裝
目前,只要機器上安裝了 Python 2.6 或 Python 2.7 (windows系統不能夠作控制主機),均可以運行Ansible.
安裝ansible很簡單,可經過git從githu上直接獲取代碼,也能夠像redhat/CentOS上經過yum進行安裝,github

[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)]

2、配置及獲取幫助說明

經過rpm -ql ansible能夠看到有不少文件,主要是配置文件和和可執行文件,以及所依賴的python庫文件
一、配置與執行文件說明
ansible的主配置文件
/etc/ansible/ansible.cfg
這個文件主要定義了roles_path路徑,主機清單路徑,鏈接清單中的主機方式等配置,這些大部的默認配置已經足夠咱們平時使用,如須要特別配置能夠自行去修改;
/etc/ansible/hosts
這個配置文件就是默認主機清單配置文件,可經過ansible.cfg從新定義的;
如定義一組主機:web

[root@ansible ~]# egrep -v '(^$|^#)' /etc/ansible/hosts
[websrvs]
172.16.3.152
172.16.3.216

除了以上兩個重要的配置文件還有三個重要的可執行文件分別是:
ansible 主執行程序,通常用於命令行下執行
ansible-playbook 執行playbook中的任務
ansible-doc 獲取各模塊的幫助信息redis

二、ansible 使用格式
ansibleshell

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

三、ansible-doc 獲取幫助信息
ansible模塊比較多,能夠經過ansible-doc --help 顯示幫助信息
ansible doc -l 獲取全部當前版本下的可用模塊及簡要信息
ansible-doc -s 模塊名 獲取指定模塊幫助信息說明``windows

3、ansible經常使用模塊

一、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

二、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的路徑

三、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模塊;

四、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)

五、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, 
     .....省略.....

六、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
會發現已經被刪除了

七、yum模塊
故名思義就是yum安裝軟件包的模塊;
經常使用參數說明:
enablerepo,disablerepo表示啓用與禁用某repo庫
name 安裝包名
state (present' orinstalled', 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"

八、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
......省略......

九、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模塊這個功能能夠作不少事,就看你怎麼用了~
以上是經常使用模塊,至於其餘模塊的使用可經過官方模塊列表得到~

4、Playbook實戰

playbook是Ansible的配置,部署和編排的語言。他們能夠描述你所但願的遠程系統強制執行的政策,或者在通常的IT流程的一組步驟;形象點的說就是:若是ansible的各模塊(能實現各類功能)是車間裏的各工具;playbook就是指導手冊,目標遠程主機就是庫存和原料對象.
playbook是基於YAML語言格式配置,關於YAML
更多playbook官方說明參考

一、playbook的核心元素
hosts : playbook配置文件做用的主機
tasks: 任務列表
variables: 變量
templates:包含模板語法的文本文件
handlers :由特定條件觸發的任務
roles :用於層次性、結構化地組織playbook。roles 可以根據層次型結構自動裝載變量文件、tasks以及handlers等

二、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 運行

三、經過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確定有不一樣的配置項,所以須要在安裝時提供配置文件

四、帶配置文件的安裝管理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文件進行測試,解析並執行應用於指定無故主機;很是方便咱們統一編排分發管理遠程主機;本文旨在入門;後續會針對playbook的roles角色及其餘更多強大功能再進行詳細說明;若有不當之處歡迎留言交流!

相關文章
相關標籤/搜索