1. 程式人生 > >ansible入門與playbook實戰

ansible入門與playbook實戰

bind directory rontab tab configure 當前 cat sent 鍵值對

一、簡要

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‘ 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"

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實戰