什麼是 Ansible?
Ansible是新出現的自動化運維工具,基於Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。
Ansible是基於模塊工作的,本身沒有批量部署的能力。真正具有批量部署的是Ansible所運行的模塊,ansible只是提供一種框架。主要包括:
- 連接插件connection plugins:負責和被監控端實現通信;
- host inventory:指定操作的主機,是一個配置文件裏面定義監控的主機;
- 各種模塊核心模塊、command模塊、自定義模塊;
- 藉助於插件完成記錄日誌郵件等功能;
- playbook:劇本執行多個任務時,非必需可以讓節點一次性運行多個任務。
Ansible的優點
-
Ansible融合了衆多老牌運維工具的優點,基本上pubbet和saltsatck能實現的功能,Ansible都可以顯現。
-
輕量級,無需在客戶端上安裝agent,更新時,只需要在操作機上進行一次更新即可。
-
Ansible是一個輕量級的工具,Ansible不需要啓動服務,僅僅只是一個工具,可以輕鬆實現分佈式擴展。
-
批量任務執行可以寫成腳本,而且不用分發的遠程就可以執行。
-
Ansible是一致性,高可靠性,安全性設計的輕量級自動化工具。
-
使用python編寫,維護更加簡單。
Ansible的基本架構,從上圖可以瞭解到其由以下部分組成:
-
核心:Ansible
-
核心模塊(Core Modules):這些都是ansible自帶的模塊
-
擴展模塊(Custom Modules):如果核心模塊不足以完成某種功能,可以添加擴展模塊
-
插件(Plugins):完成模塊功能的補充
-
劇本(Playbooks):ansible的任務配置文件,將多個任務定義在劇本中,由ansible自動執行
-
連接插件(Connectior Plugins):ansible基於連接插件連接到各個主機上,雖然ansible是使用ssh連接到各個主機的,但是它還支持其他的連接方法,所以需要有連接插件
-
主機羣(Host Inventory):定義ansible管理的主機
Ansible 任務執行模式
Ansible 系統由控制主機對被管節點的操作方式可分爲兩類,即adhoc
和playbook
:
- ad-hoc模式(點對點模式)
使用單個模塊,支持批量執行單條命令。ad-hoc 命令是一種可以快速輸入的命令,而且不需要保存起來的命令。就相當於bash中的一句話shell。 - playbook模式(劇本模式)
是Ansible主要管理方式,也是Ansible功能強大的關鍵所在。playbook通過多個task集合完成一類功能,如Web服務的安裝部署、數據庫服務器的批量備份等。可以簡單地把playbook理解爲通過組合多條ad-hoc操作的配置文件。
Ansible在運行時, 首先讀取ansible.cfg
中的配置, 根據規則獲取Inventory
中的管理主機列表, 並行的在這些主機中執行配置的任務, 最後等待執行返回的結果。
Ansible 命令執行過程
- 加載自己的配置文件,默認
/etc/ansible/ansible.cfg
- 查找對應的主機配置文件,找到要執行的主機或者組
- 加載自己對應的模塊文件,如 command
- 通過ansible將模塊或命令生成對應的臨時py文件(python腳本), 並將該文件傳輸至遠程服務器
- 對應執行用戶的家目錄的
.ansible/tmp/XXX/XXX.PY
文件 - 給文件 +x 執行權限
- 執行並返回結果
- 刪除臨時py文件,
sleep 0
退出
安裝 Ansible 有兩種方式,一種是使用 yum-epel 源模式,一種是使用 Python-pip 模式(會安裝最新版本),這裏我們選擇使用 yum-epel 源模式安裝
可以在官方網站上獲取最新版本 :https://releases.ansible.com/ansible/
Ansible配置文件
配置文件 |
說明 |
---|---|
/etc/ansible/ansible.cfg | ansible主配置文件 |
/etc/ansible/hosts | 受控主機清單 |
查看主配置文件 /etc/ansible/ansible.cfg
- 詳細說明,默認使用不用註釋#號
- #inventory = /etc/ansible/hosts 主機清單存放位置
- #library = /usr/share/my_modules/ ansible 默認搜尋模塊的位置
- #module_utils = /usr/share/my_module_utils/
- #remote_tmp = ~/.ansible/tmp
- #local_tmp = ~/.ansible/tmp
- #plugin_filters_cfg = /etc/ansible/plugin_filters.yml
- #forks = 5 與主機通信時的默認並行數,默認爲5
- #poll_interval = 15
- #sudo_user = root sudo使用的默認用戶,默認是root
- #ask_sudo_pass = False 默認爲 True
- #ask_pass = False 默認爲 True,控制ansible playbook是否會自動彈出密碼
- #transport = smart 通信機制.默認 值爲’smart’。如果本地系統支持 ControlPersist技術的話,將會使用(基於OpenSSH)‘ssh’,如果不支持將使用‘paramiko’.其他傳輸選項‘local’,‘chroot’,’jail’等等
- #remote_port = 22 遠程ssh端口,默認是22
- #module_lang = C 模塊和系統之間通信的計算機語言,默認是C語言
- #module_set_locale = False
- #timeout =10 設置SSH連接的超時時間,單位爲秒
- #host_key_checking = False //檢查主機密鑰
- #log_path = /var/log/ansible.log //日誌文件存放路徑
- #module_name = command //ansible命令執行默認的模塊
- #private_key_file = /path/to/file //私鑰文件存儲位置
Ansuble主機清單文件 /etc/ansible/hosts
主機清單裏面保存的是 ansible 需要連接管理的主機列表
- 直接指明主機地址或主機名:
- ## green.example.com
- ## blue.example.com
- 192.168.100.1
- 192.168.100.10
- 定義一個主機組[組名]把地址或主機名加進去
- [webservers]
- ## alpha.example.org
- ## beta.example.org
- 192.168.10.5
- 192.168.10.6
注意:在使用Ansible之前必須要先做ssh免密碼登錄,確保各主機都能使用密鑰無密碼登錄
設置方法請參照拙作:https://blog.csdn.net/gaofei0428/article/details/104018808
使用普通用戶(sudo)
使用 root 用戶
Ansible 常用命令
/usr/bin/ansible
Ansibe AD-Hoc 臨時命令執行工具,常用於臨時命令的執行/usr/bin/ansible-doc
Ansible 模塊功能查看工具/usr/bin/ansible-galaxy
下載/上傳優秀代碼或Roles模塊 的官網平臺,基於網絡的/usr/bin/ansible-playbook
Ansible 定製自動化的任務集編排工具/usr/bin/ansible-pull
Ansible遠程執行命令的工具,拉取配置而非推送配置(使用較少,海量機器時使用,對運維的架構能力要求較高)/usr/bin/ansible-vault
Ansible 文件加密工具/usr/bin/ansible-console
Ansible基於Linux Consoble界面可與用戶交互的命令執行工具
Ansible 命令詳解
- 命令的具體格式如下:
- ansible <host-pattern> [-f forks] [-m module_name] [-a args]
- 可以使用 ansible -h 來獲取幫助
其中常用到的有
-a MODULE_ARGS
模塊的參數,如果執行默認COMMAND的模塊,即是命令參數,如: “date”,“pwd”等等-k
,--ask-pass
#ask for SSH password 登錄密碼,提示輸入SSH密碼而不是假設基於密鑰的驗證--ask-su-pass
#ask for su password su切換密碼-K
,--ask-sudo-pass
#ask for sudo password 提示密碼使用sudo,sudo表示提權操作--ask-vault-pass
#ask for vault password 假設我們設定了加密的密碼,則用該選項進行訪問-B SECONDS
後臺運行超時時間-C
模擬運行環境並進行預運行,可以進行查錯測試-c CONNECTION
連接類型使用-f FORKS
並行任務數,默認爲5-i INVENTORY
指定主機清單的路徑,默認爲/etc/ansible/hosts
--list-hosts
查看有哪些主機組-m MODULE_NAME
執行模塊的名字,默認使用 command 模塊,所以如果是隻執行單一命令可以不用 -m參數-o
壓縮輸出,嘗試將所有結果在一行輸出,一般針對收集工具使用-S
用 su 命令-R SU_USER
指定 su 的用戶,默認爲 root 用戶-s
用 sudo 命令-U SUDO_USER
指定 sudo 到哪個用戶,默認爲 root 用戶-T TIMEOUT
指定 ssh 默認超時時間,默認爲10s,也可在配置文件中修改-u REMOTE_USER
遠程用戶,默認爲 root 用戶-v
查看詳細信息,同時支持-vvv
,-vvvv
可查看更詳細信息
Ansible 常用模塊
- ping、yum、template、copy、user、group、service、raw、command、shell、script、file
- Ansible raw 、command 、shell 的區別:
- shell 模塊調用/bin/sh指令執行
- command 模塊不是調用的shell的指令,所以沒有bash的環境變量
- raw很多地方和shell類似,更多的地方建議使用shell和command模塊。
- 但是如果是使用老版本python,需要用到raw,又或者是客戶端是路由器,因爲沒有安裝python模塊,那就需要使用raw模塊了
- 192.168.10.5 | SUCCESS
- 192.168.10.6 | SUCCESS 代表目標主機暢通
- 也可以使用 ansible all -m ping 測試 /etc/ansible/hosts 配置文件中定義的所有主機
-
command 模塊
- 這個模塊可以直接在遠程主機上執行命令,並將結果返回本主機。
- ansible
定義的主機名或主機組
-m command -a 'ss -antl' - 注意,該命令不支持
| 管道命令
- 模塊下常用的幾個命令:
- chdir # 在執行命令之前,先切換到該目錄
executable # 切換shell來執行命令,需要使用命令的絕對路徑
free_form # 要執行的Linux指令,一般使用Ansible的-a參數代替。
creates # 一個文件名,當這個文件存在,則該命令不執行,可以用來做判斷
removes # 一個文件名,這個文件不存在,則該命令不執行 - ansible
定義的主機名或主機組
-m command -a 'chdir=/data/ ls' #先切換到/data/ 目錄,再執行“ls”命令
- ansible
定義的主機名或主機組
-m command -a 'creates=/tmp/1.txt ls' 如果 /tmp/1.txt 文件存在,則不執行“ls”命令
- ansible webservers -m command -a 'removes=/tmp/1.txt ls' 如果/tmp/1.txt存在,則執行 “ls” 命令
-
shell 模塊
- shell模塊可以在遠程主機上調用shell解釋器運行命令,支持shell的各種功能,例如管道等。
- ansible webservers -m shell -a 'cat /etc/passwd | grep "gf" >> /tmp/1.txt' 支持管道和重定向功能
-
copy 模塊
- 這個模塊用於將文件複製到遠程主機,同時支持給定內容生成文件和修改權限等。
- 常用選項有:
src
#被複制到遠程主機的本地文件。可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,則會遞歸複製,用法類似於"rsync"content
#用於替換"src",可以直接指定文件的值dest
#必選項,將源文件複製到的遠程主機的絕對路徑backup
#當文件內容發生改變後,在覆蓋之前把源文件備份,備份文件包含時間信息directory_mode
#遞歸設定目錄的權限,默認爲系統默認權限force
#當目標主機包含該文件,但內容不同時,設爲"yes",表示強制覆蓋;設爲"no",表示目標主機的目標位置不存在該文件才複製。默認爲"yes"others
#所有的 file 模塊中的選項可以在這裏使用- 將當前目錄下的 test.txt 文件複製到主機組下主機的 /tmp 目錄下
- ansible webservers -m copy -a 'src=./test.txt dest=/tmp/'
- 使用 content= 給定內容生成文件,並設定權限
- 把文件的內容修改一下,然後選擇覆蓋備份:
- ansible webservers -m copy -a 'content="I am root\n" backup=yes dest=/tmp/name.txt mode=666'
-
file 模塊
- 該模塊主要用於設置文件的屬性,比如創建文件、創建鏈接文件、刪除文件等。
- 下面是一些常見的命令:
-
force
#需要在兩種情況下強制創建軟鏈接,一種是源文件不存在,但之後會建立的情況下;另一種是目標軟鏈接已存在,需要先取消之前的軟鏈,然後創建新的軟鏈,有兩個選項:yes|nogroup
#定義文件/目錄的屬組。後面可以加上mode
:定義文件/目錄的權限owner
#定義文件/目錄的屬主。後面必須跟上path
:定義文件/目錄的路徑recurse
#遞歸設置文件的屬性,只對目錄有效,後面跟上src
:被鏈接的源文件路徑,只應用於state=link
的情況dest
#被鏈接到的路徑,只應用於state=link
的情況 -
state
#狀態,有以下選項:directory
:如果目錄不存在,就創建目錄file
:即使文件不存在,也不會被創建link
:創建軟鏈接hard
:創建硬鏈接touch
:如果文件不存在,則會創建一個新的文件,如果文件或目錄已存在,則更新其最後修改時間absent
:刪除目錄、文件或者取消鏈接文件 - 創建目錄
- ansible webservers -m file -a 'path=/tmp/app state=directory'
- 創建鏈接文件
- ansible webservers -m file -a 'path=/home/gf/name.txt src=/tmp/name.txt state=link'
- 刪除文件
- ansible webservers -m file -a 'path=/home/gf/name.txt state=absent'
- fetch 模塊
- 該模塊用於從遠程某主機獲取(複製)文件到本地。
- 有兩個選項
dest
:用來存放文件的目錄src
:在遠程拉取的文件,並且必須是一個file,不能是目錄- ansible webservers -m fetch -a 'src=/tmp/name.txt dest=/tmp'
注意:文件保存的路徑在我們設置的接收目錄下的被管制主機ip
目錄下
- cron 模塊
-
該模塊適用於管理
cron
計劃任務
其使用的語法跟crontab
文件中的語法一致: day=
#日應該運行的工作( 1-31, , /2, )hour=
# 小時 ( 0-23, , /2, )minute=
#分鐘( 0-59, , /2, )month=
# 月( 1-12, *, /2, )weekday=
# 周 ( 0-6 for Sunday-Saturday,, )job=
#指明運行的命令是什麼name=
#定時任務描述reboot
# 任務在重啓時運行,不建議使用,建議使用special_timespecial_time
#特殊的時間範圍,參數:reboot(重啓時),annually(每年),monthly(每月),weekly(每週),daily(每天),hourly(每小時)state
#指定狀態,present表示添加定時任務,也是默認設置,absent表示刪除定時任務user
# 以哪個用戶的身份執行
- 添加計劃任務
- ansible webservers -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 192.168.10.2 &> /dev/null"'
- 刪除計劃任務
- 首先查看一下已經存在的計劃任務
- ansible webservers -m shell -a 'crontab -l'
- 然後執行刪除操作
- ansible webservers -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 192.168.10.2 &> /dev/null" state=absent'
-
yum 模塊
- 該模塊主要用於軟件的安裝
- 其選項如下:
name=
#所安裝的包的名稱state=
#present
--->安裝,latest
--->安裝最新的,absent
---> 卸載軟件。update_cache
#強制更新yum的緩存conf_file
#指定遠程yum安裝時所依賴的配置文件(安裝本地已有的包)。disable_pgp_check
#是否禁止GPG checking,只用於present
orlatest
。disablerepo
#臨時禁止使用yum庫。 只用於安裝或更新時。enablerepo
#臨時使用的yum庫。只用於安裝或更新時- 使用 yum 模塊安裝 HTTP
- ansible webservers -m yum -a 'name=httpd state=present'
- service 模塊
- 該模塊用於服務程序的管理。其主要選項如下:
arguments
#命令行提供額外的參數enabled
#設置開機啓動。name=
#服務名稱runlevel
#開機啓動的級別,一般不用指定。sleep
#在重啓服務的過程中,是否等待。如在服務關閉以後等待2秒再啓動。(定義在劇本中。)state
#有四種狀態,分別爲:started
--->啓動服務,stopped
--->停止服務,restarted
--->重啓服務,reloaded
--->重載配置
- 開啓服務並設置開機啓動
- ansible webservers -m service -a 'name=httpd state=started enabled=true'
-
user 模塊
- 該模塊主要是用來管理用戶賬號。
- 其主要選項如下:
comment
# 用戶的描述信息createhome
# 是否創建家目錄force
# 在使用state=absent時, 行爲與userdel –force一致.group
# 指定基本組groups
# 指定附加組,如果指定爲(groups=)表示刪除所有組home
# 指定用戶家目錄move_home
# 如果設置爲home=時, 試圖將用戶主目錄移動到指定的目錄name
# 指定用戶名non_unique
# 該選項允許改變非唯一的用戶ID值password
# 指定用戶密碼remove
# 在使用state=absent時, 行爲是與userdel –remove一致shell
# 指定默認shellstate
# 設置帳號狀態,不指定爲創建,指定值爲absent表示刪除system
# 當創建一個用戶,設置這個用戶是系統用戶。這個設置不能更改現有用戶uid
# 指定用戶的uid- 添加一個用戶 2020 指定其 uid 爲 2020
- ansible webservers -m user -a 'name=2020 uid=2020'
- 刪除用戶
- ansible webservers -m user -a 'name=2020 remove=true state=absent'
-
group 模塊
- 該模塊主要用於添加或刪除組。
gid=
#設置組的GID號name=
#指定組的名稱state=
#指定組的狀態,默認爲創建,設置值爲absent
爲刪除system=
#設置值爲yes
,表示創建爲系統組- ansible webservers -m group -a 'name=2020 gid=2020'
- 刪除組
- ansible webservers -m group -a 'name=2020 state=absent'
-
script 模塊
- 該模塊用於將本機的腳本在被管理端的機器上運行
- 該模塊直接指定腳本的路徑即可
- chmod +x test.sh
- ansible webservers -m script -a './test.sh'
setup 模塊
- 該模塊主要用於收集信息,是通過調用facts組件來實現的。
- facts組件是Ansible用於採集被管機器設備信息的一個功能,我們可以使用setup模塊查機器的所有facts信息,可以使用filter來查看指定信息。整個facts信息被包裝在一個JSON格式的數據結構中,ansible_facts是最上層的值。
- facts就是變量,內建變量 。每個主機的各種信息,cpu顆數、內存大小等。會存在facts中的某個變量中。調用後返回很多對應主機的信息,在後面的操作中可以根據不同的信息來做不同的操作。如redhat系列用yum安裝,而debian系列用apt來安裝軟件。
- 查看信息
- 保存信息
- setup 模塊還有一個很好用的功能就是可以保存所篩選的信息至主機上,同時文件名爲我們被管制的主機的IP,這樣方便我們知道是哪臺機器出的問題。
- ansible webservers -m setup -a 'filter="*mem*"' --tree /tmp/mem.txt
-
Playbook
- Playbook 是由一個或多個play組成的列表,主要功能是將task定義好的角色歸併爲一組進行統一管理,也就是通過Ansible的模板將多個play組織在一個Playbook中運行。
-
Playbook的格式
-
playbook由YMAL語言編寫。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl等。MAL格式是類似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。以下爲playbook常用到的YMAL格式。
-
YMAL中的列表元素以” - ”開頭然後緊跟着 一個空格,後面爲元素內容。就像這樣 - host
-
同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
-
playbook中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以” : ”分隔,” : ”後面還要增加 一個空格
-
劇本以.yml後綴
Playbook的核心元素
- Playbook本身由以下各部分組成:
Hosts:運行指定任務的目標主機
Tasks:任務,即調用模塊完成的操作
Variables:變量
Templates:模板
Handles:處理器,當某條件滿足時,觸發執行的操作
Roles:角色
- hosts和users介紹
-
在playbook中的每一個play都可以選擇在哪些服務器和以什麼用戶完成,hosts一行可以是一個主機組、主機、多個主機,中間以冒號分隔,可使用通配模式。其中remote_user表示執行的用戶賬號。
-
注意 - 後面的空格,字段一定要對齊
任務列表的元素介紹
Play的主體是任務列表。任務列表中的任務依照次序逐個在hosts中指定的所有主機上執行,如果發生錯誤會將所有已執行任務回滾。
-
模塊、模塊參數格式
task的任務是按照指定的參數去執行模塊
action:moudle options
moudle:options,其中後者可以實現向後兼容
注意:在Ansible自帶模塊中,command模塊和shell模塊只需要一個列表定義即可,無需使用key=value格式。
- hosts: webservers //指定主機或者主機組
remote_user: root //指定在被管理的主機上執行任務的用戶
tasks: //任務列表↓
- name: remove httpd //任務名稱卸載HttpD服務
yum: name=httpd state=absent //使用 yum 模塊卸載相關服務
-
注意:一個 - name 下面只能跟一個命令列表
-
Handles和tags的使用
Handlers用於當關注的資源發生變化時所採取的操作。使用tags讓用戶選擇跳過沒有變化的代碼,只運行Playbook中發生變化的部分代碼。
某任務的狀態在運行後爲changed時,可通過“notify”通知給相應的handlers
任務可以通過“tags“打標籤,通過 ansible-playbook命令 使用 --tags選項能實現僅運行指定的tasks
- 通知者進行notify,如果沒有被notify,則Handlers不會執行,假如被notify了,則Handlers被執行
- 不管有多少個通知者進行了notify,等到play中的所有task執行完成之後,handlers也只會被執行一次
- 如果我們只想執行其中的某一個task或多個task時就可以使用tags標籤功能了
- 修改配置文件內容之後執行時調用標籤ansible-playbook nginx.yml --tags="only",就會跳過安裝步驟直接重載配置文件。
- 使用 ansible-playbook httpd.yml --syntax-check 檢測劇本格式是否有錯
- 指定運行 tags ansible-playbook httpd.yml --tags="only"
- 劇本只執行 tags only 前的列表,後面的安裝啓動列表沒有被執行
- 可以爲單個或多個task指定同一個tags
- Playbook還提供了一個特殊的tags爲always
- 作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。
-
variables:變量
facts:可直接調用
注意:可使用setup模塊直接獲取目標主機的facters
-
ansible webservers -m setup
- Playbook中定義變量
- 使用:vars: 添加變量
- 注意段落對齊