Ansible是新出現的自動化運維工具,基於Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優勢,實現了批量系統配置、批量程序部署、批量運行命令等功能。Ansible是一個批量的自動化部署工具。php
ansible:node
模塊:python
1) yaml 用來編寫yaml腳本的語言linux
2) paramiko 模擬ssh協議鏈接linux客戶端web
3) jinja2 模板語言shell
工做原理:apache
ansible經過hosts文件和免祕鑰(配置文件用戶名密碼端口號)來實現批量管理主機。vim
Ansible是基於模塊工做的,自己沒有批量部署的能力。真正具備批量部署的是ansible所運行的模塊,ansible只是提供一種框架。主要包括:centos
1> Ansible:Ansible的核心程序;安全
2> connection plugins:鏈接插件,負責和被監控端實現通訊,即Ansible和host的通訊;
3> Host inventory:指定操做的主機,是一個配置文件裏面定義監控的主機;
4> Core Modules:核心模塊,Ansible執行任何管理任務都不是由Ansible本身完成,而是由核心模塊完成;Ansible管理主機以前,先調用core Modules中的模塊,而後指明管理Host Lnventory中的主機,就能夠完成管理主機。
5> Custom Modules:自定義模塊,完成Ansible核心模塊沒法完成的功能,此模塊支持任何語言編寫。
Ansible將不少命令集成爲模塊調用。
6> Playbook:YAML格式文件,多個任務定義在一個文件中,使用時能夠統一調用,「劇本」用來定義那些主機須要調用那些模塊來完成的功能。劇本執行多個任務時,非必需可讓節點一次性運行多個任務。
簡而言之ansible有以下的特色:
三臺主機,192.168.16.4爲服務機,.五、.6爲服務機
Ansible安裝須要用到擴展源(epel源),擴展源配置完成便可用yum進行下載
在.3上下載安裝
[root@localhost ~]# yum install ansible -y
稍等……..
Complete!
Ansible的配置文件
/etc/ansible/ansible.cfg
/etc/ansible/hosts
有兩種方法
1> 進入服務端配置文件進行配置
#在文件末尾寫入配置 [root@localhost ~]# vim /etc/ansible/hosts [zxj] #組名 192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl 192.168.16.6 ansible_ssh_user=root ansibel_ssh_port=22 ansible_ssh_pass=zxjwrl #遠程節點主機 用戶 端口 密碼 [root@localhost ~]# vim /etc/ansible/ansible.cfg host_key_checking = False #進入配置文件,關掉檢查
2> 免祕鑰登陸
sshd服務
配置完成後,查看Ansible是否與管理節點通
[root@localhost ~]# ansible zxj -m ping #主機組名能夠替換爲單獨的節點ip或者直接改成all,all表示全部主機,ip表示組名下單獨的一個節點 192.168.16.6 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.16.5 | SUCCESS => { "changed": false, "ping": "pong" }
查看Ansible的模塊
[root@localhost ~]# ansible-doc -l
經常使用的模塊
ping 模塊: 嘗試鏈接主機,若是測試成功會返回‘pong’
command模塊: 在遠程節點執行命令
yum模塊: 使用yum軟件包管理工具管理軟件包
shell模塊: 和command模塊相似,執行命令,支持變量等符號
cron模塊 : 管理定時任務,計劃任務
service模塊: 管理程序服務
file模塊: 設置文件屬性
copy模塊: 複製本地文件到遠程主機
script模塊: 傳送本地的一個腳本並在遠程主機上執行
setup模塊: 獲取遠程主機的參數信息
user模塊: 管理用戶帳戶
group模塊: 添加或者刪除用戶組
查看具體模塊的用法,以yum模塊爲例
[root@localhost ~]# ansible-doc -s yum - name: Manages packages with the `yum' package manager yum: allow_downgrade: # Specify if the named ……. state: # Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package. `present' and `installed' will simply ensure that a desired package is installed. `latest' will update the specified package if it's not of the latest available version. `absent' and `removed' will remove the specified package. Default is `None', however in effect the default action is `present' unless the `autoremove' option is¬ enabled for this module, then `absent' is inferred.
協程:線程的處理單元;
線程:最小的調度單位;
進程:是最小的管理單元;
一個進程裏面至少1個線程,一個線程或者多個線程能夠在一個進程裏面。
hoc命令行下的命令:
ansible-doc -l |
查看支持的模塊 |
ansible-doc -s MODEL_NAME |
查看模塊的用法 |
-f forks |
指定啓動併發線程數以減小服務器壓力,如ansible -f 5 表示啓動五個線程 |
-m model_name |
要使用的模塊 |
-a args1 |
特有的參數,即調用的模塊裏面的參數,使用-a調用 |
ansible all -m ping |
查看client端是否正常ping通 |
經過調用來執行命令舉例詳解
格式: ansible 組名 -m model_name -a 執行命令
#查看客戶端信息 [root@localhost ~]# ansible zxj -m setup …….. #複製文件 #複製並更名 [root@localhost ~]# ansible zxj -m copy -a "src=/root/zxj.txt dest=/root/wrl.txt" 192.168.16.6 | CHANGED => { #源文件 目標文件 "changed": true, #注意冪等性 "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/root/wrl.txt", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:admin_home_t:s0", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1557345658.29-197424182241042/source", "state": "file", "uid": 0 } 192.168.16.5 | CHANGED => { "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/root/wrl.txt", "gid": 0, "group": "root", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:admin_home_t:s0", "size": 0, "src": "/root/.ansible/tmp/ansible-tmp-1557345658.28-200767865941415/source", "state": "file", "uid": 0 } #在客戶機下查看 .5: [root@localhost ~]# ls anaconda-ks.cfg wrl.txt .6: [root@localhost ~]# ls \anaconda-ks.cfg wrl.txt #command命令 [root@localhost ~]# ansible zxj -m command -a 'date' #-a後面的引號內能夠加任何正確的命令 192.168.16.6 | CHANGED | rc=0 >> Thu May 9 03:52:53 CST 2019 192.168.16.5 | CHANGED | rc=0 >> Thu May 9 03:52:53 CST 2019 #command命令會進行警告。進入配置文件/etc/ansible/ansible.cfg改command_warnings = False #建立、刪除用戶 [root@localhost ~]# ansible zxj -m user -a "name=zxj state=present" #user模塊 用戶名 執行狀態(此處爲別名) [root@localhost ~]# ansible zxj -m user -a "name=zxj state=absent" #安裝、卸載軟件 [root@localhost ~]# ansible zxj -m yum -a "name=httpd state=latest" [root@localhost ~]# ansible zxj -m yum -a "name=httpd state=absent" #若是用install、remove等必須寫成單詞的過去式 #注意:yum模塊和yum命令同名,所以執行時會警告,進入配置文件/etc/ansible/ansible.dfg改deprecation_warnings = False #啓動apache服務 [root@localhost ~]# ansible zxj -m service -a "name=httpd state=started" #stopped、restarted、started等均爲過去式,ansible不支持systemctl,用centos6及之前版本的service代替 #運行腳本 [root@localhost ~]# ansible zxj -m script -a "/tmp/test.sh" #爲腳本絕對路徑 等等
一個任務爲play,多個任務爲playbooks
yaml是一個可讀性高的用來表達資料序列的格式,yaml參考了其餘多種語言,包括:xml,c語言,python,perl以及電子郵件格式RFC2822等,ClarkEvans在2001年在首次發表了這種語言。
yaml的可讀性好
yaml和腳本語言的交互性好
yaml使用實現語言的數據類型
yaml有一個一致的信息模型
yaml易於實現
yaml能夠基於流程來處理
yaml表達能力強,擴展性好
tasks:主程序;
variables:變量,以變量形式傳參;
templates:模板;
handlers:觸發器;
roles:角色。
腳本名以 .yaml或yml結尾;
必定不能使用tab鍵,yaml有嚴格的縮進要求;
每一個冒號:後面必須有空格;
注意:
1)以冒號結尾不須要空格
2)表示文件路徑的模版能夠不須要空格
想要表示列表項,使用一個短橫槓加一個空格。多個項使用一樣的縮進級別做爲同一個列表的一部。
1)對劇本語法檢測
ansible-playbook --syntax-check /root/ansible/httpd.yaml
2)-C模擬執行劇本
ansible-playbook -C /root/ansible/httpd.yaml
3)執行劇本
ansible-playbook /root/ansible/httpd.yaml
#建立實例文件 [root@localhost ~]# vim example.yaml # 以yaml或者yml - hosts: zxj # - 必須頂格寫,後面必須加空格,hosts:表示定義主機組,冒號後面必須加空格,後面跟的內容能夠是all、ip或主機名 remote_user: root # 指定遠程用戶,以root運行,remote必須和host對齊,冒號後面必須加空格 tasks: # 調用任務模塊,tasks必須與remote對齊,在tasks下面開始寫命令 - name: create userzxj # 橫杆和task對齊,與name之間必須有空格,冒號後面必須加空格,後面定義任務名 user: name=userzxj # 調用user模塊,user必須與name對齊,冒號後面必須加空格。一個任務已經完成,能夠繼續往下添加任務,格式一致 #如添加複製任務 - name: copy httpd.conf copy: src=/etc/httpd/conf/httpd.conf dest=/root/test/httpd.conf
#或者定義變量,經過jinjia2裏的模板語言{{ }}來引用變量執行 - hosts: zxj remote_user: root vars: #定義變量 - p: httpd.conf #p爲變量名,與橫槓間必須有空格,http爲變量值 tasks: - name: create userzxj user: name=userzxj - name: copy httpd.conf copy: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} #引用變量 #再定義觸發器,觸發器僅由相鄰的上一個任務觸發,上一個任務執行成功才觸發執行 - hosts: zxj remote_user: root vars: - p: httpd.conf tasks: - name: create userzxj user: name=userzxj - name: copy httpd.conf copy: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} notify: #申明定義觸發器 - service httpd restarted #定義觸發器名字 handlers: #定義觸發器,必須在最後,必須與hosts對齊 - name: service httpd restarted #定義任務名,必須與觸發器名字相同 service: name=httpd state=restarted #調用service模塊,執行命令
:wq #執行yaml文件用命令ansible-playbook [root@localhost ~]# ansible-playbook example.yaml PLAY [zxj] ********************************************************
TASK [Gathering Facts] ********************************************** #測試ansible是否與客戶端連通,該任務自動執行 ok: [192.168.16.5] #冪等性,因爲先前執行過,並無改變,但該命令執行成功 ok: [192.168.16.6]
TASK [create userzxj] ********************************************* #執行第一個任務 ok: [192.168.16.6] ok: [192.168.16.5] TASK [copy httpd.conf] ********************************************** #執行第二個任務 changed: [192.168.16.5] #冪等性,因爲先前並無執行過,所以改變,任務執行成功 changed: [192.168.16.6] RUNNING HANDLER [service httpd restarted] ************************* #第二個命令執行成功自動觸發 changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP ***************************************************** 192.168.16.5 : ok=4 changed=2 unreachable=0 failed=0 192.168.16.6 : ok=4 changed=2 unreachable=0 failed=0 #服務端查看httpd啓動 #.5: [root@localhost ~]# ss -tnl LISTEN 0 128 :::80 :::* .6 [root@localhost ~]# ss -tnl LISTEN 0 128 :::80 :::* #端口前的星號表示ipv4,冒號表示ipv6和ipve4 #能夠建立多個觸發器,依託於上一個任務
#還能夠進行迭代建立 - hosts: zxj remote_user: root vars: - p: httpd.conf tasks: - name: create many users user: name={{ item }} #進行迭代建立 with_items: #使用迭代 - zxj1 #建立多個用戶 - zxj2 - zxj3 #模塊都可進行迭代執行 #對於模板模塊template,在配置文件裏寫入對應模板,yaml文件在執行命令模塊的時候調用模板模塊就能夠了,如: #要執行復制http文件任務,進入httpd配置文件,將監聽端口改成jinjia2的模板文件,緊接着修改ansible的配置文件 [root@localhost ~]# vim /etc/httpd/conf/httpd.conf #Listen 12.34.56.78:80 Listen {{ port }} # 變量名能夠任意取 [root@localhost ~]# vim example.yaml - name: copy httpd.conf template: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} [root@localhost ~]# vim /etc/ansible/hosts ## db-[99:101]-node.example.com [zxj] 192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=5000 #寫入端口,寫入變量 192.168.16.6 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=6000 #引用多個模板文件時能夠在該配置文件後面空格後繼續寫
什麼狀況下用到roles:
假如如今有3個被管理主機,第一個要配置成httpd,第二個要配置成php服務器,第三個要配置成MySQL服務器。要如何來定義playbook?
第一個play用到第一個主機上,用來構建httpd,第二個play用到第二個主機上,用來構建php,第三個play用到第三個主機上,用來構建MySQL。這些個play定義在playbook中比較麻煩,未來也不利於模塊化調用,不利於屢次調用。好比說後來又加進來一個主機,這個第4個主機既是httpd服務器,又是php服務器,只能寫第4個play,上面寫上安裝httpd和php。這樣playbook中的代碼就重複了。這時咱們能夠經過roles來實現,將各個模塊命令集成在roles下的服務裏面,直接調用服務便可。
Roles實例詳解
使用目錄代替命令,各個目錄以下:
files:定義src(源)文件
handlers:定義觸發器
tasks:定義任務
templates:定義模板文件
vars:定義變量
各個目錄寫入文件後放入server目錄,執行時直接調用目錄。
#1 建立級聯目錄 [root@localhost ~]#mkdir-p playbooks/roles/{webservers,dbservers}/{files,handlers,tasks,templates,vars} [root@localhost ~]# tree playbooks/ #查看定義的roles樹 playbooks/ └── roles ├── dbservers #角色 │ ├── files │ ├── handlers │ ├── tasks │ ├── templates │ └── vars └── webservers #角色 ├── files ├── handlers ├── tasks ├── templates └── vars #2. 編輯命令 [root@localhost ~]# vim playbooks/roles/webservers/tasks/main.yml #文件名必須是main.yaml或者main.yml在建立的文件裏直接寫任務,沒必要再聲明組名等信息 - name: create user userzxj #寫入多個命令 user: name=userzxj - name: service httpd start service: name=httpd state=started :wq #3. 建立與roles同等級別的site(站點)文件 [root@localhost ~]# cd playbooks/ [root@localhost playbooks]# vim site.yml #文件名必須爲site - hosts: zxj #定義組名和遠程用戶 remote_user: root roles: #調用roles - webservers #寫入角色,執行角色下的任務 - dbservers :wq #4. 執行任務 [root@localhost playbooks]# ansible-playbook site.yml #執行site文件 PLAY [zxj] ********************************************************* TASK [Gathering Facts]*********************************************** ok: [192.168.16.6] ok: [192.168.16.5] TASK [webservers : create user userzxj]********************************** changed: [192.168.16.6] changed: [192.168.16.5] TASK [webservers : service httpd start]************************************ changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP ******************************************************* 192.168.16.5 : ok=3 changed=2 unreachable=0 failed=0 192.168.16.6 : ok=3 changed=2 unreachable=0 failed=0 #執行成功
files目錄:定義roles後scr(源文件)不須要寫絕對路徑,只聲明路徑便可
#1. 準備實驗文件 [root@localhost playbooks]# cp /etc/httpd/conf/httpd.conf roles/webservers/files/ #2. 寫入任務目錄 [root@localhost playbooks]# vim roles/webservers/tasks/main.yml - name: copy httpd copy: src=httpd.conf dest=/root/test/httpd.conf #scr不須要再寫絕對路徑 :wq #3. 執行site.yml [root@localhost playbooks]# ansible-playbook site.yml …… 192.168.16.5 : ok=2 changed=1 unreachable=0 failed=0 192.168.16.6 : ok=2 changed=1 unreachable=0 failed=0
handlers目錄,觸發任務
#1. 寫入任務文件,不須要以handlers結尾 [root@localhost playbooks]# vim roles/webservers/tasks/main.yml - name: copy httpd copy: src=httpd.conf dest=/root/test/httpd.conf notify: #聲明觸發 - restart httpd #定義名稱,不須要再以handlers結尾 #2. 寫入handlers下的main.yml [root@localhost playbooks]# vim roles/webservers/handlers/main.yml - name: restart httpd service: name=httpd state=restarted #3. 執行site.yml [root@localhost playbooks]# ansible-playbook site.yml PLAY [zxj] *************** TASK [Gathering Facts] ********* ok: [192.168.16.5] ok: [192.168.16.6] TASK [webservers : copy httpd] ************** changed: [192.168.16.5] changed: [192.168.16.6] RUNNING HANDLER [webservers : restart httpd] ************* #觸發 changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP ************ 192.168.16.5 : ok=3 changed=2 unreachable=0 failed=0 192.168.16.6 : ok=3 changed=2 unreachable=0 failed=0
template目錄,執行copy命令時調用定義的模板參數
#1. 寫入任務文件 [root@localhost playbooks]# vim roles/webservers/tasks/main.yml - name: copy httpd template: src=httpd.conf dest=/root/test/httpd.conf #src不寫絕對路徑 notify: - restart httpd #2. 定義模板參數 [root@localhost playbooks]# cp roles/webservers/files/httpd.conf roles/webservers/templates/httpd.conf [root@localhost playbooks]# vim roles/webservers/templates/httpd.conf #Listen 12.34.56.78:80 Listen {{ port }} #更改監聽端口爲模板參數 #3. 更改配置文件 [root@localhost ~]# vim /etc/ansible/hosts [zxj] 192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=5000 #寫入參數 192.168.16.6 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=6000 #寫入參數 #4. 執行site.yml文件 [root@localhost playbooks]# ansible-playbook site.yml PLAY [zxj]……. TASK [webservers : copy httpd] * changed: [192.168.16.5] changed: [192.168.16.6] RUNNING HANDLER [webservers : restart httpd] changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP *************** changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP *************** 192.168.16.5 : ok=3 changed=2 unreachable=0 failed=0 192.168.16.6 : ok=3 changed=2 unreachable=0 failed=0
var目錄,定義參數
#1. 定義var的main.yml [root@localhost playbooks]# vim roles/webservers/vars/main.yml p: httpd.conf #定義變量p,變量值爲httpd.conf
#2. 修改任務變量 [root@localhost playbooks]# vim roles/webservers/tasks/main.yml - name: copy httpd template: src={{ p }} dest=/root/test/{{ p }} notify: - restart httpd
#3. 執行site.yml
roles下的角色,如webserver、dbserver等能夠並排寫入與roles同級的site.yml文件,執行多個角色,每一個角色均可以寫入多個任務,實現不一樣量的批量部署。