CMDB在按業務、叢集、模組、IP 納管了基礎設施資源後,如何為上層應用提供資料支撐,我想到的場景如下:
從以上幾個場景可以看出,CMDB給我們提供瞭解決問題的基本思路。
本章我們就從為CI/CD構建提供動態化引數的實際案例來介紹下。
在CI/CD中構建一項job需要目標主機的IP,我們可以通過以下幾種方式獲得:
以上幾種方式都需要提前知道目標主機的IP,對執行構建人員來說很不友好。那麼我們能不能參照DNS的套路,通過特定的名稱查詢CMDB來獲取IP呢? 因此,jenkins從CMDB中根據模組名,動態獲取模組對應IP的解決方案就有了。
通常情況下,較大的企業都會基於CMDB配套企業服務匯流排(ESB),來給各個平臺提供服務。顯然,我們的小企業是不具備這種能力的。因此我們需要藉助CMDB API,自行將其封裝成標準格式,然後通過Jenkins 呼叫API 來提供動態化引數,實現引數化構建。
整理流程如下:
通常情況下CMDB 自帶的API 返回的結果資料比較多,上層的應用呼叫需要進行層層過濾篩選才能獲得最終的結果。
例如藍鯨CMDB 根據模組查詢IP 介面,獲取的結果資料為:
# 請求cmdb api
curl http://paas.bk.net/api/c/compapi/v2/cc/search_host/ -d
{
"bk_app_code": "bk-test",
"bk_app_secret": "62bc9c22-334d-4fcd-9523-991662163b67",
"bk_username": "admin",
"condition": [
{
"bk_obj_id": "biz",
"fields": [],
"condition": [
{
"field": "bk_biz_name",
"operator": "$in",
"value": ["生產環境"]
}
]
},
{
"bk_obj_id":"module",
"fields":[""],
"condition":[
{
"field": "bk_module_name",
"operator": "$in",
"value": ["test"]
}
]
}
],
"page": {
"start": 0,
"limit": 1,
"sort": "bk_host_id"
},
"pattern": ""
}
# 返回資料
{
"message": "success",
"code": 0,
"data": {
"count": 2,
"info": [
{
"host": {
"bk_cpu": null,
"bk_isp_name": null,
"host_host_manageip": "",
"bk_os_name": "",
"bk_province_name": null,
"bk_host_id": 1861,
"import_from": "3",
"bk_os_version": "",
"bk_disk": null,
"operator": null,
"create_time": "2019-12-08T14:24:04.924+08:00",
"bk_mem": null,
"bk_host_name": "",
"bk_host_innerip": "10.168.202.58",
"bk_host_type": "2",
"bk_comment": "",
"bk_host_jiwei": "",
"bk_host_band": "",
"bk_os_bit": "",
"bk_outer_mac": "",
"bk_host_jigui": "",
"bk_asset_id": "",
"bk_service_term": null,
"bk_cloud_id": [
{
"bk_obj_name": "",
"id": "0",
"bk_obj_id": "plat",
"bk_obj_icon": "",
"bk_inst_id": 0,
"bk_inst_name": "default area"
}
],
"bk_sla": null,
"bk_cpu_mhz": null,
"bk_service_limit": null,
"bk_host_outerip": "",
"bk_state_name": null,
"bk_os_type": null,
"bk_host_stat": "1",
"bk_mac": "",
"bk_bak_operator": null,
"bk_supplier_account": "0",
"bk_host_model": "",
"bk_sn": "",
"bk_cpu_module": ""
},
"set": [],
"biz": [
{
"bk_biz_id": 3,
"language": "1",
"life_cycle": "2",
"bk_biz_developer": "",
"bk_biz_maintainer": "admin",
"bk_biz_tester": "",
"time_zone": "Asia/Shanghai",
"default": 0,
"create_time": "2020-12-09T11:12:04.449+08:00",
"bk_biz_productor": "",
"bk_supplier_account": "0",
"operator": "admin",
"bk_biz_name": "生產環境",
"last_time": "2021-11-29T09:17:09.837+08:00",
"bk_supplier_id": 0
}
],
"module": [
{
"default": 0,
"TopModuleName": "生產環境",
"bk_module_id": 1358
}
]
}
]
},
"result": true,
"request_id": "02ed84f480e0412980923cb1959973ba"
}
其中從請求的json資料可以得出查詢條件:
返回的結果包含了很多資訊,但是我們只想要test模組所部署的IP:10.168.202.58
,其他資訊可以忽略。如果直接使用原生API ,我們要花費很大的精力在解析json資料上。因此我們需要單獨封裝一個API,功能需求不變,即根據業務、模組查詢IP。
# 請求封裝後的api
curl http://10.168.209.88:8080/cmdb/getHost/?module=test&env=pro
{"status": 200, "module": "test", "env": "pro", "hosts": ["10.168.202.58"]}
通過簡單的引數查詢,即可得到我們想要的結果,後面只需愉快的接入了。
Jenkins我們以管理應用的job為例,功能為啟動、停止、重新啟動指定應用。
在引數化構建過程中,我們只需輸入應用名,就可以獲得該應用名所對應的部署IP,後面的一系列操作就可以基於此IP按需實現。
其中:
由於Jenkins 是基於grovvy開發,因此我們需要在Groovy Script
處呼叫封裝的API ,實現根據模組名動態獲取IP的功能
,得到的結果以Single Select
即單選框的形式展現。
另外,Referenced parameters 是將實際輸入的APP_NAME引數指,傳遞到Groovy Script中,實現按需呼叫。
通過CMDB給Jenkins提供動態引數,使CMDB成為資料孤島的可能性進一步降低,同時也給Jenkins帶來了另一種最佳實踐。這種方式類似於DNS,我們不需要知道IP地址,只需知道應用名就可以快速獲取IP進行操作了。