Ansible配置文件 一、ansible配置文件 1.配置ansible 可以通過修改 Ansible 配置文件中的設置來自定義 Ansible安裝的行為。 Ansible從控制節點上多個可能的位置之一選擇其配置文件。 使用/etc/ansible/ansible.cfg ansible軟體包提供 ...
Ansible配置文件
目錄一、ansible配置文件
1.配置ansible
可以通過修改 Ansible 配置文件中的設置來自定義 Ansible安裝的行為。
Ansible從控制節點上多個可能的位置之一選擇其配置文件。
使用/etc/ansible/ansible.cfg
ansible軟體包提供一個基本的配置文件,它位於/etc/ansible/ansible.cfg。如果找不到其他配置文件,則使用此文件。
使用~/.ansible.cfg
Ansible在用戶的家目錄中查找.ansible.cfg文件。如果存在此配置文件並且當前工作目錄中也沒有ansible.cfg文件,則使用此配置取代/etc/ansible/ansible.cfg。
使用./ansible.cfg
如果執行ansible命令的目錄中存在ansible.cfg文件,則使用它,而不使用全局文件或用戶的個人文件。這樣,管理員可以創建一種目錄結構,將不同的環境或項目存儲在單獨的目錄中,並且每個目錄包含為獨特的一組設置而定製的配置文件。
推薦的做法是在需要運行Ansible命令的目錄中創建ansible.cfg文件。此目錄中也將包含任何供Ansible項目使用的文件,如清單和playbook。這是用於Ansible配置文件的最常用位置。實踐中不常使用~/.ansible.cfg或/etc/ansible/ansible.cfg文件
使用ANSIBLE_CONFIG環境變數
我們可以通過將不同的配置文件放在不同的目錄中,然後從適當的目錄執行Ansible命令,以此利用配置文件。但是,隨著配置文件數量的增加,這種方法存在局限性並且難以管理。有一個更加靈活的選項,即通過ANSIBLE_CONFIG環境變數定義配置文件的位置。定義了此變數時,Ansible將使用變數所指定的配置文件,而不用上面提到的任何配置文件。
2.配置文件優先順序
ansible的配置文件名為ansible.cfg,預設會在四個地方(根據高/低優先順序排序——從1到4):
- ANSIBLE_CONFIG:Ansible命令會優先檢查該環境變數以及這個環境變數指向的配置文件
Export 環境變數:設置環境變數
Unset 環境變數: 取消環境變數 - ./ansible.cfg:當前工作目錄,即當前執行ansible指令的目錄,如果ANSIBEL_CONFIG環境變數(上一優先順序配置文件)未定義,則優先使用該配置文件
- ~/.ansible.cfg:用戶家目錄下的隱藏文件,若當前工作目錄下不存在ansible.cfg配置文件(上一優先順序目錄中的文件),則會查找用戶家目錄下的該隱藏文件
- /etc/ansible/ansible.cfg:預設配置文件,如果上面兩個路徑下的ansible.cfg都不存在,則使用該文件
由於Ansible配置文件可以放入的位置有多種,因此Ansible當前使用哪一個配置文件可能會令人困惑。我們可以運行以下命令來清楚地確認所安裝的Ansible版本以及正在使用的配置文件。
[root@localhost ~]# ansible --version
ansible 2.9.6
config file = /etc/ansible/ansible.cfg
...........
Ansible僅使用具有最高優先順序的配置文件中的設置。即使存在優先順序較低的其他配置文件,其設置也會被忽略,不會與選定配置文件中的設置結合。因此,如果你選擇自行創建配置文件來取代全局/etc/ansible/ansible.cfg配置文件,就需要將該文件中所有需要的設置複製到自己的用戶級配置文件中。用戶組配置文件中未定義的設置將保持設為內置預設值,即使已在全局配置文件中設為某個其他值也是如此。
3.管理配置文件中的設置
Ansible配置文件由幾個部分組成,每一部分含有以鍵值對形式定義的設置。部分的標題以中括弧括起來。對於基本操作,請使用以下兩部分:
- [defaults]部分設置Ansible操作的預設值
- [privilege_escalation]配置Ansible如何在受管主機上執行特權升級
例如,下麵是典型的ansible.cfg文件:
[defaults]
inventory = ./inventory
remote_user = user
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
下表說明瞭此文件中的指令:
Ansible配置
指令 | 描述 |
---|---|
inventory | 指定清單文件的路徑。 |
remote_user | 要在受管主機上登錄的用戶名。如果未指定則使用當前用戶名 |
ask_pass | 是否提示輸入SSH密碼。如果使用SSH公鑰身份驗證則可以是false |
become | 連接後是否自動在受管主機上切換用戶(通常切換為root) 這也可以通過play來指定。 |
become_method | 如何切換用戶(通常為sudo,這也是預設設置,但可選擇su) |
become_user | 要在受管主機上切換到的用戶(通常是root,這也是預設值) |
become_ask_pass | 是否需要為become_method提示輸入密碼。預設為false。 |
4.配置連接
Ansible需要知道如何與其受管主機通信。更改配置文件的一個最常見原因是為了控制Ansible使用什麼方法和用戶來管理受管主機。需要的一些信息包括:
- 列出受管主機和主機組的清單的位置
- 要使用哪一種連接協議來與受管主機通信(預設為SSH),以及是否需要非標準網路埠來連接伺服器
- 要在受管主機上使用哪一遠程用戶;這可以是root用戶或者某一非特權用戶
- 如果遠程用戶為非特權用戶,Ansible需要知道它是否應嘗試將特權升級為root以及如何進行升級(例如,通過sudo)
- 是否提示輸入SSH密碼或sudo密碼以進行登錄或獲取特權
4.1連接設置
預設情況下,Ansible使用SSH協議連接受管主機。控制Ansible如何連接受管主機的最重要參數在[defaults]部分中設置。
預設情況下,Ansible嘗試連接受管主機時使用的用戶名與運行ansible命令的本地用戶相同。若要指定不同的遠程用戶,請將remote_user參數設置為該用戶名。
如果為運行Ansible的本地用戶配置了SSH私鑰,使得它們能夠在受管主機上進行遠程用戶的身份驗證,則Ansible將自動登錄。如果不是這種情況,可以通過設置指令ask_pass = true,將Ansible配置為提示本地用戶輸入由遠程用戶使用的密碼。
【defaults]
inventory = ./inventory
remote_user = root
ask_pass = true
假設在使用一個Linux控制節點,並對受管主機使用OpenSSH,如果可以使用密碼以遠程用戶身份登錄,那麼我們可以設置基於SSH密鑰的身份驗證,從而能夠設置ask_pass = false。
第一步是確保在~/.ssh中為控制節點上的用戶配置了SSH密鑰對。並且使用ssh-copy-id命令將本地的公鑰複製到受管主機中。
[root@localhost ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:7yO2BD/BEu9k/IHVA6P+ttx6OnjfxedM4AbHJLh7W3w [email protected]
The key's randomart image is:
+---[RSA 3072]----+
| o |
| . = |
| . . o + . |
| * o . = |
| o S o . + |
| B = o = o |
| =.* . = E|
| .+=++.= *.|
| ..+*B+ . o|
+----[SHA256]-----+
[root@localhost ~]# ssh-copy-id -i ./.ssh/id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "./.ssh/id_rsa.pub"
The authenticity of host '192.168.111.142 (192.168.111.142)' can't be established.
ECDSA key fingerprint is SHA256:ihTF+QdYwS+/XcImxzGkKP1w2QFfOkfCl+AI91A/g4Y.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
4.2升級特權
鑒於安全性和審計原因,Ansible可能需要先以非特權用戶身份連接遠程主機,然後再通過特權升級獲得root用戶身份的管理許可權。這可以在Ansible配置文件的[privilege_escalation]部分中設置。
要預設啟用特權升級,可以在配置文件中設置指令become = true。即使預設為該設置,也可以在運行臨時命令或Ansible Playbook時通過各種方式覆蓋它。(例如,有時候可能要運行一些不需要特權升級的任務或play。)
become_method指令指定如何升級特權。有多個選項可用,但預設為使用sudo。類似地,become_user指令指定要升級到的用戶,但預設為root。
如果所選的become_method機制要求用戶輸入密碼才能升級特權,可以在配置文件中設置become_ask_pass = true指令。
以下示例ansible.cfg文件假設你可以通過基於SSH密鑰的身份驗證以someuser用戶身份連接受管主機,並且someuser可以使用sudo以root用戶身份運行命令而不必輸入密碼:
[defaults]
inventory = ./inventory
remote_user = someuser
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
5.配置文件註釋
Ansible配置文件允許使用兩種註釋字元:井號或分號。
位於行開頭的#號會註釋掉整行。它不能和指令位於同一行中。
分號字元可以註釋掉所在行中其右側的所有內容。它可以和指令位於同一行中,只要該指令在其左側。
二、構建ansible清單
1.定義清單
清單定義Ansible將要管理的一批主機。這些主機也可以分配到組中,以進行集中管理。組可以包含子組,主機也可以是多個組的成員。清單還可以設置應用到它所定義的主機和組的變數。
可以通過兩種方式定義主機清單。靜態主機清單可以通過文本文件定義。動態主機清單可以根據需要使用外部信息提供程式通過腳本或其他程式來生成。
2.清單存放位置
在[defaults]部分中,inventory指令可以直接指向某一靜態清單文件,或者指向含有多個靜態清單文件和動態清單腳本的某一目錄。
[defaults]
inventory = ./inventory
3.使用靜態清單指定受管主機
靜態清單文件是指定Ansible目標受管主機的文本文件。可以使用多種不同的格式編寫此文件,包括INI樣式或YAML。一般預設使用的INI模式
在最簡單的形式中。INI樣式的靜態清單文件是受管主機的主機名或IP地址的列表,每行一個:
配置文件位置為:/etc/ansible/hosts
192.168.111.142
192.168.111.143
web1
但通常而言,可以將受管主機組織為主機組。通過主機組,可以更加有效的對一系列系統運行Ansible。這時,每一部分的開頭為以中括弧括起來的主機組名稱。其後為該組中每一受管主機的主機名或IP地址,每行一個。
web1
[webservers]
192.168.111.142
[dbservers]
192.168.111.143
4.驗證清單
若有疑問,可使用 ansible 命令驗證電腦是否存在於清單中:
ansible [主機名/IP] --list-hosts
[root@localhost ~]# ansible web1 --list-hosts
hosts (1):
web1
//不存在清單中
[root@localhost ~]# ansible web111111111 --list-hosts
[WARNING]: Could not match supplied host pattern, ignoring: web111111111
[WARNING]: No hosts matched, nothing to do
hosts (0):
運行以下命令來列出指定組中的所有主機:
ansible [組名稱] --list-hosts
[root@localhost ~]# ansible webservers --list-hosts
hosts (1):
192.168.111.142
如果清單中含有名稱相同的主機和主機組,ansible 命令將顯示警告並以主機作為其目標。主機組則被忽略。
應對這種情況的方法有多種,其中最簡單的是確保主機組不使用與清單中主機相同的名稱。
5.構建Ansible清單
清單內容:
web1
[webservers]
192.168.111.142
[dbservers]
192.168.111.143
使用以下命令列出預設清單文件中的所有受管主機:
[root@localhost ~]# ansible all --list-hosts
hosts (3):
web1
192.168.111.142
192.168.111.143
使用以下命令列出不屬於任何組的受管主機:
[root@localhost ~]# ansible ungrouped --list-hosts
hosts (1):
web1
使用以下命令列出屬於某組的受管主機:
[root@localhost ~]# ansible dbservers --list-hosts
hosts (1):
192.168.111.143
6.自定義清單文件
在清單的位置中已經創建一個名為inventory的自定義靜態清單文件。
伺服器清單規格
主機IP | 用途 | 位置 | 運行環境 |
---|---|---|---|
192.168.111.142 | web伺服器 | 武漢 | 測試 |
192.168.111.143 | web伺服器 | 武漢 | 生產 |
編輯/etc/ansible/inventory文件,將上表中所列出的主機加入受管主機序列。
[root@localhost ~]# vim /etc/ansible/ansible.cfg
inventory = /etc/ansible/inventory //自定義清單存放位置
[root@localhost ~]# vim /etc/ansible/inventory
[test1]
192.168.111.142 ansible_user=root ansible_password=1 //密碼寫在配置文件中容易泄露最好別寫
[produce]
192.168.111.143
執行以下命令列出所有受管主機:
[root@localhost ~]# ansible all -i /etc/ansible/inventory --list-hosts
hosts (2):
192.168.111.142
192.168.111.143
執行以下命令列出webservers組中的所有受管主機:
[root@localhost ~]# ansible test1 -i /etc/ansible/inventory --list-hosts
hosts (1):
192.168.111.142
三、運行臨時命令
Ansible運行臨時命令的語法如下:
ansible host-pattern -m module [-a 'module arguments'] [-i inventory]
host-pattern參數用於指定在其上運行臨時命令的受管主機。它可以是清單中的特定受管主機或主機組。也可以用後面的-i選項指定特定的清單而不使用預設清單。
-m選項將Ansible應在目標主機上運行的module名稱作為參數。模塊是為了實施任務而執行的小程式。一些模塊不需要額外的信息,但其他模塊需要使用額外的參數來指定其操作詳情。-a選項以帶引號字元串形式取這些參數的列表。
一種最簡單的臨時命令使用ping模塊。此模塊不執行ICMP ping,而是檢查能否在受管主機上運行基於Python的模塊。例如,以下臨時命令確定清單中的所有受管主機能否運行標準的模塊:
[root@localhost ~]# ansible all -m ping
192.168.111.143 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.111.142 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
1.使用臨時命令通過模塊來執行任務
模塊是臨時命令用於完成任務的工具。Ansible提供了數百個能夠完成不同任務的模塊。通常我們可以查找一個經過測試的專用模塊,作為標準安裝的一部分來完成所需的任務。
ansible-doc -l命令可以列出系統上安裝的所有模塊
可以使用ansible-doc來按照名稱查看特定模塊的幫助文檔,再查找關於模塊將取什麼參數作為選項的信息。
例如以下命令顯示ping模塊的幫助文檔,在幫助文檔裡面輸入q命令表示退出:
ansible-doc ping
更多的模塊信息請訪問線上Ansible文檔,網址:
Index of all Modules — Ansible Documentation
Ansible常用模塊
模塊類別 | 模塊 |
---|---|
文件模塊 | copy:將本地文件複製到受管主機 file:設置文件的許可權和其他屬性 lineinfile:確保特定行是否在文件中 synchronize:使用rsync同步內容 |
軟體包模塊 | package:使用操作系統本機的自動檢測軟體包管理器管理軟體包 yum:使用yum管理軟體包 apt:使用APT管理軟體包 dnf:使用dnf管理軟體包 gem:管理Ruby gem pip:從PyPI管理Python軟體包 |
系統模塊 | firewalld:使用firewalld管理防火牆 reboot:重啟電腦 service:管理服務 user:添加、刪除和管理用戶帳戶 |
Net Tools模塊 | get_url:通過HTTP、HTTPS或FTP下載文件 nmcli:管理網路 uri:與Web服務交互 |
大部分模塊會取用參數。可在模塊的文檔中找到可用於該模塊的參數列表。臨時命令可以通過-a選項向模塊傳遞參數。無需參數時,可從臨時命令中省略-a選項。如果需要指定多個參數,請以引號括起的空格分隔列表形式提供。
例如,以下臨時命令使用user模塊來確保runtime用戶存在於192.168.111.142上並且其UID為4000:
[root@localhost ~]# ansible 192.168.111.142 -m user -a 'name=runtime uid=4000 state=present'
192.168.111.142 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 4000,
"home": "/home/runtime",
"name": "runtime",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 4000
}
[root@localhost ~]# ansible 192.168.111.142 -a 'id runtime'
192.168.111.142 | CHANGED | rc=0 >>
uid=4000(runtime) gid=4000(runtime) groups=4000(runtime)
大多數模塊為idempotent,這表示它們可以安全地多次運行;如果系統已處於正確的狀態,它們不會進行任何操作。
2.在受管主機上運行任意命令
command模塊允許管理員在受管主機的命令行中運行任意命令。要運行的命令通過-a選項指定為該模塊的參數。例如,以下命令將對webservers組的受管主機運行hostname命令:
[root@localhost ~]# ansible test1 -m command -a 'hostname'
192.168.111.142 | CHANGED | rc=0 >>
LNMP
這條命令為每個受管主機返回兩行輸出。第一行是狀態報告,顯示對其運行臨時操作的受管主機名稱及操作的結果。第二行是使用Ansible command模塊遠程執行的命令的輸出。
若要改善臨時命令輸出的可讀性和解析,管理員可能會發現使對受管主機執行的每一項操作具有單行輸出十分有用。使用-o選項以單行格式顯示Ansible臨時命令的輸出。
[root@localhost ~]# ansible test1 -m command -a 'hostname' -o
192.168.111.142 | CHANGED | rc=0 | (stdout) LNMP
command模塊允許管理員對受管主機快速執行遠程命令。這些命令不是由受管主機上的shell加以處理。因此,它們無法訪問shell環境變數,也不能執行重定向和管道等shell操作。
在命令需要shell處理的情形中,管理員可以使用shell模塊。與command模塊類似,可以在臨時命令中將要執行的命令作為參數傳遞給該模塊。Ansible隨後對受管主機遠程執行該命令。與command模塊不同的是,這些命令將通過受管主機上的shell進行處理。因此,可以訪問shell環境變數,也可以使用重定向和管道等操作。
以下示例演示了command與shell的區別。如果嘗試使用這兩個模塊執行內建的Bash命令set,只有使用shell模塊才會成功:
[root@localhost ~]# ansible 192.168.111.143 -m command -a 'set'
192.168.111.143 | FAILED | rc=2 >>
[Errno 2] No such file or directory: b'set': b'set'
[root@localhost ~]# ansible 192.168.111.143 -m shell -a 'set'
192.168.111.143 | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:complete_fullquote:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_EXECUTION_STRING=set
...............
TERM=xterm
UID=0
USER=root
XDG_RUNTIME_DIR=/run/user/0
XDG_SESSION_ID=6
_=/usr/libexec/platform-python
which_declare='declare -f'
command和shell模塊都要求受管主機上安裝正常工作的Python。第三個模塊是raw,它可以繞過模塊子系統,直接使用遠程shell運行命令。在管理無法安裝Python的系統(如網路路由器)時,可以利用這個模塊。它也可以用於將Python安裝到主機上。
在大多數情況下,建議避免使用command、shell和raw這三個“運行命令”模塊。
其他模塊大部分都是冪等的,可以自動進行更改跟蹤。它們可以測試系統的狀態,在這些系統已處於正確狀態時不執行任何操作。相反,以冪等方式使用“運行命令”模塊要複雜得多。依靠它們,你更難以確信再次運行臨時命令或playbook不會造成意外的失敗。當shell或command模塊運行時,通常會基於它是否認為影響了電腦狀態而報告CHANGED狀態。
有時候,“運行命令”模塊是有用的工具,也是解決問題的好辦法。如果確實需要使用它們,可能最好先嘗試用command模塊,只有在需要shell或raw模塊的特殊功能時才利用它們。