Ansible 基礎入門

谱次·發表於2024-03-08

2)Ansible 介紹

Ansible 基本概念

Ansible 是一種自動化運維工具,基於 Paramiko 開發的,並且基於模組化工作,Ansible 是一種整合 IT 系統的配置管理、應用部署、執行特定任務的開源平臺,它是基於 Python 語言,由 Paramiko 和 PyYAML 兩個關鍵模組構建。集合了眾多運維工具的優點,實現了批次系統配置、批次程式部署、批次執行命令等功能。

Ansible 是基於模組工作的,本身沒有批次部署的能力,真正具有批次部署的是 Ansible 所執行的模組,Ansible 只是提供一種框架。Ansible 不需要在遠端主機上安裝 Client、Agents,因為它們是基於 SSH 來和遠端主機通訊的。

Ansible 優勢

  • Ansible 不需要單獨安裝客戶端,也不需要啟動任何服務
  • Ansible 是 Python 中的一套完整的自動化執行任務模組
  • Ansible PlayBook,採用 yaml 配置,對於自動化任務執行一目瞭然
  • Ansible 模組較多,對於自動化的場景支援較豐富

2.1)Ansible 發展史

官網:https://www.ansible.com/
作者: Michael DeHaan( Cobbler 與 Func 作者)

Ansible 的名稱來自科幻小說《 安德的遊戲 》中跨越時空的即時通訊工具,使用它可以在相距數光年的距離,遠端實時控制前線的艦隊戰鬥。
2012-03-09,釋出 0.0.1 版
2015-10-17,Red Hat 宣佈 1.5 億美元收購

官方文件:https://docs.ansible.com/

2.2)Ansible 功能

Ansible 功能介紹

  • 批次執行遠端命令,可以對遠端的多臺主機同時進行命令的執行
  • 批次安裝和配置軟體服務,可以對遠端的多臺主機進行自動化的方式配置和管理各種服務
  • 編排高階的企業級複雜的 IT 架構任務,Ansible 的 PlayBook 和 Role 可以輕鬆實現大型的 IT 複雜架構
  • 提供自動化運維工具的 開發 API,有很多運維工具,如 JumpServer 就是基於 Ansible 實現自動化管理功能

2.3)Ansible 特性

Ansible 特性

  • 模組化: 呼叫特定的模組完成特定任務,支援自定義模組,可使用任何程式語言寫模組
  • Paramiko( Python 對 SSH 的實現),PyYAML,Jinja2(模板語言)三個關鍵模組
  • 基於 Python 語言實現
  • 部署簡單,基於 Python 和 SSH (預設已安裝),agentless,無需代理不依賴 PKI( 無需 SSL )
  • 安全, 基於 OpenSSH
  • 冪等性: 一個任務執行 1 遍和執行 n 遍效果一樣,不因重複執行帶來意外情況,此特性非絕對。( Shell 指令碼想實現冪等性很困難 )
  • 支援 PlayBook 編排任務,YAML 格式,編排任務,支援豐富的資料結構( 存在 分支,迴圈,判斷,變數 等功能 )
  • 較強大的 多層解決方案 role( Role 角色管理 )

2.4)Ansible 架構

Ansible 是 基於模組工作 的,本身沒有批次部署的能力。真正具有批次部署的是 Ansible 所執行的模組,Ansible 只是提供一種框架。

上圖為 Ansible 的基本架構,從上圖可以瞭解到其由以下部分組成:

  • 核心: Ansible
  • 核心模組(Core Modules):這些都是 Ansible 自帶的模組
  • 擴充套件模組(Custom Modules):如果核心模組不足以完成某種功能,可以新增擴充套件模組
  • 外掛(Plugins):完成模組功能的補充
  • 劇本(Playbooks):Ansible 的任務配置檔案,將多個任務定義在劇本中,由 Ansible 完成執行
  • 連線外掛(Connectior Plugins):Ansible 基於連線外掛連線到各個主機上,雖然 Ansible 是使用 SSH 連線到各個主機的,但是它還支援其他的連線方法,所以需要有連線外掛
  • 主機清單(Host Inventory):定義 Ansible 管理的主機

