第2天:Ansible-Inventory管理
在Ansible中,將可管理的服務器集合成為Inventory。因此,Inventory管理便是服務器管理。
hosts文件位置
我們知道,Ansible在執行操作時,首先需要確定對哪些服務器執行操作。默認情況下,Ansible讀取/etc/ansible/hosts文件中的服務器配置,獲取需要操作的服務器列表。Ansible定義與獲取服務器列表的方式比這個要靈活的多。
在Ansible中,有三種方式指定hosts文件:
1)默認讀取/etc/ansible/hosts文件
2)通過命令行參數的 -i 指定hosts文件
3)通過ansible.cfg文件的inventory選項
ansible命令的--list-hosts選項用來顯示匹配的服務器列表,我們可以通過該參數驗證服務器的匹配情況
[heboan@c1 ~]$ ansible test --list-hostshosts (2):192.168.88.2192.168.88.3我們在家目錄下創建個hosts,然后用-i指定這個hosts
[heboan@c1 ~]$ cat hosts [test] 192.168.20.1 192.168.20.2 [heboan@c1 ~]$ [heboan@c1 ~]$ ansible test -i hosts --list-hostshosts (2):192.168.20.1192.168.20.2 [heboan@c1 ~]$ [heboan@c1 ~]$ ansible test --list-hosts #默認情況hosts (2):192.168.88.2192.168.88.3我們也可以在ansible.cfg中通過inventory選項指定hosts文件路徑
[heboan@c1 ~]$ cat /etc/ansible/ansible.cfg [defaults] remote_port = 2202 remote_user = heboan inventory = /home/heboan/hosts [heboan@c1 ~]$ [heboan@c1 ~]$ ansible test --list-hostshosts (2):192.168.20.1192.168.20.2靈活定義hosts文件內容
Ansible支持更加靈活的方式定義hosts文件,例如將服務器進行分組,以便對不同的服務器類型進行不同的操作, 如下
mail.heboan.com #不屬于任何一個組 [webservers] foo.heboan.com bar.heboan.com[dbserver] one.heboan.com two.heboan.com three.heboan.com在服務器匹配時,all或星號是一個特殊的名稱,用于匹配所有的服務器
[heboan@c1 ~]$ ansible '*' --list-hostshosts (6):mail.heboan.comfoo.heboan.combar.heboan.comone.heboan.comtwo.heboan.comthree.heboan.com 匹配所有服務器使用組名,匹配該組所有服務器
[heboan@c1 ~]$ ansible dbserver --list-hostshosts (3):one.heboan.comtwo.heboan.comthree.heboan.com 匹配組服務器?Ansible也可以定義一個組,這個組下面定義的不是服務器列表,而是包含其他組的名稱, 通過":children"的方式來聲明
[common:children] webserver dbserver如果我有一批服務器,并且這些服務器有相同的模式,我們可以向下面這樣定義服務器
[webservers] web[1:3].heboan.com bar.heboan.com[dbservers] db[a:d].heboan.com靈活匹配hosts文件內容
| 規則 | 含義 |
| 192.168.88.2或c2.heboan.com | 匹配模板IP地址或服務器名,如果有多個ip或服務器,使用":"分隔 |
| webservers | ?匹配目標組為webservers,多個組使用":"分隔 |
| ?all或'*' | ?匹配所有服務器 |
| ?webservers:!dbservers | ?匹配在webservers中,不在dbservers組中的服務器 |
| ?webservers:&dbservers | ?匹配同時在webservers組以及在dbservers組中的服務器 |
| ?*.example.com或192.168.* | ?使用通配符匹配 |
| ?webservers[0],webservers[1:],webservers[-1] | ?使用索引或切片操作的方式匹配組中的服務器 |
| ?~(web|db).*example.com | ?以~開頭的匹配,表示使用正則表達式匹配 |
動態Inventory獲取
從前面的介紹可以看到,Ansible提供給你了非常靈活的方式來編寫hosts文件,可以節省不必要的時間浪費、提高工作效率。此外,Ansible還可以通過調用云計算服務的API,編寫自定義腳本的方式獲取服務器列表。如果公司有使用CMDB系統來管理服務器,那么,我們可以通過讀取CMDB數據庫中的記錄得到服務器列表。
既然 我們可以通過調用云計算系統的API,或者讀取CMDB系統的數據庫獲取服務器列表,那么,再將服務器地址寫入hosts文件就顯得比較冗余,且沒有任何必要。
一個動態獲取服務器列表的腳本必須支持如下兩個命令行參數:
1)--host=<hostname>: 用于列出某臺服務器的詳細信息
2)--list:用于列出群組以及群組中的服務器
例如,我們才CMDB系統庫中包含了一些服務器的信息, 如果將這些服務器信息從數據庫中拷貝到hosts文件中,效果如下:
[root@c1 ~]# cat /etc/ansible/hosts [test] 192.168.88.2 ansible_user=heboan ansible_port=22 192.168.88.3 ansible_user=heboan ansible_port=22[uat] 192.168.88.4 ansible_user=heboan ansible_port=22按照Ansible的約定,我們需要編寫一個動態腳本來獲取服務器的列表,這個腳本必須支持--list選項和--host選項。其中,--list選項以json的格式返回以組名為key,服務器列表為value的數據。--host返回一個字典,該字典中包含了這個服務器的詳細信息,如下:
[heboan@c1 ~]$ python hosts.py --list {"test": ["192.168.88.2", "192.168.88.3"], "uat": ["192.168.88.4"] } [heboan@c1 ~]$ [heboan@c1 ~]$ python hosts.py --host='192.168.88.2' {"ansible_port": "22", "asnible_user": "heboan" }接下來我們來看下如何編寫這樣一個動態獲取服務器的腳本。假設。我們的CMDB數據庫中,存在一張名為hosts的表:
CREATE TABLE hosts( id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, host varchar(15) DEFAULT NULL, groupname varchar(15) DEFAULT NULL, username varchar(15) DEFAULT NULL, port int(11) DEFAULT NULL );INSERT INTO hosts values(null, '192.168.88.2', 'test', 'heboan', 22); INSERT INTO hosts values(null, '192.168.88.3', 'test', 'heboan', 22); INSERT INTO hosts values(null, '192.168.88.3', 'uat', 'heboan', 22);下面是動態獲取服務器列表的程序
#!/usr/bin/python #_*_ coding: UTF-8 _*_import argparse import json from collections import defaultdict from contextlib import contextmanager import pymysqldef to_json(in_dict):return json.dumps(in_dict, sort_keys=True, indent=4)@contextmanager def get_conn(**kwargs):conn = pymysql.connect(**kwargs)try:yield connfinally:conn.close()def parse_args():parser = argparse.ArgumentParser(description='Heboan Inventory Module')group = parser.add_mutually_exclusive_group(required=True)group.add_argument('--list', action='store_true', help='list active servers')group.add_argument('--host', help='List details about the specific host')return parser.parse_args()def list_all_hosts(conn):hosts = defaultdict(list)with conn as cur:cur.execute('select * from hosts')rows = cur.fetchall()for row in rows:no, host, group, user, port = rowhosts[group].append(host)return hostsdef get_host_detail(conn, host):details = {}with conn as cur:cur.execute("select * from hosts where host='{}'".format(host))rows = cur.fetchall()if rows:no, host, group, user, port = rows[0]details.update(asnible_user=user, ansible_port=port)return detailsdef main():parser = parse_args()with get_conn(host='127.0.0.1', user='root', password='root', db='cmdb' ) as conn:if parser.list:hosts = list_all_hosts(conn)print(to_json(hosts))else:details = get_host_detail(conn, parser.host)print(to_json(details))if __name__ == '__main__':main() hosts.py為了讓我們動態獲取服務器列表程序能夠應用在Ansible中,需要為hosts.py加上可執行權限。其他使用方式和普通的hosts文件一模一樣。
定義服務器變量
...
?
轉載于:https://www.cnblogs.com/sellsa/p/9946448.html
總結
以上是生活随笔為你收集整理的第2天:Ansible-Inventory管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#反射基础理解1(转)
- 下一篇: 2018年11月12日