手頭的Proxmox VE集群和節點越來越多,需要考慮統一管理了,先定一個小目標——集中狀態監控。
以前寫過檢測ceph并用釘釘報警的bash腳本,這次換上洋氣的方式,用python來通過pve的api獲取其狀態信息。
首先參考proxmox官方的api(實際上自己弄個外殼全部調用了你就可以“自主研發”一個云計算虛擬化平臺,業內普遍現狀,你懂的。)
https://pve.proxmox.com/pve-docs/api-viewer/
先在瀏覽器里面測試一下:
比如你原來使用https://192.168.1.1:8006管理pve,在瀏覽器上再開一個新的tab,輸入https://192.168.1.1:8006/api2/json/,就可以看到json格式的文檔頁面了,像下面這樣:
今天我們只要監控幾個狀態信息,就看這三個:
名稱 | api URL |
PVE節點狀態 | https://ip:port/api2/json/nodes |
PVE集群狀態 | https://ip:port/api2/json/cluster/status |
CEPH集群狀態 | https://ip:port/api2/json/cluster/ceph/status |
為了安全,pve要求每次訪問都使用ticket,所以我們需要先獲取一個ticket,把它放入Cookie,嵌入header,然后才能發起訪問。
作為野生程序猿,我們先不考慮日志(一律用print()),也不考慮類(燒腦),更不考慮多線程(多個集群的時候能成倍地降低采集時間)。
直接上簡單明了的兩個函數:一個獲取ticket,一個根據url獲取信息。然后調用兩個函數,獲取狀態信息。
運行函數之前還要準備基本的認證信息,最后這個樣子:
#coding=utf-8 #!/usr/bin/python3#!/usr/bin/python3#?huky0924@aliyun.com# 參考https://pve.proxmox.com/pve-docs/api-viewer/ #?20200612?檢查PVE運行狀態import os, sslimport urllib.request, json#?獲取pve的ticketdef getTicket(urlBase, user, password): try: url = urlBase + 'access/ticket' params = {'username': user, 'password': password} post = urllib.parse.urlencode(params).encode(encoding='UTF8') headers = {"Accept": "application/json"} request = urllib.request.Request(url, post, headers)????????response?=?urllib.request.urlopen(request) fields = json.loads(response.read().decode('utf-8')) ticket = fields['data']['ticket']????????return?ticket except Exception as e: print('獲取集群'+ alias +'認證ticket錯誤!') print(e) os._exit(1)# 利用ticket從相應的api獲取信息def getInfo(urlExt, ticket): try: url = urlBase + urlExt print('') print('從' + url + '獲取信息') headers = {"Accept": "application/json", "Cookie": "PVEAuthCookie=%s" % ticket} request = urllib.request.Request(url) for k,v in headers.items(): request.add_header(k, v) response = urllib.request.urlopen(request) fields = json.loads(response.read().decode('utf-8'))????????return?fields['data'] except Exception as e:????????print('從'?+?url?+?'獲取信息錯誤:?'?+?e)if?__name__?==?'__main__': #因為使用自簽名的ssl證書,需要允許 ssl._create_default_https_context = ssl._create_unverified_context????#為了多個集群信息用數組表示其認證信息,[別名 ip地址?端口?用戶名及其認證模式?密碼]。????#實際操作中使用字典,別名作為鍵,后面的值作為值,為了安全密碼要手動輸入并加密????pveLogin?=?['pve集群1',?'192.168.2.11',?8006,?'root@pam',?'password']????alias?=?pveLogin[0] host = pveLogin[1] port = pveLogin[2] user = pveLogin[3] password = pveLogin[4] urlBase = 'https://{}:{}/api2/json/'.format(host, port) pveTicket = getTicket(urlBase, user, password)????statusNodes?=?getInfo('nodes',?pveTicket) print(statusNodes) statusCeph = getInfo('cluster/ceph/status', pveTicket) statusCephs = statusCeph['health'] print(statusCephs['status'])
運行獲取的信息再提取就可以了,如最后的ceph狀態