ansible基礎-優化

簡介

當管理集羣達到必定規模時,ansible達到性能瓶頸是難以免的,此時咱們能夠經過必定手段提升ansible的執行效率和性能。html

筆者雖未管理過超大規模服務器,但也經過查找資料和諮詢大神瞭解了一些。現總結一些調優方法,供你們參考。node

Pipelinling

咱們知道ansible執行一個模塊要ssh到目的主機屢次,開啓「pipelining」特性其實是經過減小ssh鏈接次數,從而縮短ansible執行時間。在部署大規模服務器或引用模塊很是多時,開啓「pipelining」特性會給ansible帶來顯著的性能提高。linux

開啓方法也很簡單,將ansible.cfg的pipelining參數設置爲True便可,該參數默認值是False。redis

既然「pipelining」特性默認是關閉的,確定有它的理由:關閉該特性能夠與sudo的requiretty兼容(即/etc/sudoers配置文件的「Defaults requiretty」配置項)。大部分linux操做系統是默認開啓requiretty功能的,因此pipelining也是默認False的。shell

也就是說,若是咱們要開啓pipelining特性,要麼playbook不使用sudo越權功能,要麼取消sudo的「requiretty」特性數據庫

該特性能夠經過命令行添加 -vvvv 後,根據執行結果對比出區別,因篇幅緣由這裏再也不展現。json

適用場景緩存

  • 管理大規模集羣
  • 部署代碼內容不少,調用了大量的ansible模塊 

Control_path

control_path經過設置ControlPath sockets的文件路徑與文件命名避免因sockets文件過長(超過108個字符串)致使ansible報錯的問題。服務器

設置方法爲更改ansible.cfg裏的control_path參數,ansible2.7版本默認值爲「配置項control_path_dir的值」+「根據hostname生成的哈希值」+「ssh端口號」+「用戶名」網絡

在ansible舊版本中,默認值是包含主機名的,這在一些特殊狀況下(例如EC2主機),會因主機名過長致使ControlPath sockets文件過長,從而致使ansible執行報錯。但在新版本中默認值的主機名部分被替換爲主機名的哈希值,這很大程度上避免了該問題的發生。

咱們也能夠設置其餘的參數,例如:

control_path = %(directory)s/%%h-%%r

其中$directiry是control_path_dir的值,後面的參數能夠靈活定製,可用參數以下:

%L 本地主機名的第一個組件 %l 本地主機名(包括域名) %h 遠程主機名(命令行輸入) %n 遠程原始主機名 %p 遠程主機端口 %r 遠程登陸用戶名 %u 本地 ssh 正在使用的用戶名 %i 本地 ssh 正在使用 uid %C 值爲 %l%h%p%r 的 hash

適用場景

當ansible報錯而且使用 -vvvv 查看發現有相似「too long for Unix domain socket」的錯誤信息,咱們應該想到這個調優方式。 

Gather subset

Disable gather facts

在介紹Gather subset以前,咱們先簡單說下gather_facts功能,gather_facts用於控制一個play是否收集目的主機的facts信息(參考《ansible基礎-變量》),默認值爲true/True/yes,寫法以下:

- hosts: nodes gather_facts: True tasks:

在playbook執行過程當中,ansible收集facts變量是很耗時的一個步驟,若是咱們肯定play中沒有用到fact變量信息,能夠直接將其關閉,即將gather_facts設置爲false/False/no。

Gather subset

可是在實際使用中不收集facts變量的狀況不多。在gather_facts關閉的狀況下,咱們能夠給play單獨添加一個setup模塊,並經過gather_subset參數嚴格控制facts的收集種類,這樣既拿到了咱們須要的fact變量又提升了ansible的執行效率,gather_subset參數的默認值爲all。

playbook中使用方法示例:

- name: Collect only facts returned by facter setup: gather_subset: - '!all'
      - '!any'
      - facter

命令行使用方法示例:

# Collect only facts returned by facter. ansible all -m setup -a 'gather_subset=!all,!any,facter'

可用參數有all, min, hardware, network, virtual, ohai, facter,可使用列表的格式指定多個參數,使用「!」指定不收集的facts類型。

