Kerrigan:配置中心管理UI的實現思路和技術細節
去年寫過一篇文章『中小團隊落地配置中心詳解』,介紹了我們藉助etcd+confd實現的配置中心方案,這是一個對運維友好,與開發解耦的極佳方案,經過了一年多的實踐也確實幫我們解決了配置檔案無版本、難回滾、更新複雜等問題
這套配置中心解決方案的特點是,對整個配置檔案進行管理,而非配置項,且在配置中心修改的配置,客戶端可以實時自動更新。同時藉助於我們自研的配置中心管理UI(kerrigan)還能夠實現記錄修改歷史,快速回滾配置,與線上配置做對比等實用功能
陸續有小夥伴問我能否寫篇文章介紹一下配置中心的管理UI(Kerrigan)的實現,咖啡君就通過本篇文章來介紹Kerrigan的設計思路,以及用到的技術和部分核心程式碼,由於kerrigan有過一次改版,所以介面會與上面文章中的截圖有出入
介面與功能
使用者登陸進入會看到一個簡單的統計頁面,展示配置檔案相關資料
這個實現非常簡單就是對資料庫資料進行查詢統計,都是類似於下邊這樣的語句輸出的結果
Config.objects.all().count()
當點選“我的專案”標籤時,會出現所有的專案,在這裡可以搜尋你要操作的專案,或是新建/匯入專案
當點選“新建/匯入專案”時,可以選擇從CMDB同步專案,或者自己填寫專案名稱新建配置中心中的專案,但由於我們配置中心和CMDB是打通的,配置中心裡的所有專案都來源於CMDB,保證專案資訊一致性,所以新建專案功能並沒有被用到
與CMDB系統的同步是通過http協議進行了,當點選“與CMDB同步”按鈕時,會發送個get請求到cmdb伺服器獲取專案資訊,cmdb採用JWT認證,主要程式碼如下:
headers = { "WWW-Authenticate": "Token", "Content-Type": "application/json", "Authorization": "Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NDgyMjg4MzgsImlhdCI6MTU0ODE0MjQzOCwiZGF0YSI6eyJ1c2VybmFtZSI6ImFkbWluQDE2My5jb20ifX0.oKc0SafgksMT9ZIhTACupUlz49Q5kI4oJA-B8-GHqLA" } requests.get('https://ops-coffee.cn/api/cmdb/project', headers=headers)
在我的專案頁面點選專案時,會進入專案的配置管理頁面,這個頁面列出了專案下的所有配置檔案,也可以通過右上角的“新增配置”按鈕新增配置檔案
當新增配置檔案時,會做三件事情:
- 配置檔案表(Config)新增一條新資料
- 歷史記錄表(History)新增一條新資料,作為歷史版本
- 往etcd裡寫入一條新的KV資料,其中key為:專案+環境+服務+檔名稱的組合,保證在etcd內唯一
操作etcd的程式碼如下:
class EtcdApi:
def __init__(self):
self.client = etcd.Client(
host=str(self.ETCD_HOST),
port=int(self.ETCD_PORT),
username=str(self.ETCD_USER),
password=str(self.ETCD_PASS)
)
def read(self, key):
try:
kx = self.client.read(key)
return {"state": 1, "message": "", "action": kx.action, "key": kx.key, "value": kx.value,
"newKey": kx.newKey, "dir": kx.dir, "_children": kx._children}
except Exception as e:
return {"state": 0, "message": str(e)}
def write(self, key, value):
try:
kx = self.client.write(key, value)
return {"state": 1, "message": "", "action": kx.action, "key": kx.key, "newKey": kx.newKey,
"dir": kx.dir, "_children": kx._children}
except Exception as e:
return {"state": 0, "message": str(e)}
def delete(self, key, recursive=False, dir=False):
try:
if dir:
kx = self.client.delete(key, recursive, True)
return {"state": 1, "message": "", "action": kx.action, "key": kx.key, "newKey": kx.newKey,
"dir": kx.dir, "_children": kx._children}
else:
kx = self.client.delete(key)
return {"state": 1, "message": kx}
except Exception as e:
return {"state": 0, "message": str(e)}
當編輯和刪除配置檔案時,操作與新建類似,修改Config表資料-->Histror表新增新資料-->修改或刪除etcd資料,History表在每次新建或修改配置時都需要新增一條新資料,這裡使用到了Django的訊號Signales來實現,主要程式碼如下:
@receiver(signals.post_init, sender=Config)
def migrate_notify_init(instance, **kwargs):
instance.old_content = instance.content
@receiver(signals.post_save, sender=Config)
def migrate_notify_post(instance, created, **kwargs):
_t = Setting.objects.get(key='enable_etcd')
# 每次新建或者content變更都往歷史表裡插入一條歷史資料
if created or instance.old_content != instance.content:
History.objects.create(
config=instance,
user=instance.user,
content=instance.content
)
除了History表操作之外,對於etcd的操作以及下邊要說到的釋出功能也是在signales裡完成的,signals可以簡化程式碼強化邏輯
當點選“編輯”按鈕後,會進入配置檔案編輯頁面,在這裡可以修改、儲存或釋出配置檔案,也可以拿當前配置檔案與已釋出配置檔案做對比
這裡“儲存”和“釋出”的區別在於,儲存只會將配置檔案儲存在Kerrigan內,不會修改etcd裡的資料,從而實現客戶端不更新,而釋出會直接修改etcd裡的資料,客戶端能夠直接更新,對於未釋出的配置檔案,當你點選配置檔案時會有如下的提示,你可以對比或者釋出
判斷是否釋出主要是在Config表裡加入了is_published
欄位,同樣通過signals的post_save訊號在每次儲存時檢查這個欄位,如果為True,則修改對應etcd的值,否則不處理
@receiver(signals.post_save, sender=Config)
def migrate_notify_post(instance, created, **kwargs):
...
# 判斷狀態為釋出且開啟了etcd,則更新資料到etcd
if instance.is_published:
_r = EtcdApi().write(key, instance.content)
if _r.get('state') == 0:
raise '寫入key:%s失敗' % (key)
系統中多次出現“對比”功能,都指的是當前配置檔案和已釋出配置檔案的對比,通過對比可以清晰的看出修改的內容,對比結果展示如下
對比功能主要用到了difflib模組,主要程式碼如下:
difflib.HtmlDiff().make_file(src_value, diff_value, context=True, numlines=3)
每一次的新增或者修改都會往History表裡寫入一條新資料,“歷史版本”便是直接讀的History表,展示出誰在什麼時間修改了什麼內容
當點選歷史版本時可以檢視此版本的配置檔案內容,同時在必要的時候回滾,有了歷史版本的內容,回滾也只是將歷史內容覆蓋到etcd
至此,Kerrigan介紹完成,其最主要的功能是通過web瀏覽器來操作etcd裡的KV資料,在此基礎上做了擴充套件,對每一次的修改都做了記錄,以實現實用的儲存、釋出、歷史、回滾等功能
最後再回顧一下整個配置中心的工作流程,配置管理員通過Kerrigan來新增或修改配置檔案,Kerrigan記錄修改,同時將修改同步至etcd,客戶端上的confd服務在檢測到etcd對應key的資料發生變化時,會自動拉取資料覆蓋至本地配置檔案,然後配合check_cmd
和reload_cmd
指令對配置檔案進行檢查和過載,更多細節原理回顧文章『中小團隊落地配置中心詳解』
相關文章推薦閱讀:
- 我們自研的那些Devops工具
- 中小團隊基於Docker的devops實踐