Ansible 工作邏輯

  1. 使用者請求
  2. 尋找要執行的主機清單
  3. 透過模組連線遠端主機傳送要執行的命令
  4. 被控節點執行命令

2.4.1)Ansible 組成

組合 INVENTORY、API、MODULES、PLUGINS 的綠框
為 Ansible 命令工具,其為 核心執行工具
INVENTORY:Ansible 管理主機的清單 /etc/anaible/hosts ( 主機清單 )
MODULES:Ansible 執行命令的 功能模組,多數為內建核心模組,也可自定義( 功能模組 )
PLUGINS:模組功能的補充,如 連線型別外掛、迴圈外掛、變數外掛、過濾外掛等,該功能不常用( 擴充套件外掛 )
API:**供第三方程式呼叫 **的應用程式程式設計介面( 開發介面 )

2.4.2)Ansible 命令執行來源

USER 使用者,即 SYSTEM ADMINISTRATOR
PLAYBOOKS:任務劇本(任務集),編排定義 Ansible 任務集的配置檔案,由 Ansible 順序依次執行,通常是 JSON 格式的 YML 檔案
CMDB(配置管理資料庫) API 呼叫
PUBLIC/PRIVATE CLOUD( 共有云\私有云 )API 呼叫
USER -> Ansible Playbook -> Ansibile

2.4.3)注意事項

執行 Ansible 的主機 一般稱為:管理端,主控端,中控,Master堡壘機
主控端 Python 版本需要 2.6 或以上
被控端 Python 版本小於 **2.4 **時,需要安裝 Python-simplejson
被控端 如開啟 SELinux 需要安裝 libselinux-python
Windows 不能做為主控端( 可以做被控端 )

3)Ansible 入門

3.1)Ansible 安裝

官方文件:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

Ansible 的安裝方法有多種

  1. Yum 源安裝
  2. 編譯安裝
  3. Git 方式
  4. PIP 安裝

3.1.1)Yum 源安裝

注意:Ansible 軟體包預設不在 Yum 倉庫中,需配置 EPEL 源安裝。
https://blog.csdn.net/weixin_74962223/article/details/134573366

// CentOS 的 EPEL 源的 rpm 包安裝
[root@centos7 ~] yum repolist | grep epel
[root@centos7 ~] yum install ansible -y

// Ubuntu 安裝
[root@ubuntu ~] apt install ansible -y

範例:檢視 Ansible 版本

[root@centos7 ~] yum info ansible
[root@centos8 ~] yum info ansible

[root@ubuntu1804 ~] apt show ansible

範例:Ubuntu18.04 安裝最新版的 Ansible

[root@ubuntu1804 ~] apt update
[root@ubuntu1804 ~] apt install software-properties-common
[root@ubuntu1804 ~] apt-add-repository --yes --update ppa:ansible/ansible
[root@ubuntu1804 ~] apt install ansible
[root@ubuntu1804 ~] ansible --version

範例: CentOS 安裝 Ansible

# 需要存在 EPEL 源
# 參考: https://blog.csdn.net/weixin_74962223/article/details/134573366
[root@centos7 ~] yum repolist
[root@centos7 ~] yum install ansible -y
[root@centos7 ~] ansible --version

3.1.2)編譯安裝

yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto

wget https://releases.ansible.com/ansible/ansible-1.5.4.tar.gz

tar xf ansible-1.5.4.tar.gz
 && cd ansible-1.5.4

python setup.py build
python setup.py install