比較經常使用的幾個範例:

  • 僅指定facter,說明收集puppet facter和min子集信息(默認包含min子集)。
  • 指定「!all」,說明只收集min子集信息
  • 指定「!all,!min」,說明不收集任何信息
  • 指定「!all,!any」+其餘的fact子集,說明只收集該子集信息 

Fact gather cache

關於facts變量還有一個優化手段,即facts緩存。

fact緩存是指將收集到的facts信息緩存到本地json文件或者redis數據庫內,以便下次執行直接讀取,從而提升執行效率。

關於facts緩存,咱們在《ansible基礎-變量》6.1.2 facts緩存有詳細介紹,在這裏就再也不重複介紹了。

Strategy

strategy的做用範圍是一個play,經過設置不一樣參數,控制一個play內全部任務的執行策略。

設置方法爲更改ansible.cfg裏的strategy參數,默認值爲linear,可選參數爲free;另一種方式是在playbook內定義該策略,格式爲:

- hosts: all strategy: free tasks: ...

參數含義:

  • linear策略即線性執行策略,線性執行策略指主機組內全部主機完成一個任務後才繼續下一個任務的執行,在執行一個任務時,若是某個主機先執行完則會等待其餘主機執行結束。說直白點就是第一個任務在指定的主機都執行完,再進行第二個任務的執行,第二個任務在指定的主機都執行完後,再進行第三個任務的執行…… 以此類推。
  • free策略即自由策略,即在一個play執行完以前,每一個主機都各顧各的儘量快的完成play裏的全部任務,而不會由於其餘主機沒執行完任務而等待,不受線性執行策略那樣的約束。因此這種策略的執行結果給人感受是無序的甚至是雜亂無章的,並且每次執行結果的task顯示順序極可能不同。

舉個🌰,展現下兩種策略的執行效果:

playbook要實現的是三臺主機debug出test_1,test_2,test_3三個字符串。當使用linear策略時,執行效果以下:

➜  lab-ansible ansible-playbook playbooks/test_trategy.yaml

PLAY [nodes] ***********************************************************

TASK [Gathering Facts] ***********************************************************
ok: [node3]
ok: [node2]
ok: [node1]

TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_1"
}
ok: [node3] => {
    "msg": "test_1"
}
ok: [node2] => {
    "msg": "test_1"
}

TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_2"
}
ok: [node3] => {
    "msg": "test_2"
}
ok: [node2] => {
    "msg": "test_2"
}

TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_3"
}
ok: [node3] => {
    "msg": "test_3"
}
ok: [node2] => {
    "msg": "test_3"
}

PLAY RECAP ***********************************************************
node1                      : ok=4    changed=0    unreachable=0    failed=0
node2                      : ok=4    changed=0    unreachable=0    failed=0
node3                      : ok=4    changed=0    unreachable=0    failed=0
執行結果

當使用free策略時,執行效果以下:

PLAY [nodes] ***********************************************************

TASK [Gathering Facts] ***********************************************************
ok: [node3]
ok: [node2]
TASK [debug] ***********************************************************
ok: [node3] => {
    "msg": "test_1"
}
ok: [node2] => {
    "msg": "test_1"
}
TASK [Gathering Facts] ***********************************************************
ok: [node1]

TASK [debug] ***********************************************************
ok: [node3] => {
    "msg": "test_2"
}
ok: [node2] => {
    "msg": "test_2"
}
TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_1"
}
TASK [debug] ***********************************************************
ok: [node3] => {
    "msg": "test_3"
}
ok: [node2] => {
    "msg": "test_3"
}

TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_2"
}

TASK [debug] ***********************************************************
ok: [node1] => {
    "msg": "test_3"
}

PLAY RECAP ***********************************************************
node1                      : ok=4    changed=0    unreachable=0    failed=0
node2                      : ok=4    changed=0    unreachable=0    failed=0
node3                      : ok=4    changed=0    unreachable=0    failed=0
執行結果

