『Ansible 上手指南:2』

Ansible 上手指南 2.png

讀一本書最好的時機是何時?是你剛買的時候,趁着新鮮勁,先了解這本書,繼而立刻閱讀完這本書。若是錯過了最好的時機閱讀一本書,那何時是合適的時機,是你須要這方面的資料或者知識的時候。html

最近我一直在研究 Ansible 自動化運維工具。入手請參考 Ansible 上手指南。主要是爲了實現本身在遠程主機進行相關操做的任務,以此爲切入點進行學習。node

在實現了本身的任務後,我準備繼續研究下 Ansible 的其餘用法。下面就是個人我的總結。shell


體會:編程

  • 文檔內容不少,不可能所有掌握,使用 2/8 法則,看看同事們口中的主要內容有哪些
  • 實踐型的內容,仍是須要本身寫寫代碼,運行,看看效果。當你跑通了你本身寫的代碼,有可能你就學會了這個知識點
  • 快速入手的方法是:若是你急切須要解決問題,那就問有經驗的人。若是你不是很急,先嚐試瞭解下內容,不懂再問別人。反覆提出你的疑問。
  • 提問題不要以爲很差意思,時間很珍貴的。

下面的總結主要以例子爲主:ubuntu

  • 第一稿:拋棄全部參考資料,憑藉實踐的經驗總結
  • 第二稿:彌補不明白的地方
  • 第三稿:對着參考文獻修正不對的地方,發佈

大綱:bash

  • ansible.cfg 配置文件
  • 變量
  • 判斷
  • 循環
  • 經常使用模塊
    • debug
    • copy
    • file
    • shell
    • command
    • stat
    • unarchive
    • ping
    • template
    • user
    • group
    • service
    • get_url
  • include
  • role
    • 目錄結構
    • 依賴
    • 執行順序

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_CONFG 環境變量中定義
  • ansible.cfg 當前目錄
  • */ansible.cfg 當前用戶home/username/ansible.cfg
  • /etc/ansible/ansible.cfg 默認生成的文件路徑

怎麼理解這個讀取配置文件的信息呢?

舉個例子:

# 當前項目結構

ansible:
---playbooks
---example
---leanr-ansible/example.yml
---ansible.cfg

複製代碼

你在這個目錄下執行:ansible 命令

  • 那麼首先查看環境變量有沒有設置,沒有那就讀取當前目錄下的ansible.cfg 配置信息;
  • 若是當前目錄沒有設置,那麼就搜索home 目錄下有沒有配置信息。
  • 不然讀取默認生成的配置信息。

四、經常使用模塊

操做動做舉例

這裏爲舉例只明白這些模塊的使用場景,故意執行多步操做。

  • 拷貝管理節點 /home/ubuntu/zartclient 下的 zartclizartcli.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 目錄下
  • 在節點主機上拷貝解壓以後的文件至 /etc/opcli 目錄下
  • 在節點主機上拷貝 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"}

複製代碼

能夠看出,處理相應的動做,有相應的模塊,模塊帶參數,完成任務。

  • {{ }} 裏面表示變量
  • with_items: 是一個列表,表示循環獲取變量
  • register : 表示把執行的動做結果賦值給一個變量,是一個map, 能夠根據鍵值,獲取內容
  • when: 表示判斷, 根據結果的布爾值進行操做

第二步:先查詢是否存在文件,存在則執行下載命令

第一步拷貝的文件是一個客戶端,主要是對文件的上傳、下載、查詢等。

模塊: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


複製代碼
  • item 是個關鍵字,表示變量
  • item[0] 能夠表示變量是一個列表,這裏表示列表的第一個值
  • item.src 能夠表示變量是一個map, 這裏表示map的src 的值
  • vars 表示模塊中能夠填充自定義的變量名稱對應的值

第三步:解壓下載的文件

第二步下載的文件內是一個 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"
    


複製代碼
  • yes 和 true 沒區別
  • remote_src: yes 表示解壓的文件在節點主機上操做

第四步:拷貝文件

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

複製代碼
  • with_nested: 嵌套循環

上文至關於: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 # 第六步
    
    ...


複製代碼

五、 include_tasks

假如你但願寫的task 可以進行復用,就至關於編程領域裏的抽象出函數同樣。ansible 提供這樣的機制。即將上文一個很大的文件拆分紅獨立的文件。使用 include_tasks 方法將文件導入。

好比:上文的五步動做分別單獨寫文件

  • zartclient.yml
  • download.yml
  • untarfile.yml
  • copyfile.yml
  • executecommand.yml

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
    

複製代碼

即將各個處理動做獨立出去。隨時複用。

六、roles

看上去 include_tasks 方式就是對ansible-playbook 的一種比較好的組織方式了。

ansible 提供了一種更好的組織方式:roles

Roles 基於一個已知的文件結構,去自動的加載某些 vars_files,tasks 以及 handlers。基於 roles 對內容進行分組,使得咱們能夠容易地與其餘用戶分享 roles。 這樣的組織方式使得複用更爲簡便。每一個相對獨立的處理動做獨立出來,能夠適用於更復雜的場景。

一個role 的文件大概包括這些:

  • tasks 文件:主要編寫某個獨立模塊的處理動做
  • handlers 文件:
  • vars 文件: 主要編寫某個獨立模塊的變量
  • meta 文件:主要編寫依賴關係,即一個獨立模塊引用另外一個role
  • defaults 文件:默認的變量文件
  • templates 文件: 模板文件
  • files 文件

注意文件夾下能夠有多個後綴名爲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_taskspost_tasks

  • pre_tasks 最早執行
  • post-tasks 最後執行

再一個使用roles 須要配置 ansible.cfg

roles_path = 目錄
# 即roles 所在的文件目錄
複製代碼

七、參考文獻


這些原理性的東西,用文字不是很好講,之後遇到文字難以表達出來,我錄個視頻實際操做下。這樣讀者可能更好理解。

相關文章
相關標籤/搜索