Ansible入門與playbook實戰

轉載:
https://blog.51cto.com/dyc2005/2070729
一、簡要

1、關於Ansible
Ansible是一個部署一羣遠程主機的工具;Ansible通過SSH協議實現遠程節點和管理節點之間的通信。理論上說,只要管理員通過ssh登錄到一臺遠程主機上能做的操作,Ansible都可以做到。Ansible是python開發的,故依賴一些python庫和組件,如:paramiko,PyYaml和jinja三個關鍵組件;
Ansible入門與playbook實戰
2、ansible架構:
Ansible入門與playbook實戰
右邊綠色部分是被管理的主機(虛擬機,物理機,雲主機等)從以上架構圖中可以看出
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文件進行測試,解析並執行應用於指定無端主機;非常方便我們統一編排分發管理遠程主機;

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