讀一本書最好的時機是何時?是你剛買的時候,趁着新鮮勁,先了解這本書,繼而立刻閱讀完這本書。若是錯過了最好的時機閱讀一本書,那何時是合適的時機,是你須要這方面的資料或者知識的時候。html
最近我一直在研究 Ansible 自動化運維工具。入手請參考 Ansible 上手指南。主要是爲了實現本身在遠程主機進行相關操做的任務,以此爲切入點進行學習。node
在實現了本身的任務後,我準備繼續研究下 Ansible 的其餘用法。下面就是個人我的總結。shell
體會:編程
下面的總結主要以例子爲主:ubuntu
大綱:bash
Ansible 是使用Python 編寫,基於模塊化的工做方式,真正處理動做都是這些模塊。Ansible 提供總體的框架。框架
pip install ansible
複製代碼
或者根據Linux 的版本進行安裝運維
apt-get install ansible
複製代碼
管理主機要求是Linux, 節點主機須要帶 Python 及相應的庫。模塊化
通常是管理主機和節點主機都是Linux。函數
命令行方式運行:
命令行方式適合操做簡單的動做。
ansible all -m ping
複製代碼
playbook 運行:
playbook 適合複雜的處理動做。
ansible-playbook example.yml
複製代碼
查看支持的模塊:
ansible-doc -l
複製代碼
查看某模塊用法及支持的參數:
ansible-doc -s ping
複製代碼
安裝完成以後,默認目錄下有兩個文件:
/etc/ansible/hosts
/etc/ansible/ansible.cfg
複製代碼
hosts 文件定義節點主機的IP 及如下配置信息。
ansible.cfg 文件定義全局配置文件,配置項不少, 通常默認就能夠完成你的平常任務了。
可是除默認的生成的 ansible.cfg 文件以外,你能夠在本身的項目中建立這樣一個同名ansible.cfg 文件。
ansible 讀取配置文件的順序是:
怎麼理解這個讀取配置文件的信息呢?
舉個例子:
# 當前項目結構
ansible:
---playbooks
---example
---leanr-ansible/example.yml
---ansible.cfg
複製代碼
你在這個目錄下執行:ansible 命令
操做動做舉例
這裏爲舉例只明白這些模塊的使用場景,故意執行多步操做。
/home/ubuntu/zartclient
下的 zartcli
和 zartcli.ini
文件至節點主機 /home/ubuntu/zartclient
下/home/ubuntu/zartclient/zartcli
至 /usr/bin/zartcli
zartcli -o=download -i=admin -m=bin -n=op-cli -v=v0.0.3 -p=/home/ubuntu/download
下載至 /home/ubuntu/download
目錄/paasdata/data
目錄下op-cli
至 /usr/bin
op-cli task list
執行命令op-cli node list
執行命令快閱讀時代,估計沒人想認真看這些動做。畫個流程圖吧。
把每一步動做認爲是一個任務 task.
第一步:先檢查是否存在對應的文件,是則拷貝
模塊:stat, copy, debug, file
- name: is /home/ubuntu/zartclient exists
stat:
path: /home/ubuntu/zartclient
register: result
- name: show result
debug:
msg: "{{result}}"
- name: create dest path in remote
file:
path: "{{ dest-path }}"
state: direstory
with_items:
- "/home/ubuntu/zartclient"
when: not result.stat.exists
- name: copy file to remote
copy:
src: "{{item.src}}"
dest: "{{item.dest}}"
with_items:
- { src: "/home/ubuntu/zartclient/zartcli" dest: "/home/ubuntu/zartclient"}
- { src: "/home/ubuntu/zartclient/zartcli.ini" dest: "/home/ubuntu/zartclient"}
- name: copy zartcli into /usr/bin
copy:
src: "{{item.src}}"
dest: "{{item.dest}}"
with_items:
- { src: "/home/ubuntu/zartclient/zartcli", dest: "/usr/bin"}
複製代碼
能夠看出,處理相應的動做,有相應的模塊,模塊帶參數,完成任務。
{{ }}
裏面表示變量第二步:先查詢是否存在文件,存在則執行下載命令
第一步拷貝的文件是一個客戶端,主要是對文件的上傳、下載、查詢等。
模塊:shell 、 command
- name: is /home/ubuntu/download exists
stat:
path: "{{item}}"
with_items:
- "/home/ubunt/download"
register: result
- name: create /home/ubuntu/download
file:
path: "{{item}}"
state: direstroy
with_items:
- "home/ubuntu/download"
when: not result.stat.exists
- name: query op-cli
command: "{{tools}} -o={{operate}} -i={{tenants}} -m={{type}} -n={{name}} \ -v={{version}}"
vars:
tools: zartcli
operate: query
tenants: admin
type: bin
name: op-cli
version: v0.0.3
register: result
- name: download op-cli
command: "{{tools}} -o={{operate}} -i={{tenants}} -m={{type}} -n={{name}} \ -v={{version}} -p={{path}}"
vars:
tools: zartcli
operate: query
tenants: admin
type: bin
name: op-cli
version: v0.0.3
path: /home/ubuntu/download
複製代碼
第三步:解壓下載的文件
第二步下載的文件內是一個 tar 包,須要將其解壓至指定目錄
模塊:unarchive, file
- name: create /paasdata/data
file:
path: "/paasdata/data"
state: direstory
- name: untar file
unarchive:
src: "{{src-path}}"
dest: "{{dest-path}}"
remote_src: yes
vars:
src-path: "/home/ubuntu/download/admin_op_cli_v0.0.3/op-cli.tar.gz"
dest-path: "/paasdata/data"
複製代碼
第四步:拷貝文件
- name: create /etc/opcli
file:
path: "/etc/opcli"
state: directory
- name: copy /paadata/data/conf||op-cli
copy:
src: "{{item.src}}"
dest: "{{item.dest}}"
with_items:
- { src: "/paasdata/data/conf/common.yml" dest: "/etc/opcli/conf"}
- { src: "/paasdata/data/op-cli" dest: "/usr/bin"}
複製代碼
第五步:執行查詢命令
- name: op-cli task list || op-cli node list
command: "{{item[0]}} {{item[1]}} list"
with_nested:
- [ "op-cli" ]
- ["task", "node", "nodepool"]
複製代碼
上文至關於:op-cli task list, op-cli node list, op-cli nodepool list
上文借用一些循環,把以前規劃的 八 個動做改爲了 五個動做, 即 五 個動做內的每個又包含幾個動做。
新手容易把上面的全部的動做都處理在一個文件內:可是其實存在更好的處理方法。
# main.yml
---
- hosts: 10.62.60.21
romote_user: root
tasks:
- name: one # 第一步
- name: two # 第二步
- name: three # 第三步
- name: four # 第四步
- name: five # 第五步
- name: six # 第六步
...
複製代碼
假如你但願寫的task 可以進行復用,就至關於編程領域裏的抽象出函數同樣。ansible 提供這樣的機制。即將上文一個很大的文件拆分紅獨立的文件。使用 include_tasks 方法將文件導入。
好比:上文的五步動做分別單獨寫文件
playbook 入口: mail.yml
則main.yml 以下:
---
- hosts: 10.62.60.21
root_usr: root
tasks:
- include_tasks: zartclient.yml
- include_tasks: download.yml
- include_tasks: untarfile.yml
- include_tasks: copyfile.yml
- include_tasks: executecommand.yml
複製代碼
即將各個處理動做獨立出去。隨時複用。
看上去 include_tasks 方式就是對ansible-playbook 的一種比較好的組織方式了。
ansible 提供了一種更好的組織方式:roles
Roles 基於一個已知的文件結構,去自動的加載某些 vars_files,tasks 以及 handlers。基於 roles 對內容進行分組,使得咱們能夠容易地與其餘用戶分享 roles。 這樣的組織方式使得複用更爲簡便。每一個相對獨立的處理動做獨立出來,能夠適用於更復雜的場景。
一個role 的文件大概包括這些:
注意文件夾下能夠有多個後綴名爲yml
的文件,但必定要有main.yml
文件
上文的處理動做,使用 roles 從新組織以下:
目錄:
├─ansible
│ ├─playbook
│ └─roles
│ ├─download-bin
│ │ ├─tasks
│ │ └─vars
│ └─op-cli
│ ├─meta
│ ├─tasks
│ └─vars
複製代碼
這裏以上文的處理動做:下載文件獨立成一個 download-bin role 爲例,講述如何編寫 role.
tasks/deploy.yml
- name: download bin by zartcli
command: "{{zartcli_cli_path}}/zartcli -o=download -i={{tenant_id}} -m={{bin_type}} \ -n={{bin_name}} -v={{bin_version}} -p={{download_path}}"
複製代碼
tasks/main.yml
---
- include_tasks: download.yml
vars:
zartcli_cli_path: "{{zartcli_clipath}}"
tenant_id: "{{tenantid}}"
bin_name: "{{binname}}"
bin_version: "{{binversion}}"
download_path: "{{downloadpath}}"
bin_type: "{{bintype}}"
複製代碼
vars/main.yml
---
zartcli_clipath: "/home/cloud/zartclient"
tenantid: "admin"
binname: "op-cli"
binversion: "v0.0.3"
downloadpath: "/home/cloud/zartclidownload"
bintype: "bin"
複製代碼
task/main.yml 是這個role 的入口。導入download.yml,下載所須要的變量所有置放在 var/main.yml 文件中。
別的role 須要複用這個模塊:
op-cli/meta/main.yml
dependencies:
- role: download-bin
複製代碼
這樣 op-cli role 也有download 動做。
roles 適用於組織較爲複雜的項目,將各個模塊獨立處理,又能夠相互複用。使用 include_tasks 存在模塊的複用性變低、變量須要重複定義等缺點。
上文 op-cli role 複用download-bin,無需再次定義變量。
再一個值得注意的是:通常playbook 的執行順序和task 的定義順序一致。
使用 roles 後,playbook 中 roles 先執行,再按tasks 的定義順序執行。
若是須要最早執行某個task , 或者最後執行某個task, 可使用pre_tasks
和 post_tasks
。
pre_tasks
最早執行post-tasks
最後執行再一個使用roles 須要配置 ansible.cfg
roles_path = 目錄
# 即roles 所在的文件目錄
複製代碼
這些原理性的東西,用文字不是很好講,之後遇到文字難以表達出來,我錄個視頻實際操做下。這樣讀者可能更好理解。