Ansible 多機自動化工具 初學筆記

Kin_Zhang發表於2023-02-23

此文件僅張聰明同學個人筆記;新負責KTH-RPL Cluster GPU的漫漫學習長路

English Docs:

  1. official https://docs.ansible.com/ansible/latest/index.html

中文相關文件:

  1. https://ansible.leops.cn/basic/Quickstart/
  2. https://blog.csdn.net/xinshuzhan/article/details/115915698 ← 這篇博文寫的更為仔細

請注意下面有引用框的 均為這些參考文件中的話語,相關圖片也由他們而來,不再在文中單獨說明


測試學習階段 請不要執行危險的指令,比如 rm -rf * 當然你沒有sudo的話 刪的只是自己使用者下的 問題不大,切記管理人員 不要執行 自己直接copy過來看都沒看的script 或者 指令! 建議以下學習時,就列印列印資訊

簡要介紹

Ansible是一款為類Unix系統開發的自由開源的配置和自動化工具
它用Python寫成,類似於saltstack和Puppet,但是有一個不同和優點是我們不需要在節點中安裝任何客戶端。 它使用SSH來和節點進行通訊。
Ansible基於 Python paramiko 開發,分散式,無需客戶端,輕量級,配置語法使用 YMAL 及 Jinja2模板語言,更強的遠端命令執行操作。

主要呢 可以透過這幅圖看出來,也就是東西是裝在你自己的主機上的:

  1. 透過 主機清單 和playbooks進行配置 當然也可以單獨就執行一段指令 後續的實踐部分再介紹
  2. 主機【也就是自己的電腦】透過SSH 進行其他機器的連線
  3. 然後就可以 快樂一個ansible 所有ssh 機器都執行
Ansible 多機自動化工具 初學筆記

