開發了一個 Copilot 用來處理運維故障
本篇內容主要來自內部的一次分享,也是最近工作的一些總結。
- 常見的故障處理流程
如上圖是一次典型的運維異常處理流程。
按照時間線,有如下關鍵時間點:
-
發生故障
-
發現故障
-
響應故障
-
定位故障
-
恢復故障
發生故障到發現故障,指的是被系統檢測到,主要涉及到指標的採集週期、檢測週期。如果按照 15 s 的採集週期,檢測週期爲 1 min,那麼發現故障需要時間級別就是幾十秒到幾分鐘級別。
發現故障到響應故障指的是,接收到告警之後,人開始着手處理的時間。白天、晚上的區別就很大,白天工作時間段和非工作時間段區別也很大。晚上,大家都在休息,可能幾個小時都沒人響應告警;而在白天,運維人員在工作時間段分鐘級別就能快速切入,開始定位故障。
響應故障到定位故障指的是,要找出故障的原因。這部分的時間與人的經驗、能力密切相關,入職不久的新人,可能得幾個小時都不一定能定位到故障;而熟悉基礎設施的老運維,可能幾分鐘就能快速找到問題所在。
定位故障到恢復故障指的是,要修復故障,恢復線上的 SLO。這部分和上面的一部分類似,但對人的能力要求不同,比如程序有 Bug,運維能快速定位故障,但修復還是得研發同學介入。
整體上就是這五個環節,四個時間段,其實後面還需要對 SLO 進行觀測、覆盤、優化、混沌實驗驗證等,但不涉及處理故障的流程。
- 大模型能參與的環節
如上圖,按照我的分析主要在四個時間點可以介入,分別是發現故障、響應故障、定位故障、處理故障。
2.1 發現故障
發現故障時,人還沒來得及響應。
如果大模型能夠自動介入,響應告警,能獲得最快的響應速度,獲得最大的收益,極大縮短平均故障處理時間 MTTF。
但發現故障時,立即讓大模型介入也是最難的。難點就在於,需要開發一個 AI Agent 自動的響應告警信息,自動的收集觀測的指標,自動調用平臺接口,甚至登錄機器嘗試處理故障,驗證是否被修復了,循環往復。
如果你寫過代碼或者智能體就會知道,這件事挺難的,而如果你覺得很簡單,可能就是高估了大模型的智能水平,低估了現實問題的複雜度。
2.2 響應故障
響應故障時,大模型如果能立即對故障進行初步的分析,縮小故障的處理範圍有利於加快定位故障的速度。
大模型預分析,依賴於平時的故障處理資料,這需要我們在每次發生故障時,詳細地記錄和分析故障的各個方面。
只有具備足夠的故障數據根因數據積累,纔能有效藉助大模型縮小故障範圍。
2.3 定位故障
現在的可觀測性又擴充了,新增了事件,加上之前的監控指標、日誌、鏈路,數據源是多了,但是每次定位故障時,需要查詢的平臺也多了。
大模型可以幫我們有效縮短查詢這些可觀測性指標的時間。
同時,根據一些關鍵字,還能檢索文檔庫,分析故障原因,給出一些修復方案,節省我們上網檢索的時間。
2.4 處理故障
大模型也可以用來直接處理故障。
回憶一下,我們經常是怎麼處理故障的。重啓一下 Deployment、重啓一下 Kubelet、調整一下路由配置、換一個節點試試等。這些通常就是一條命令、一次接口調用、一次按鈕點擊。
讓大模型幫我們執行這些操作,非常省時省事兒。
2.5 小結
大模型能夠參與的環節其實很多,但從難易程度上看,大模型越早介入難度越大,越晚介入易於實現。
故障早期涉及的範圍太大,大模型難以有效捕獲到故障的關鍵根因,而人的經驗、靈活性、自主學習能力會體現出優勢。
最終落地大模型卻要反着來,先用大模型介入後期的處理,逐步積累相關的文檔和案例,再將介入的時間點往前推移,直至能夠完全實現 AI Agent 自動化的響應故障。
- 使用大模型處理故障時的挑戰點
3.1 文本如何轉換爲運維操作
我們熟知的大模型服務,典型的輸入和輸出都是文本、圖片、視頻。
如果將這些靜態的輸出,轉換爲一個具體的操作,一個命令的執行,一個運維的操作,這是我們首先要面對的問題。
3.2 大模型提取的信息不穩定
對於程序來說,確定性是非常重要的,但大模型的魅力就是不確定性、多樣性。着手開始寫大模型應用很容易遇到這些問題:
-
大模型不理解意圖,頻繁道歉
-
輸出的格式不對
-
輸出的參數缺失
-
...
類似的問題會有很多,我們通常會從以下幾個方面破局:
-
提示詞
-
重試
-
微調模型
當然,這次我想提的另外一個關鍵點,從應用設計的層面來解決。
3.3 怎麼快速接入場景
快速驗證、快速迭代應該深入每個工程師的基因中。怎樣快速對接上各種場景,讓我們的方案看起來不那麼離譜,甚至感覺有點效果很重要。
這裏我選的就是日常的一些瑣事:
-
處理告警事件
-
輔助日常運維
但這兩大類事情的子項非常多,幾十種,甚至上百種場景,我想到的是插件編排的思路。如果能抽象出原子操作,拼接原子構成流水線,就能夠覆蓋無數種場景。
- 落地關鍵技術 - Ops 簡介
每個領域可能都需要一個類似 Ops 的項目,提供大模型驅動領域的能力。下面對 Ops 進行簡單介紹。
- OpsObject
通過 CRD 存儲操作對象,管理集羣、主機對象。
- Core
核心操作,實現文件分發和腳本執行的能力。
- Task
封裝、組合各種操作,輕量級的編排能力。
- Tools
對外提供三種操作入口
Ops 項目是對接運維能力的關鍵。我之前的文章中已經多次介紹,感興趣的話可以前往 https://www.chenshaowen.com/ops/ 查看詳情。
4.1 使用示例 - 查看對象
- 查看運維對象
可以看到集羣的節點數、證書過期剩餘天數等關鍵信息。
可以看到節點配置、GPU 卡的亞實時狀態。
4.2 使用示例 - Opscli
-
shell 用於在主機上執行腳本
-
file 用於在主機與 S3、文件服務、鏡像之間傳輸文件
-
task 用於編排多個 shell\file 操作
-
支持僅提供 kubeconfig 憑證,在指定節點上執行命令
-
也支持 Kubectl 中的 SA 鑑權
4.3 使用示例 - Web UI
通過更簡單的方式使用 Ops 的核心能力:
-
Server 提供接口能力
-
Web 有提供一個簡單管理的 UI
4.4 使用示例 - Task
Task 提供模板的能力,只需要先定義一個任務。
apiVersion: crd.chenshaowen.com/v1
kind: Task
metadata:
name: cron-clear-disk
namespace: ops-system
spec:
desc: cron to create clear disk
selector:
managed-by: ops
typeRef: host
steps:
- name: clear > 100M log
content: find /var/log -type f -name "*.log" -size +100M -exec rm -f {} \; 2>/dev/null || true
- name: clear jfs cache
content: |
find /data/jfs/cache2/mem -maxdepth 1 -type d -atime +15 -exec rm -rf {} + 2>/dev/null || true
find /var/lib/jfs/cache -maxdepth 1 -type d -atime +15 -exec rm -rf {} + 2>/dev/null || true
find /var/lib/jfs/cache2 -maxdepth 1 -type d -atime +15 -exec rm -rf {} + 2>/dev/null || true
接着在 TaskRun 中引用這個任務就能夠執行。
apiVersion: crd.chenshaowen.com/v1
kind: TaskRun
metadata:
name: cron-clear-disk
namespace: ops-system
spec:
ref: cron-clear-disk
- Copilot 的設計
Copilot 是我們目前落地大模型處理運維故障的主要形態。通過交互對話的方式,讓大模型參與到故障處理的過程中,按照前面的思路,先介入故障處理的後期,再落地前期,採用逐層積累、推進的策略。
5.1 關鍵步驟
核心的思路:
-
通過 Ops 項目對 Copilot 提供運維的操作能力
-
通過流水線 pipeline 提供操作場景對接能力
核心的步驟:
第一步,大模型幫我們選擇一條流水線 第二步,大模型幫我們從故障的上下文中提取運行流水線的參數
這與 function_call 的功能類似,只不過調用的不是 function 而是 pipeline。使用 pipeline 對接場景的好處多多,不僅能夠處理更加複雜的任務,還能不被模型功能限制。
目前只要支持 OpenAI 接口的大模型,都能夠對接上 Copilot 的 pipeline。只不過由於沒有經過運維故障處理領域的微調,使用的模型參數量不能太少,對理解能力有一定要求。
5.2 流水線的設計
流水線的設計目標是:
-
便於大模型識別意圖,選中一條流水線執行
-
便於擴展,覆蓋更多場景
-
便於大模型自行組裝 tasks 形成新的 pipeline,爲實現 AI Agent 提供可行路徑
我很熟悉 CICD 等編排系統,很容易就用代碼寫出這個 pipeline 對象和具體執行邏輯。
目前已經定義了:
-
task 95 個
-
pipeline 20 個
同時,由於 task、pipeline 都是 CR 對象,只需要編寫 Yaml 就能夠快速對接場景,十分方便。
最終提交給大模型的輸入是這樣:
Please select the most appropriate option to classify the intention of the user.
Don't ask any more questions, just select the option.
Must be one of the following options:
- xxx-es-log-analysis(Analysis - xxx ES日誌分析告警過去20秒異常日誌超過閾值)
- xxx-grafana-alert-node-disk-pressure(Analysis - 節點異常NodeDiskPressure)
- xxx-grafana-alert-pod-crashloopbackoff(Analysis - xxx Grafana告警Pod處於CrashLoopBackOff狀態持續超過1分鐘)
- xxx-grafana-alert-pod-error-request(Analysis - xxx Grafana告警Pod異常請求比例大於10%)
- xxx-grafana-alert-pod-pending(Analysis - xxx Grafana告警 Pod處於Pending狀態持續超過十分鐘)
- xxx-grafana-alert-pod-restart(Analysis - xxx Grafana告警Pod重啓次數大於2)
- xxx-grafana-node-status(Analysis - xxx Grafana告警 (平臺)節點狀態不可用)
- cluster-clear-disk(磁盤使用率超過閾值時清理磁盤)
- cluster-cordon-node(禁用\屏蔽集羣中的某個節點)
- cluster-restart-pod(重啓、刪除集羣中的某一個 Pod)
- cluster-uncordon-node(恢復集羣中的某一個節點)
- collect-gpu-log(Collect - 蒐集 GPU 的相關日誌)
- get-pod(查看 Pod 信息、狀態)
- grafana-alert-pod-restart(Analysis - xxx Grafana告警 Pod 重啓次數大於2)
- list-clusters(列出、查看所有的集羣, 哪些指令、功能)
- list-nodes(查看、列出某個集羣的所有節點)
- list-pipelines(查看、列出所有的流水線)
- restart-containerd(重啓 containerd)
- restart-fabricmanager(重啓 fabricmanager)
- restart-kubelet(重啓 kubelet)
5.3 變量的設計
變量的設計如此重要,只有當你真正寫過大模型應用時,纔會由此體會。
首先是參數的定義:
-
默認值
-
描述
-
正則
-
是否必須
-
枚舉
-
示例
-
固定值
接着是參數的優先級:
-
task 固定值
-
pipeline 固定值
-
運行提取值
通過變量的設計,我們可以獲得如下好處:
-
通過變量定義提高抽參數準確性
-
task 固定值提高執行成功率 e.g. 只運行在 master 節點
-
pipeline 固定值提供敏感信息 e.g. 上傳 S3 的 ak\sk 值
下面是我提交給大模型的輸入:
The cluster-clear-disk pipeline is used to 磁盤使用率超過閾值時清理磁盤.
It requires the following parameters(if enum provided, choose one of them):
- nameRef {"required":true,"enums":["cluster-1","cluster-2","cluster-3","cluster-4","cluster-5"]}
- nodeName {"regex":"\b[a-zA-Z-]*node[a-zA-Z-]*\b","required":true}
- typeRef {"value":"cluster","required":true}
- 主動發現故障,讓飛輪轉起來
如果只是被動等待故障,要到猴年馬月才能積累足夠的數據,最好的辦法永遠是主動出擊。
巡檢能夠主動的發現一些潛在問題,在故障發生之前,提前預警。
目前我們的巡檢已經涉及多個方面,設備層、驅動層、系統層等。新加入集羣的節點也可以自動加入巡檢中。
巡檢的配置也非常簡單,還記得上面的 TaskRun 對象嗎。
apiVersion: crd.chenshaowen.com/v1
kind: TaskRun
metadata:
name: cron-clear-disk
namespace: ops-system
spec:
crontab: 0 0 * * *
ref: cron-clear-disk
只需要在 TaskRun 中加上 crontab: 0 0 * * * 就可以開始週期性的執行了,這個示例中就是每天八點清理磁盤。而巡檢任務只需要在 Task 中寫了一些巡檢的邏輯,並觸發告警通知、推送預警事件即可。
- 典型案例
可能上面提到很多內容,還缺少一個直觀的感受,下面我就來介紹一個典型的案例。
AI 加速卡工作在高溫環境中,經常會有各種異常和報錯。不同於 CPU 會大幅降頻自我保護,AI 加速卡會掉卡(系統層、驅動層不了硬件的狀態),直接無法使用。千卡訓練,平均每天至少一張卡異常。
當 GPU 掉卡時,就需要報修,讓雲廠的工程師在現場解決,下面是傳統的報修流程。
現在只需要在 IM 中 at Copilot 就行。
處理時間從幾十分鐘減少到了幾分鐘,同時也增強的安全性,避免 AK/SK 信息泄露。
除了這個在流程、時間上能極大提高效率的案例之外,我還比較看中的是,現在處理故障不受時間、是否能遠程辦公等條件約束,隨時隨地都能處理。
- 總結
本篇介紹了我在使用大模型處理運維故障的一些實踐,希望對大家設計和開發大模型應用有所幫助。主要內容如下:
-
故障處理流程的時間線以及大模型能參與的環節
-
大模型幾乎能參與全部的故障處理環節,包括故障的發現、響應、定位、處理
-
着手使用大模型處理故障時,可以從距離解決故障最近的環節開始,逐步向前推進
-
如果你也在從事運維相關的工作,可以試試 https://github.com/shaowenchen/ops 項目
-
function_call是一種思路,不要侷限在function還可以是 pipeline、workflow 等任意可編程對象 -
開發大模型應用時,對變量的描述極其重要
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Wiff1MuAGXh7HhZmcDEcMg