從上面兩個個執行結果很明顯的能看出區別,linear策略是遵循第一個任務、第二個任務、第三個任務……這樣順序執行下去的,而free策略則是無序的,甚至Gathering Facts任務也可能在debug任務以後執行。

Forks

forks用來設置同一時刻與目的主機鏈接數,也能夠理解爲主機並行數,默認值比較保守爲5。在生產中,多數狀況下咱們會更改這個參數。若是控制節點的CPU和網絡性可以用,設置幾十上百個也是能夠的。

在ansible.cfg設置forks的全局默認值:

# ansible.cfg [defaults] forks = 15

命令行設置forks的數量,即在執行playbook時,經過「--forks」或「-f」指定: 

lab-ansible ansible-playbook playbooks/test_forks.yaml --fork 10

Serial

serial用於控制一個play內的主機並行數,這個並行數不能超過forks,超事後則serial不會生效。

定義方法以下:

--
- hosts: nodes serial: 2 tasks:

本質上,serial做用範圍是一個play,受限於forks,但比forks控制的更加細節。假如咱們的forks設置爲100,可是想讓某個play裏的全部任務並行數爲50的執行,此時咱們應該想到serial這個調優方法。

Async and poll

同步阻塞模式和異步模式

  1. 同步阻塞模式指在playbook執行時,控制端和被控制端會一直保持鏈接狀態,逐個任務的執行,直到該playbook執行完畢,這種模式稱爲同步阻塞模式,也是absible的默認執行模式。
  2. 異步模式指ansible將一次性運行全部的任務,並將全部的任務丟到後臺執行,每一個任務有一個job_id,ansible會根據這個job_id每隔一段時間輪訓檢測該任務的執行狀況,直到檢測到任務執行結束。這種模式稱爲異步模式。

Async and pool

前面章節咱們所說的Strategy、Forks、Serial都是ansible同步阻塞模式下的優化方法,其中,strategy是經過控制任務執行策略進行優化,forks和serial是經過控制並行數進行優化。

針對某些特殊任務,尤爲是可能被鎖住或超時的任務,咱們能夠採用ansible異步模式來提升執行效率。

async和poll分別用來指定異步模式下任務的最大運行時間和檢測間隔時間,poll的缺省值爲10。

示例以下:

---
- hosts: all remote_user: root tasks: - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec command: /bin/sleep 15 async: 45 poll: 5

該示例中sleep命令採用異步的方式執行,ansible會等待該任務最長45秒,每隔5秒鐘檢測一次任務的執行結果。

特殊狀況下,咱們能夠將poll的值設置爲0,這表明ansible將任務放到後臺後,不會再管這個任務的執行狀態,任其自生自滅。

這裏舉一個利用異步重啓服務器的例子,因篇幅緣由,僅給你們展現部署代碼,就不貼執行結果了,若是您感興趣,能夠親自實踐下:

---
- hosts: node1
  gather_facts: no
  tasks:
    - shell:
        cmd: grub2-set-default 0
      notify:
        - reboot
        - wait for reboot
        - wait for ssh start

  handlers:
    - name: reboot
      shell:
        cmd: shutdown -r now "Reboot triggered by ansible"
      async: 1
      poll: 0
      ignore_errors: True

    - name: wait for reboot
      wait_for_connection:
        timeout: 300

    - name: wait for ssh start
      wait_for:
        host: node1
        state: started
        delay: 10
        port: 22
        timeout: 30
reboot服務器示例

參考連接

  • https://docs.ansible.com/ansible/2.4/playbooks_acceleration.html
  • https://docs.ansible.com/ansible/2.4/intro_configuration.html#pipelining
  • https://docs.ansible.com/ansible/2.4/intro_configuration.html#control-path
  • https://docs.ansible.com/ansible/latest/modules/setup_module.html
  • https://docs.ansible.com/ansible/2.5/user_guide/playbooks_strategies.html
  • https://www.ansible.com/blog/ansible-performance-tuning
  • https://www.cnblogs.com/f-ck-need-u/p/7580170.html
  • https://docs.ansible.com/ansible/2.5/user_guide/playbooks_async.html

 

歡迎你們關注個人公衆號:

相關文章
相關標籤/搜索