1. 程式人生 > 實用技巧 >105)ansible優化

105)ansible優化

1. 連線優化[openssh]

  • 開啟SSH長連線

ssh版本:> 5.6

  • 關閉ansible的SSH金鑰檢測

    ansible預設是以ssh來實現遠端推送執行的,是基於ssh祕鑰檢測,會檢測遠端主機的公鑰,並記錄在本地中known_host檔案中,下次訪問主機時,會核對公鑰,如果公鑰不同,openssh會發出警告,如果相同,會提示輸入密碼

SSH對主機的public_key的檢查等級是根據StrictHostKeyChecking變數來設定的,StrictHostKeyChecking檢查級別包括:no(不檢查)、ask(詢問)、yes(每次都檢查)、False(關閉檢查)。

vim  /etc/ansible/ansible.cfg 
host_key_checking = False    #關閉StrictHostKeyChecking檢查
  • openssh UseDNS

使用OpenSSH服務時,預設伺服器端配置檔案UseDNS=YES狀態,該選項會導致伺服器根據客戶端的IP地址進行DNS PTR反向解析,得到客戶端的主機名,然後根據獲取到的主機名進行DNS正向A記錄查詢,並驗證該IP是否與原始IP一致。關閉DNS解析程式碼如下:

sed  -i  '/^GSSAPI/s/yes/no/g;/UseDNS/d;/Protocol/aUseDNS no' /etc/ssh/sshd_config
  • SSH pipelining加速Ansible

開啟「pipelining」特性實際上是通過減少ssh連線次數,從而縮短ansible執行時間

SSH pipelining是一個加速 Ansible 執行速度的簡單方法,SSH pipelining 預設是關閉的,關閉是為了相容不同的 sudo 配置,主要是requiretty 選項。

如果不使用Sudo建議開啟該選項,開啟此選項可以減少Ansible 執行沒有檔案傳輸時,SSH在被控機器上執行任務的連線數。使用Sudo操作的時候, 必須在所有被管理的主機上將配置檔案/etc/sudoers中requiretty選項禁用。

sed    -i    '/^pipelining/s/False/True/g'    /etc/ansible/ansible.cf

2- Ansible Facts快取優化

  • 關閉
gather_facts: nogather_facts: no
  • 儲存在檔案或者redis中[只在第一次連線時收集]

Gather subset

給play單獨新增一個setup模組,並通過gather_subset引數嚴格控制facts的收集種類,這樣既拿到了我們需要的fact變數又提高了ansible的執行效率,gather_subset引數的預設值為all。

  • yaml:
- name: Collect only facts returned by facter
  setup:
    gather_subset:
      - '!all'
      - '!any'
      - 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子集,說明只收集該子集資訊

3- 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執行報錯。但在新版本中預設值的主機名部分被替換為主機名的雜湊值,這很大程度上避免了該問題的發生。

4- Strategy

strategy的作用範圍是一個play,通過設定不同引數,控制一個play內所有任務的執行策略。

設定方法為更改ansible.cfg裡的strategy引數,預設值為linear,可選引數為free;另外一種方式是在playbook內定義該策略,格式為:

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

引數含義:

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

5- Forks

forks用來設定同一時刻與目的主機連線數,也可以理解為主機並行數,預設值比較保守為5。在生產中,多數情況下我們會更改這個引數。如果控制節點的CPU和網路效能夠用,設定幾十上百個也是可以的。

  • 配置檔案:
ansible.cfg
[defaults]
forks  = 15
  • 命令列:

通過「--forks」或「-f」指定

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

ansible的同步模式與非同步模式執行區別:

同步模式: 如果節點數太多,ansible無法一次在所有遠端節點上執行任務,那麼將先在一部分節點上執行一個任務(每一批節點的數量取決於fork程序數量,預設為5個,可設定),直到這一批所有節點上該任務完全執行完畢才會接入下一個批節點,直到所有節點將該任務都執行完畢,然後重新回到第一批節點開始執行第二個任務。依次類推,直到所有節點執行完所有任務,ansible端才會釋放shell。這是預設的同步模式,也就是說在未執行完畢的時候,ansible是佔用當前shell的,任務執行完畢後,釋放shell了才可以輸入其他命令做其他動作。

非同步模式:假如fork控制的併發程序數為5,遠端控制節點為24個,則ansible一開始會將5個節點的任務扔在後臺,並每隔一段時間去檢查這些節點的任務完成情況,當某節點完成不會立即返回,而是繼續等待直到5個程序都空閒了,才會將這5個節點的結果返回給ansible端,ansible會繼續將下一批5個節點的任務扔在後臺並每隔一段時間進行檢查,依次類推,直到完成所有任務。

在非同步模式下,如果設定的檢查時間間隔為0,在將每一批節點的任務丟到後臺後都會立即返回ansible,並立即將下一批節點的任務丟到後臺,直到所有任務都丟到後臺完成後,會返回ansible端,ansible會立即釋放佔用的shell。也就是說,此時ansible是不會管各個節點的任務執行情況的,不管執行成功還是失敗。因此,在輪訓檢查時間內,ansible仍然正在執行(儘管某批任務已經被放到後臺執行了),當前shell程序仍被佔用處於睡眠狀態,只有指定的檢查時間間隔為0,才會儘快將所有任務放到後臺並釋放shell。

6- Serial

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

  • yaml
--
- hosts: nodes
  serial: 2
  tasks:

serial作用範圍是一個play,受限於forks,但比forks控制的更加細節。

7- 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。

  • yaml
---
- 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將任務放到後臺後,不會再管這個任務的執行狀態,任其自生自滅。

ansible併發和非同步:

ansible預設只會建立5個程序,所以一次任務只能同時控制5臺機器執行。那如果你有大量的機器需要控制,或者你希望減少程序數,那你可以採取非同步執行。
使用async和poll這兩個關鍵字便可以並行執行一個任務。 async這個關鍵字觸發ansible並行運作任務,而async的值是ansible等待執行這個任務的最大超時值(如果執行超時任務會強制中斷導致失敗),而poll就是ansible檢查這個任務是否完成的頻率時間。

8- ControlPersist

ControlPersist 特性需要高版本的 SSH 才支援,CentOS 6 預設是不支援的,如果需要使用,需要自行升級 openssh。ControlPersist 即持久化 socket,一次驗證,多次通訊。並且只需要修改 ssh 客戶端就行,也就是 Ansible 機器即可。

ControlPersist 設定

cat ~/.ssh/config 
Host * 
Compression yes 
ServerAliveInterval 60 
ServerAliveCountMax 5 
ControlMaster auto 
ControlPath <a href="mailto:~/.ssh/sockets/%25r@%25h-%25p"><code>~/.ssh/sockets/%r@%h-%p</code></a>
ControlPersist 4h

9- 任務

  • 目錄結構

如果只是一個簡單的獨立任務,使用playbook檔案即可,方便我們在其他地方引用. 複雜建議採用role形式管理.

  • 定義多環境

通過Inventory 方式去區分多環境下的主機或者主機組資訊. 生成多個主機檔案.
不同環境需要呼叫不同的playbook 或者task ,可以通過when 方式去判斷當前的主機資訊存在哪個環境中,然後進行引用.

  • 檢測

ansible-playbook 命令的–syntax-check 引數即可

  • 灰度釋出

挑選一臺機器進行測試,只有進行測試之後我們才知道整個配置流程是否達到我們想要結果.
進行預執行時,我們只需要把一個或者多個task 使用delegate_to引數指定到一臺裝置上進行測試. 如果測試通過後,再進行接下來的工作.

  • 統一管理

納入git/svn倉庫管理