所以ansible 是安裝在自己電腦上的 [沒錯 我一開始以為每個node server都得裝 hhhh 理解沒到位

安裝

sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

當然因為本身是Python 程式碼 可以透過pip install或者是conda install進行library的安裝,建議感興趣的可以看 官方文件的 這個部分

安裝完後 第一件事! 所有的工具類 安裝完後都可以試著執行 —help 去快速瞭解指令

ansible --help
Ansible 多機自動化工具 初學筆記

常用指令開頭為 擷取至 官方文件 建議都再次 --help

ansible
ansible-inventory
ansible-playbook
ansible-config
ansible-console
ansible-doc
ansible-galaxy
ansible-pull
ansible-vault

初步嘗試

根據上面簡要介紹中內容,我們首先確定一下 ansible 知道的host 應該是什麼? 才能去連線到各個節點進行指令執行

設定 host

根據官方文件 我們得知 應該要寫一個 /etc/ansible/hosts 內容大概長這樣

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com
  • 然後我們回到自己電腦上可以看到 有一個這樣的檔案 開啟雖然都註釋掉了 但也能理解

    #
    #   - Comments begin with the '#' character
    #   - Blank lines are ignored
    #   - Groups of hosts are delimited by [header] elements
    #   - You can enter hostnames or ip addresses
    #   - A hostname/ip can be a member of multiple groups
    
    # Ex 1: Ungrouped hosts, specify before any group headers:
    
    ## green.example.com
    ## blue.example.com
    ## 192.168.100.1
    ## 192.168.100.10
    
    # Ex 2: A collection of hosts belonging to the 'webservers' group:
    
    ## [webservers]
    ## alpha.example.org
    ## beta.example.org
    ## 192.168.1.100
    ## 192.168.1.110
    
    # If you have multiple hosts following a pattern, you can specify
    # them like this:
    
    ## www[001:006].example.com
    
    # Ex 3: A collection of database servers in the 'dbservers' group:
    
    ## [dbservers]
    ##
    ## db01.intranet.mydomain.net
    ## db02.intranet.mydomain.net
    ## 10.25.1.56
    ## 10.25.1.57
    
    # Here's another example of host ranges, this time there are no
    # leading 0s:
    
    ## db-[99:101]-node.example.com
    

對於伺服器的話 因為之前我們有寫在 ~/.ssh/config 大概一個config長這樣:

Host Server3
    HostName xxx # ip or hostnames
    IdentityFile ~/.ssh/id_rsa
    Port xxx # 可連通的Port節點
    User xxx # node節點上登入的使用者名稱

Host Server10
    HostName xxx # ip or hostnames
    IdentityFile ~/.ssh/id_rsa
    Port xxx # 可連通的Port節點
    User xxx # node節點上登入的使用者名稱
  • 如果是給是我之前那樣的設定的話 我會把 ``/etc/ansible/hosts` 寫成這樣:

    [local]
    localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3
    
    [compute]
    Server3
    Server5
    Server8
    Server4
    Server12
    Server13
    Server11
    
    [cluster:children]
    compute
    
    [cluster:vars]
    ansible_python_interpreter=/usr/bin/python3
    

列印 graph

然後 設定完成後,儲存退出,在終端輸入:

ansible-inventory --graph --vars

比如我的設定完 伺服器的所有節點:

Ansible 多機自動化工具 初學筆記

執行 command

首先我們測試幾個點,然後再仔細解釋一下 即更進階的版本

小試一下 連通這些節點 :

ansible cluster -m ping

可以看到 server3 不能被連通 其他的都可

Ansible 多機自動化工具 初學筆記

那麼我們再試一下 讀取所有伺服器上的的gpu 狀態

ansible cluster -m command -a "nvidia-smi"
Ansible 多機自動化工具 初學筆記

好了,是時候要解釋一下了 【再次提醒 --help 是個好東西】:

  • ansible 使用的工具名字

  • cluster 我對host裡面的命名,比如上面舉例 ansible-inventory --graph --vars 這個執行完後 能看到 graph是從cluster 這個名字開啟的,所以 也就是在cluster組的所有節點上都執行

  • -m command -m 是 ansible的引數,從第一次安裝完 我們列印了 --help 裡面有提到這個

    • m MODULE_NAME, --module-name MODULE_NAME
      Name of the action to execute (default=command)

    command 的意思就是 我自己會給指令讓他執行

    -m ping 因為ping是ansible裡面內建的module名字 所以 -m 帶上 ping就是測試這個組的所有節點是否連通

  • -a "nvidia-smi" 一般 -a 跟著的是 -m command 或者 是沒有(因為預設是command) 因為一般只有自己輸入特定指令需要給這個引數

    • a MODULE_ARGS, --args MODULE_ARGS
      The action's options in space separated k=v format: -a 'opt1=val1 opt2=val2'

ok 隨堂測試 這條指令幹什麼 【可以自己試試】:

ansible cluster -m command -a "nvidia-smi --query-gpu=index,gpu_name,utilization.gpu,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits"

實際上到這裡 普通使用者用來 看看 server的狀態 就差不多了,進階呢 就是把command -a 後面的 搞成一個yaml檔案,這樣就不用輸入一系列長的指令了

進階嘗試

主要 適用人員 就是對node節點要幹些什麼,不是單純的列印資訊了;比如統一升級某個包、統一新增一個使用者、統一解除安裝什麼東西 等等等

首先介紹一下ansible 的模組

  • command:也就是上面我們介紹過了的 常見命令都可以使用,但是執行不是透過shell的 所以 < > | and & 等操作 nope

    ansible cluster -m command -a "nvidia-smi"
    
  • shell :預設/bin/sh執行,所以終端輸入的命令都可以使用

    可以看到 -m 後面跟的是shell! 然後我們還接了一個 &&

    ansible cluster -m shell -a "nvidia-smi && ls | grep config"
    

    當然看到這裡,確實shell 是可以把自己的scripts 先 cp 過去,然後再執行,但是呢 這樣需要呼叫兩次ansible 第一次 cp 第二次 run

    # copy 過去
    ansible cluster -m copy -a "src=/home/kin/echo_test.sh dest=/home/kin owner=kin group=kin mode=0777"
    # 然後執行
    ansible cluster -m shell -a "./home/kin/echo_test.sh"
    

    而下面介紹的scripts 和 playbook 就不需要了

  • scripts:在本地寫一個指令碼,在遠端伺服器上執行

scripts執行

首先這個 我們需要寫好一個指令碼,舉個例子

寫個echo_test.sh 就列印一下顯示卡和 echo Hello

#!/bin/bash
#nvidia-smi
date
hostname
echo "Hello Test ansible Here!"

然後執行:

ansible cluster -m script -a "/home/kin/echo_test.sh"
Ansible 多機自動化工具 初學筆記

playbook 介紹

終於到大頭了 看到這裡還記得第一幅圖的東西嗎?所有的部分基本快速過了一遍 還差一個playbook! 關於ansible自己文件的介紹 在這裡

  • Playbooks are automation blueprints, in YAML format 並使用它進行部署和配置節點等

那麼為什麼上面的script不夠用呢? 可以停下想想


因為 在你執行上面scripts 的時候 沒法說 node B執行這段,node B執行第二段;或者是不同的使用者屬性不同操作等等 【官方的答案還有幾個點 感興趣可以點上面的link;這麼一看 playbook這個名字取得真不錯 按照劇本 演】

好 進入正題,先給一個參考部落格裡的 playbooks 樣子:

---
- name: Update web servers
  hosts: webservers
  remote_user: root

  tasks:
  - name: Ensure apache is at the latest version
    ansible.builtin.yum:
      name: httpd
      state: latest
  - name: Write the apache config file
    ansible.builtin.template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf

解釋一下:

  • name task description 任務描述資訊
  • hosts 要執行這個task的 節點組,比如我們之前一直的命名是 cluster
  • ansible.builti 這裡都是使用了ansible 內建的模組功能
  • module_name module_args #需要使用的模組名字: 模組引數
  • shell 使用shell模組
---
- hosts: mongo_servers
  tasks:
  - include: roles/mongod/tasks/shards.yml

其中include 的playbook 長這樣:

---
#This Playbooks adds shards to the mongos servers once everythig is added

- name: Create the file to initialize the mongod Shard
  template: src=shard_init.j2 dest=/tmp/shard_init_{{ inventory_hostname }}.js
  delegate_to: '{{ item }}'
  with_items: groups.mongos_servers

- name: Add the shard to the mongos
  shell: /usr/bin/mongo localhost:{{ mongos_port }}/admin -u admin -p {{ mongo_admin_pass }} /tmp/shard_init_{{ inventory_hostname }}.js
  delegate_to: '{{ item }}'
  with_items: groups.mongos_servers

這是官方的一個示例

是不是大概看懂了?【反正我第一次是沒看懂 一堆admin 也不敢執行 所以還是 祖傳!檢查disk space 是不是剩餘ok

- name: Disk space in local storage
  hosts: cluster
  tasks:
  - set_fact:
      mount: "{{ ansible_mounts | selectattr('mount', 'equalto', '/')  | first }}"
  - set_fact:
      size_total_gb: "{{ (mount.size_total / (1024*1024*1024)) }}"
      size_used_gb: "{{ ((mount.size_total - mount.size_available) / (1024*1024*1024)) }}"
      size_used_percent: "{{ 100 * (mount.size_total - mount.size_available) / mount.size_total }}"
  - set_fact:
      size_ok: "{{ ( (mount.size_total - mount.size_available) / mount.size_total ) < 0.80 }}"
      size_msg: "Local storage: {{ size_used_gb|float|round(1) }}/{{ size_total_gb|float|round(1) }}GB ({{ size_used_percent|float|round(1) }}%)"
  - assert:
      that: size_ok
      quiet: true
      fail_msg: "{{size_msg}}"

vim 完了 可以試一下check,這個check mode只是一個模擬 不會輸入任務的output,但是是一個非常適合驗證這個playbook在一個節點上 執行的一些配置管理操作【當然 我們上面只是判斷一下 硬碟還有儲存空間

ansible-playbook echo_local.yaml --check

如果只想在一個node上執行可以 加 --limit node_name 比如:

ansible-playbook echo_local.yaml --limit Server5

實際的執行指令很簡單,直接跟yaml即可:

Ansible 多機自動化工具 初學筆記

總結

意猶未盡?ansible 自己官方給了很多很多 examples,歡迎去探索:https://github.com/ansible/ansible-examples

然後這個 文件 真的是一個特別特別特別簡單的入門 瞭解 嘗試,也是張聰明同學第一次學的時候 邊學邊寫的… 有錯誤很正常 或者是隨時間 萬一指令不對了 過時了 大家都看官方文件為主哈


贈人點贊 手有餘香 ?;正向回饋 才能更好開放記錄 hhh

相關文章