Ansible 可同時操作屬於一個組的多台主機,組和主機之間的關系通過 inventory 文件配置. 默認的文件路徑為 /etc/ansible/hosts。
除默認文件外,還可以同時使用多個 inventory 文件,也可以從動態源,或雲上拉取 inventory 配置信息。
4.1 靜態Inventory文件
靜態Inventory指的是在文件/etc/ansible/hosts中指定的主機和組,其格式類似於Windows的ini配置文件。如:
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
- 方括號[]中是組名,用於對主機進行分類,便於對不同類別進行分別管理。
- 一個主機可以屬於不同的組。如果有主機的SSH端口不是標准的22端口,可以在主機名之后加上端口號,用冒號分割。如:
badwolf.example.com:5309
- 假設你有一些靜態IP地址,希望設置一些別名,但不是在系統的 host 文件中設置,又或者你是通過隧道在連接,那么可以設置如下:
jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50
- 一組相似的 hostname , 可簡寫如下:
[webservers] www[01:50].example.com 或者 [webservers] 10.152.35.[100:110]
4.1.1 主機變量
分配變量給主機,只需要將變量定義在主機的host之后,就可在 playbooks 中使用。如:
[atlanta] host1 http_port=80 maxRequestsPerChild=808 host2 http_port=303 maxRequestsPerChild=909
4.1.2 組變量
也可以定義屬於整個組的變量:
[atlanta] host1 host2 [atlanta:vars] ntp_server=ntp.atlanta.example.com proxy=proxy.atlanta.example.com
4.1.3 把一個組作為另一個組的子成員
可以把一個組作為另一個組的子成員,以及分配變量給整個組使用。這些變量可以給 /usr/bin/ansible-playbook 使用,但不能給 /usr/bin/ansible 使用:
[atlanta] host1 host2 [raleigh] host2 host3 [southeast:children] atlanta raleigh [southeast:vars] some_server=foo.southeast.example.com halon_system_timeout=30 self_destruct_countdown=60 escape_pods=2
這里,southeast有兩個子成員atlanta和raleigh,這樣southeast組里面的變量,可以給子成員使用。
4.1.4 分文件定義 Host 和 Group 變量
在 inventory 主文件中保存所有的變量並不是最佳的方式。還可以保存在獨立的文件中,這些獨立文件與 inventory 文件保持關聯。
假設在inventory文件中有一個主機名為 ‘foosball,主機同時屬於兩個組,一個是 ‘raleigh’,另一個是 ‘webservers’:
[raleigh]
foosball
[webservers]
foosball
那么以下配置文件(YAML 格式)中的變量可以為 ‘foosball’ 主機所用。依次為 ‘raleigh’ 的組變量,’webservers’ 的組變量,’foosball’ 的主機變量:
/etc/ansible/group_vars/raleigh /etc/ansible/group_vars/webservers /etc/ansible/host_vars/foosball
優先級最高的是host_vars中定義的變量,其次組的變量是根據組的名字排序來進行優先級排序的,組名稱靠后的優先級高。
4.1.5 Inventory 參數的說明
通過設置下面的參數,可以控制 ansible 與遠程主機的交互方式:
1)ansible_ssh_host
將要連接的遠程主機名.與你想要設定的主機的別名不同的話,可通過此變量設置。
2)ansible_ssh_port
ssh端口號.如果不是默認的端口號,通過此變量設置.
3)ansible_ssh_user
默認的 ssh 用戶名
4)ansible_ssh_pass
ssh 密碼(這種方式並不安全,我們強烈建議使用 --ask-pass 或 SSH 密鑰)
5)ansible_sudo_pass
sudo 密碼(這種方式並不安全,我們強烈建議使用 --ask-sudo-pass)
6)ansible_sudo_exe (new in version 1.8)
sudo 命令路徑(適用於1.8及以上版本)
7)ansible_connection
與主機的連接類型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默認使用 paramiko.1.2 以后默認使用 'smart','smart' 方式會根據是否支持 ControlPersist, 來判斷'ssh' 方式是否可行.
8)ansible_ssh_private_key_file
ssh 使用的私鑰文件.適用於有多個密鑰,而你不想使用 SSH 代理的情況.
9)ansible_shell_type
目標系統的shell類型.默認情況下,命令的執行使用 'sh' 語法,可設置為 'csh' 或 'fish'.
10)ansible_python_interpreter
目標主機的 python 路徑.適用於的情況: 系統中有多個 Python, 或者命令路徑不是"/usr/bin/python",比如/usr/bin/python
不是 2.X 版本的 Python.我們不使用 "/usr/bin/env" 機制,因為這要求遠程用戶的路徑設置正確,且要求 "python" 可執行程序名不可為 python以外的名字(實際有可能名為python26).
與 ansible_python_interpreter 的工作方式相同,可設定如 ruby 或 perl 的路徑....
4.2 動態inventory
Dynamic Inventory指通過外部腳本獲取主機列表,並按照ansible 所要求的格式返回給ansilbe命令的。
這部分一般會結合CMDB資管系統、zabbix 監控系統、crobble安裝系統、雲計算平台等獲取主機信息。由於主機資源一般會動態的進行增減,而這些系統一般會智能更新。我們可以通過這些工具提供的API 或者接入庫查詢等方式返回主機列表。
4.2.1最簡單示例
由於Ansible在接受腳本動態獲取主機信息時支持的是json格式,這里直接通過一段代碼打印一個段json格式的主機信息:
#!/usr/bin/env python # coding=utf-8 import json host1ip = ['10.212.52.252', '10.212.52.14'] host2ip = ['10.212.52.16'] group1 = 'test1' group2 = 'test2' hostdata = {group1: {"hosts": host1ip}, group2: {"hosts": host2ip} } print json.dumps(hostdata, indent=4)
注:
- 主機部分必須是列表格式的;
- hostdata行,其中的"hosts" 部分可以省略,但如果使用時,必須是"hosts" ,不能是其他如‘‘hostlist’’ 等字符串。
- 腳本中一定要加上解釋器,如 #!/usr/bin/python #!/bin/bash
省略后可以這樣寫:
hostdata = {group1:host1ip, group2:host2ip}
直接執行該段代碼結果如下:
上面定義了兩個主機組,test1組內包含主機10.212.52.252、10.212.52.14,test2組內包含主機10.212.52.16 。ansible可以通過如下方法調用:
4.2.2 復雜示例
在靜態主機配置文件示例中,會有組變量(vars),組之間的包含,如下圖:
如果以上部分想要通過腳本獲取實現,實現后返回的json格式應該如下圖:
像上面這種復雜的返回格式,一般不會用在ad-hoc環境中,多數會用在ansible-playbook 中,應為playbook文件中有時假會涉及到vars 參數的傳參。
4.2.3其他
- ansible -i 參數后調用的腳本並非一定是py文件,也可以是其他腳本輸出的結果,這里做了個簡單的測試:
- -i 參數指定的腳本需要有可執行權限 ,不然會報錯,如下:
[root@361way.com yaml]# ansible -i hostjson.py AA -a 'uptime' ERROR: The file hostjson.py looks like it should be an executable inventory script, but is not marked executable. Perhaps you want to correct this with `chmod +x hostjson.py`?
4.2.4 _meta
如果inventory腳本返回的頂級元素為”_meta”,它可能會返回所有主機的變量,其可以包含一個名為”hostvars”的value,表示每個主機的變量。字典_meta中定義的是主機變量,如:
主機變量並不是Inventory文件中所必需的,所以_meta字典也不是必須生成的。當Inventory腳本中生成_meta字典時,Ansible會將_meta信息存放在緩存中,當任務中需要調用這些主機變量時,會直接從緩存中讀取,而不是調用一次變量就執行一次Inventory腳本。這就大大提高了運行效率。