mkdir /etc/ansible
cp -r examples/* /etc/ansible

3.1.3)Git 方式

git clone git://github.com/ansible/ansible.git --recursive

cd ./ansible

source ./hacking/env-setup

3.1.4)PIP 安裝

# PIP 是安裝 Python 包的管理器, 類似 Yum
[root@centos7 ~] yum install python-pip 
[root@centos7 ~] pip install --upgrade pip
[root@centos7 ~] pip install ansible --upgrade
[root@centos7 ~] ansible --version

3.1.5)驗證安裝

[root@ansible ~] ansible --version
ansible 2.9.27    # 版本資訊
  config file = /etc/ansible/ansible.cfg    # 配置檔案
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']      # 模組路徑
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible    # ansible 可執行程式 ( 基於 Python 編寫 )
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

3.2)Ansible 相關檔案

3.2.1)配置檔案

Ansible 是一款自動化運維工具,它並不是一個服務。
因此,它沒有對應的 Service 檔案。Ansible 無需長期執行,只在需要使用時執行其二進位制檔案即可。( 安裝完成後,直接使用即可 )

/etc/ansible/ansible.cfg 主配置檔案
配置 ansible 工作特性,也可以在專案的目錄中建立此檔案,
當前目錄下如果也有 ansible.cfg,則此檔案優先生效,建議每個專案目錄下,建立獨有的 ansible.cfg 檔案
/etc/ansible/hosts 主機清單
/etc/ansible/roles 存放角色的目錄

3.2.2)Ansible 主配置檔案

Ansible 的配置檔案 可以放在多個不同地方
優先順序從高到低順序如下

ansible will read ANSIBLE_CONFIG,ansible.cfg in the current working directory, .ansible.cfg in the home directory or /etc/ansible/ansible.cfg, whichever it finds first

a. $ANSIBLE_CONFIG 變數
b. 專案目錄下的配置檔案
c. 當前使用者家目錄下的配置檔案
d. /etc/ansible/ansible.cfg (預設)
# 驗證 Ansible 預設呼叫的主配置檔案路徑
ansible --version    # 當前目錄的 ansible 配置檔案呼叫優先順序高於 /etc/ansible/xxx

Ansible 的 預設配置檔案 /etc/ansible/ansible.cfg
其中大部分的配置內容無需進行修改( 下圖:RHCE 考試預設使用的 ansible.cfg )

[defaults]
# inventory     = /etc/ansible/hosts    // 主機列表配置檔案
# library = /usr/share/my_modules       // 庫檔案存放目錄
# remote_tmp = $HOME/.ansible/tmp       // 臨時py命令檔案存放在遠端主機目錄
# local_tmp     = $HOME/.ansible/tmp    // 本機的臨時命令執行目錄
# forks         = 5                     // 預設併發數
# sudo_user     = root                  // 預設 sudo 使用者
# ask_sudo_pass = True                  // 每次執行 ansible 命令是否詢問 ssh 密碼
# ask_pass     = True   
# remote_port   = 22
# host_key_checking = False            // 檢查對應伺服器的 host_key, 建議取消此行註釋, 實現第一次連線自動信任目標主機
# log_path=/var/log/ansible.log        // 日誌檔案, 建議啟用
# module_name = command                // 預設模組, 可以修改為 shell 模組

[privilege_escalation]                 # 如果是普通使用者則需要配置提權
# become=True
# become_method=sudo
# become_user=root
# become_ask_pass=False

小技巧:當前目錄下的 Ansible 的配置檔案 優先生效

// 驗證 Ansible
[root@ansible ~] ansible --version

// 複製 Ansible 配置檔案至當前目錄
[root@ansible ~] cp /etc/ansible/ansible.cfg .

// 再次驗證
[root@ansible ~] ansible --version
ansible 2.9.17
    config file = /root/ansible.cfg        # 注意配置檔案路徑優先順序為當前目錄的 ansible.cfg 啦
    configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
    ansible python module location = /usr/lib/python3.6/site-packages/ansible
    executable location = /usr/bin/ansible
    python version = 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

3.2.3)inventory 主機清單

官方文件:https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html
Ansible 的主要功能 在於批次主機操作,為了便捷地使用其中的部分主機,可以在 Inventory 主機清單檔案中將其分組組織。

預設的 inventory file 為 /etc/ansible/hosts
當然也可以自定義,然後使用 -i 指定 inventory 檔案位置
注意: 生產環境建議在每個專案目錄下建立專案獨立的 hosts 檔案

主機清單 檔案格式
inventory 檔案遵循 INI 檔案風格
中括號中的字元為組名。可以將同一個主機同時歸併到多個不同的組中
此外,當如若目標主機使用了非預設的 SSH 埠,還可以在主機名稱之後使用冒號加埠號來標明
如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機

Inventory 引數說明

ansible_ssh_host                // 將要連線的遠端主機名. 與你想要設定的主機的別名不同的話, 可透過此變數設定.
ansible_ssh_port                // ssh 埠號. 如果不是預設的埠號, 透過此變數設定. 這種可以使用 ip:埠 192.168.1.100:2222
ansible_ssh_user                // 預設的 ssh 使用者名稱
ansible_ssh_pass                // ssh 密碼 ( 這種方式並不安全, 我們強烈建議使用 --ask-pass 或 SSH 金鑰 )
ansible_sudo_pass               // sudo 密碼 (這種方式並不安全, 我們強烈建議使用 --ask-sudo-pass )
ansible_sudo_exe (new in version 1.8)    // sudo 命令路徑 ( 適用於1.8及以上版本 )
ansible_connection                      // 與主機的連線型別. 比如: local, ssh 或者 paramiko. Ansible 1.2 以前預設使用 paramiko.1.2 以後預設使用 'smart', 'smart' 方式會根據是否支援 ControlPersist, 來判斷'ssh' 方式是否可行.
ansible_ssh_private_key_file            // ssh 使用的私鑰檔案. 適用於有多個金鑰, 而你不想使用 SSH 代理的情況.
ansible_shell_type                      // 目標系統的 shell 型別. 預設情況下, 命令的執行使用 'sh' 語法, 可設定為 'csh' 或 'fish'.
ansible_python_interpreter              // 目標主機的 python 路徑.

範例:列表形式

# vim /etc/ansible/hosts ( 預設主機清單檔案 )

ntp.magedu.com            # 1) 被管理主機名或 IP 地址
[webservers]              # 2) 將被管理主機分類
www1.magedu.com:2222      # 3) 目標主機使用了非預設的 SSH 埠
www2.magedu.com

[dbservers]
db1.magedu.com
db2.magedu.com
db3.magedu.com

或者
db[1:3].magedu.com        # 4) 可以使用列表的方式標識主機

範例:組巢狀

# vim /etc/ansible/hosts ( 預設主機清單檔案 )
[webservers]
www[1:100].example.com

[dbservers]
db-[a:f].example.com

[appservers]
10.0.0.[1:100]            # 列表形式: 10.0.0.1 - 10.0.0.100

// 定義 testsrvs 組包括兩個其它分組, "實現組巢狀"
[testsrvs:children] 
webservers
dbservers

範例:

本機地址: 10.0.0.8
# vim /etc/ansible/hosts ( 預設主機清單檔案 )
[local]
10.0.0.8 ansible_connection=local        # 指定本地連線, 無需 ssh 配置
# 注意: ansible_connection=ssh 時
# 配置檔案需要 StrictHostKeyChecking no
[websrvs]    # 也可以在被控主機行新增如下資訊 ( 不推薦, 會暴露主機安全 )
10.0.0.7 ansible_connection=ssh ansible_ssh_port=2222 ansible_ssh_user=wang ansible_ssh_password=magedu
10.0.0.6 ansible_connection=ssh ansible_ssh_user=root ansible_ssh_password=123456
# 執行 ansible 命令時顯示別名, 如 web01
[websrvs]
web01 ansible_ssh_host=10.0.0.101
web02 ansible_ssh_host=10.0.0.102

# 僅填寫主機 IP 地址也可以
[websrvs]
10.0.0.7
10.0.0.17

---   
[websrvs:vars]
ansible_ssh_password=magedu

some_host         ansible_ssh_port=2222    ansible_ssh_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

總結:

  • 主機支援主機名通配以及正規表示式,例如 web[1:3].magedu.com 代表三臺主機
  • 主機支援基於非標準的 SSH 埠,例如 web1.magedu.com:6666
  • 主機支援指定變數,可對個別主機的特殊配置,如登陸使用者,密碼
  • 主機組支援指定變數 [group_name:vars],同時支援巢狀組 [game:children]

3.3)Ansible 相關工具

  • /usr/bin/ansible 主程式,臨時命令執行工具
  • /usr/bin/ansible-doc 檢視配置文件,模組功能檢視工具,相當於 man
  • /usr/bin/ansible-playbook 定製自動化任務,編排劇本工具,相當於指令碼
  • /usr/bin/ansible-pull 遠端執行命令的工具
  • /usr/bin/ansible-vault 檔案加密工具( RHCE 有考該工具的使用 )
  • /usr/bin/ansible-console 基於 Console 介面與使用者互動的執行工具
  • /usr/bin/ansible-galaxy 下載/上傳優秀程式碼或 Roles 模組的官網平臺

利用 Ansible 實現管理的主要方式:

Ansible Ad-Hoc:即利用 ansible 命令,主要用於臨時命令使用場景
Ansible PlayBook:主要用於長期規劃好的,大型專案的場景,需要有前期的規劃過程

ansible 使用前 準備工作( 建議 )

Ansible 相關工具大多數是 透過 SSH 協議,實現對遠端主機的配置管理、應用部署、任務執行等功能

建議: 使用此工具前,先配置 ansible 主控端能基於金鑰認證的方式聯絡各個被管理節點

# 解決: 遠端被控端主機是, 自動回覆 yes 選項
# 第一次遠端連線某個主機時, 對方主機會預設詢問你是否 xxx, 輸入 yes 後, 預設會將遠端主機公鑰寫入本機 known_hosts
1) 修改 SSH 客戶端配置檔案
vim /etc/ssh/ssh_config
StrictHostKeyChecking no        // "自動回覆 yes 選項"

# 驗證 known_hosts 檔案
cat ~/.ssh/known_hosts

2) 或者, 修改 Ansible 配置檔案
vim /etc/ansible/ansible.cfg
host_key_checking = False        // "建議取消該行註釋"

// 基於密碼認證 ( "不常用" )
# 注意: websrvs 組的所有主機密碼 必須都是 redhat
# 如果 websrvs 組的某個主機密碼不是 redhat, 則無法連線成功
# 因此推薦使用 Key 認證 !!!
ansible websrvs -m ping -k
SSH password: redhat

範例: 利用 sshpass 批次實現基於 key 驗證指令碼 1

這個指令碼的作用是批次向指定的 IP 地址列表傳送 SSH 公鑰,並且在執行過程中忽略對遠端主機主機金鑰的嚴格檢查。

// 修改下面一行 ( 允許連線新的主機時,不需要手動確認金鑰 )
[root@centos8 ~] vim /etc/ssh/ssh_config
StrictHostKeyChecking no


[root@centos8 ~] vim push_ssh_key.sh
#!/bin/bash
IPLIST="
192.168.80.8
192.168.80.18
192.168.80.28"
rpm -q sshpass &> /dev/null || yum -y install sshpass  
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa  -P '' export SSHPASS=redhat    # 主機密碼
for IP in $IPLIST;do
    {
    sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $IP 
    }&
done 
wait

範例: 實現基於 key 驗證的指令碼 2

這段指令碼主要用於 在區域網中掃描活動的主機,然後透過 SSH 在這些主機之間傳遞 SSH 金鑰 以便後續相互訪問時不需要手動確認金鑰

注意: 該指令碼會實現主機之間相互免密認證

#!/bin/bash
PASS=redhat        # 主機密碼
# 設定網段最後的地址, 4-255 之間, 越小掃描越快
END=254

IP=`ip a s eth0 | awk -F'[ /]+' 'NR==3{print $3}'`    # 注意網路卡名稱
NET=${IP%.*}.

rm -f /root/.ssh/id_rsa
[ -e ./SCANIP.log ] && rm -f SCANIP.log
for((i=3;i<="$END";i++));do
ping -c 1 -w 1  ${NET}$i &> /dev/null  && echo "${NET}$i" >> SCANIP.log &
done
wait

ssh-keygen -P "" -f /root/.ssh/id_rsa
rpm -q sshpass || yum -y install sshpass
sshpass -p $PASS ssh-copy-id -o StrictHostKeyChecking=no $IP 

AliveIP=(`cat SCANIP.log`)
for n in ${AliveIP[*]};do
sshpass -p $PASS scp -o StrictHostKeyChecking=no -r /root/.ssh root@${n}:
done

# 把 .ssh/known_hosts 複製到所有主機, 使它們第一次互相訪問時不需要輸入回車
for n in ${AliveIP[*]};do
scp /root/.ssh/known_hosts ${n}:.ssh/
done

[root@centos7 ~] bash push_ssh_key.sh

推薦:使用該指令碼

< '批次部署多臺主機 基於 key 驗證指令碼' >
[root@ansible ~] vim push_ssh_key.sh
#!/bin/bash
HOSTS="
192.168.80.8
192.168.80.18
192.168.80.28                                                                            
"
PASS=redhat	# 注意: 密碼
[ -f /root/.ssh/id_rsa ] ||
ssh-keygen -P ""  -f /root/.ssh/id_rsa &> /dev/null
rpm -q sshpass &> /dev/null || yum -y install sshpass &> /dev/null
for i in $HOSTS;do
        {
            sshpass -p $PASS ssh-copy-id -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub $i &> /dev/null
        }&
done
wait

Ansible 命令 引數示範

# 列出 Ansible 可控制的所有主機
ansible all --list-hosts

# 列出 Ansible 可控制的 websrvs 組主機
ansible websrvs --list-hosts

// 演示: 萬用字元
ansible "*" -m ping 

ansible 192.168.80.* -m ping

ansible "192.168.80.8 192.168.80.18" -m ping
# Ping 模組: 測試與目標主機的連通性 ( 注意: 該 Ping 模組並沒有走 ICMP 協議 )
# -m 指定模組
# ping 模組
ansible all -m ping

3.3.1)ansible-doc

此工具用來 顯示模組的幫助,相當於 man

// 格式
ansible-doc [options] [module...]
-l, --list        // 列出可用模組
-s, --snippet     // 顯示指定模組的 playbook 片段

// 檢視幫助
[root@ansible ~] ansible-doc --help

image.png

範例:

// 列出所有模組
ansible-doc -l

// 檢視指定模組幫助用法 ( 詳細說明 )
ansible-doc ping

// 檢視指定模組幫助用法 ( 簡單說明 )
ansible-doc -s ping
ansible-doc -l | grep ^ping

// "重要"
// 檢視模組的 "使用案例"
ansible-doc ping | grep -A 100 EXA
ansible-doc file | grep -A 100 EXA

注意點

ansible-doc file
ansible-doc file | grep ^=


眼尖的小夥伴們可能會發現,上述操作其實可以透過 Linux 的 chown 命令來實現。但為什麼我們不直接使用 chown,而要藉助 Ansible 的 file 模組呢?這主要是因為 Shell 命令不具備冪等性,而 Ansible 的大部分模組都支援冪等性。這使得使用 Ansible 的 file 模組更加安全可靠。

範例: 檢視指定的外掛

[root@ansible ~] ansible-doc -t connection -l
[root@ansible ~] ansible-doc -t lookup -l

3.3.2)ansible Ad-Hoc

Ansible 的執行方式的主要工具就是 ansible( 專業名詞:Ad-Hoc

用於執行一次性的任務,臨時任務。

# 格式
ansible <host-pattern> [-m module_name] [-a args]

# 特殊案例 ( localhost: 代表本機)
ansible localhost -m ping

# 常規案例 ( websrvs: 主機清單中的分組資訊 )
ansible websrvs -m ping

**

選項說明:
ansible 'oldboy' -m command -a 'df -h' 含義如下圖
image.png

--version                 # 顯示版本
-m module                 # 指定模組,預設為 command
-v                        # 詳細過程 -vv -vvv 更詳細
--list-hosts              # 顯示主機列表, 可簡寫 --list
-C, --check               # 檢查, 並不執行
-T, --timeout=TIMEOUT     # 執行命令的超時時間, 預設 10S
-k, --ask-pass            # 提示輸入 ssh 連線密碼, 預設 Key 驗證 
-u, --user=REMOTE_USER    # 執行遠端執行的使用者, 預設 root
-b, --become              # 代替舊版的 sudo 切換
--become-user=USERNAME    # 指定 sudo 的 runas 使用者, 預設為 root
-K, --ask-become-pass     # 提示輸入 sudo 時的口令
-f FORKS, --forks FORKS   # 指定併發同時執行 ansible 任務的主機數

顯示詳細過程

ansible websrvs -m ping -v
ansible websrvs -m ping -vv
ansible websrvs -m ping -vvv

案例: 使用 普通使用者 身份 提升許可權 操作 遠端主機

# 先在被控制端 授權普通使用者 sudo 許可權
[root@centos8 ~] useradd wangj
[root@centos8 ~] echo 123456 | passwd --stdin wangj
[root@centos8 ~] vim /etc/sudoers
wangj    ALL=(ALL) NOPASSWD: ALL

# 以 wangj 普通使用者身份連線主機, 並利用 sudo 授權 root 許可權執行 whoami 命令
[root@ansible ~] ansible 192.168.80.8 -m shell -a 'whoami' -u wangj -k -b --become-user=root
SSH password:        // 輸入遠端主機 wangj 使用者 ssh 連線密碼
10.0.0.8 | CHANGED | rc=0 >>
root

Ansible 的 Host-pattern
用於匹配被控制的主機列表
All:表示所有 Inventory 中的所有主機

ansible all -m ping

*:萬用字元

ansible "*" -m ping
ansible 192.168.1.* -m ping

或 關係

# websrvs 或 dbsrvs 主機
ansible "websrvs:dbsrvs" -m ping

# 192.168.80.18 或 192.168.80.28 主機
ansible "192.168.80.18:192.168.80.28" -m ping

邏輯 與

// 在 websrvs 組並且在 dbsrvs 組中的主機
ansible "websrvs:&dbsrvs" -m ping

邏輯 非

// 在 websrvs 組, 但不在 dbsrvs 組中的主機
// 注意: 此處為單引號
ansible 'websrvs:!dbsrvs' -m ping

綜合 邏輯

ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' -m ping

正則 表示式

ansible "websrvs:dbsrvs" -m ping
ansible "~(web|db).*\.magedu\.com" -m ping

舉例:

// 重啟所有以 "kube" 開頭 或 "etcd" 開頭, 且不是 10.0.0.101 的主機
// 一般 10.0.0.101 為本機 IP 地址.
[root@kube-master1 ~] ansible 'kube*:etcd:!10.0.0.101' -a reboot && reboot

範例:

[root@centos8 ~] ansible all --list-hosts  
 hosts (3):
    10.0.0.6
    10.0.0.7
    10.0.0.8
    
[root@centos8 ~] ansible websrvs --list-hosts  
 hosts (3):
    10.0.0.6
    10.0.0.7
    10.0.0.8

[root@centos8 ~] ansible appsrvs --list-hosts  
 hosts (2):
    10.0.0.7
    10.0.0.8
    
// 使用 雙引號 或者 單引號 都可以                                       
[root@centos8 ~] ansible "appsrvs:dbsrvs" --list-hosts
[root@centos8 ~] ansible 'appsrvs:dbsrvs' --list-hosts  
 hosts (3):
    10.0.0.7
    10.0.0.8
    10.0.0.6
                 
[root@centos8 ~] ansible "dbsrvs" --list-hosts
[root@centos8 ~] ansible 'dbsrvs' --list-hosts  
 hosts (2):
    10.0.0.6
    10.0.0.7
    
[root@centos8 ~] ansible appsrvs --list-hosts  
 hosts (2):
    10.0.0.7
    10.0.0.8
    
[root@centos8 ~] ansible "appsrvs:dbsrvs" --list-hosts  
 hosts (3):
    10.0.0.7
    10.0.0.8
    10.0.0.6
    
[root@centos8 ~] ansible "appsrvs:&dbsrvs" --list-hosts  
 hosts (1):
    10.0.0.7

// 注意: 引用 ! 號時, "不要用雙引號"
[root@centos8 ~] ansible "appsrvs:!dbsrvs" --list-hosts  
-bash: !dbsrvs: event not found

// "而使用單引號"
[root@centos8 ~] ansible 'appsrvs:!dbsrvs' --list-hosts  
 hosts (1):
    10.0.0.8

範例:Ansible 執行 併發控制
GIF 錄製工具:https://www.cockos.com/licecap/

// 分別執行下面兩條命令觀察結果
[root@ansible ~] ansible all -a 'sleep 1' -f1    # 單臺單臺 執行任務
[root@ansible ~] ansible all -a 'sleep 1' -f10   # 一次性 執行任務

Ansible 命令執行過程
參考:https://www.liushuang6296.com/posts/a71433d/

  1. 載入預設配置檔案 /etc/ansible/ansible.cfg。
  2. 載入相應的模組,例如 command 模組。
  3. Ansible 生成臨時 Python 檔案,並傳輸到遠端伺服器的 $HOME/.ansible/tmp/ansible-tmp-數字/XXX.PY。
  4. 為檔案新增執行許可權。
  5. 執行檔案並返回結果。
  6. 刪除臨時檔案並退出。

// 演示
[root@ansible ~] ansible all -m shell -a 'sleep 100'

// 驗證 ( 臨時 Python 檔案 )
[root@centos8 ~] ll ~/.ansible/tmp/*

Ansible 的執行狀態:

[root@centos8 ~] grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg
[colors]
# highlight = white
# verbose = blue
# warn = bright purple
# error = red
# debug = dark gray
# deprecate = purple
# skip = cyan
# unreachable = red
# ok = green
# changed = yellow
# diff_add = green
# diff_remove = red
# diff_lines = cyan

Ansible 執行返回 -> 顏色資訊說明:
綠色: 成功執行,沒有發生狀態改變
黃色: 成功執行,有發生狀態改變
紅色: 執行失敗

Ansible 使用範例

# 以 wang 使用者執行 ping 存活檢測
ansible all -m ping -u wang -k

# 以 wang sudo 至 root 執行 ping 存活檢測
ansible all -m ping -u wang -k -b

# 以 wang sudo 至 mage 使用者執行 ping 存活檢測
ansible all -m ping -u wang -k -b --become-user=mage

# 以 wang sudo 至 root 使用者執行 ls
ansible all -m command -u wang -a 'ls /root' -b --become-user=root -k -K

使用示範

// 單臺主機 10.0.0.7
ansible 10.0.0.7 -m ping

// websrvs 組
ansible websrvs -m ping

3.3.3)ansible-console

此工具可互動執行命令,支援 tab,ansible 2.0+ 新增
提示符格式:
執行使用者@當前操作的主機組 (當前組的主機數量)[f:併發數]$

常用子命令:

  • 設定併發數:forks n 例如: forks 10
  • 切換組:cd 主機組 例如: cd web
  • 列出當前組主機列表:list
  • 列出所有的內建命令: ? 或 help

範例
ansible-console:可互動式執行 ansible 命令

[01:13:41 root@ansible ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (3)[f:5]$ ping
192.168.80.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.80.18 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.80.28 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}

root@all (3)[f:5]$ list
192.168.80.8
192.168.80.18
192.168.80.28
root@all (3)[f:5]$ cd websrvs
root@websrvs (2)[f:5]$ list
192.168.80.18
192.168.80.28
root@websrvs (2)[f:5]$ forks 1
root@websrvs (2)[f:1]$ ping
192.168.80.18 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.80.28 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    }, 
    "changed": false, 
    "ping": "pong"
}
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started

3.3.4)ansible-playbook

此工具 用於執行編寫好的 PlayBook 任務

範例:

[root@ansible ~] vim hello.yml
---
# hello world yml file
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks:
    - name: hello world
      command: /usr/bin/wall hello world

[root@ansible ~] ansible-playbook hello.yml

image.png

3.3.5)ansible-vault

此工具可以用於加密解密 yml 檔案( RHCE 考試中存在該工具的考題 )

ansible-vault [create|decrypt|edit|encrypt|rekey|view]

範例

ansible-vault encrypt hello.yml     # 加密
ansible-vault decrypt hello.yml     # 解密
ansible-vault view hello.yml        # 檢視
ansible-vault edit hello.yml        # 編輯加密檔案
ansible-vault rekey hello.yml       # 修改口令
ansible-vault create new.yml        # 建立新檔案

3.3.6)ansible-galaxy

Galaxy 是一個免費網站,類似於 GitHub 網站,網站上釋出了很多的共享的 Roles 角色。
Ansible 提供了 ansible-galaxy 命令列工具連線 https://galaxy.ansible.com 網站下載相應的 Roles,進行 init (初始化)、search (查詢)、install (安裝)、 remove (移除)等操作。
image.png

範例:

# 搜尋專案
[root@ansible ~] ansible-galaxy search lamp

# 列出所有已安裝的 galaxy
ansible-galaxy list

# 安裝 galaxy, 預設下載到 ~/.ansible/roles 下
ansible-galaxy install geerlingguy.mysql
ansible-galaxy install geerlingguy.redis

# 刪除 galaxy
ansible-galaxy remove geerlingguy.redis