偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

AIOps系列 | 開發(fā) K8s GPT 故障診斷工具

人工智能
我們使用一個(gè)?map[string][]string?來保存 pod 的事件和日志信息,然后通過?client-go?獲取?warning?級別的事件,最后過濾需要的?pod?事件以及?pod?相關(guān)信息,然后繼續(xù)通過?client-go?獲取對應(yīng)?pod?的日志,然后把這些信息放到?map?中。

前面我們介紹了 《開發(fā) K8s Chat 命令行工具》,實(shí)現(xiàn)了通過和 Kubernetes 進(jìn)行交互的方式進(jìn)行運(yùn)維,雖然文章中所描述的功能比較簡單,但是可以以此進(jìn)行擴(kuò)展,豐富功能。

那本章,我們將在 《開發(fā) K8s Chat 命令行工具》的基礎(chǔ)之上,增加 Kubernetes 故障診斷工具,其主要功能點(diǎn)是:

  • 獲取集群的 event 時(shí)間,特別關(guān)注 warning 級別事件
  • 然后進(jìn)入對應(yīng)的 pod 獲取日志
  • 大模型結(jié)合事件和日志進(jìn)行分析,得出解決問題的建議

當(dāng)然,這里也只是起到一個(gè)拋磚引玉的作用,提供簡單的思路,可以自行擴(kuò)展。

開發(fā)過程

(1)首先使用 cobra-cli 新增一個(gè) analyze 命令

cobra-cli add analyze

(2)然后在 analyze 下面添加一個(gè)子命令 event,專門用于分析事件

cobra-cli add event -p 'analyzeCmd'

(3)設(shè)計(jì)一個(gè)方法 getPodEventsAndLogs 用于獲取 K8s 的事件和日志

// int64Ptr 輔助函數(shù),用于創(chuàng)建 int64 指針
func int64Ptr(i int64) *int64 {
 return &i
}

func getPodEventsAndLogs() (map[string][]string, error) {
 // 創(chuàng)建 Kubernetes 客戶端
 clientGo, err := utils.NewClientGo(kubeconfig)
 if err != nil {
  return nil, fmt.Errorf("創(chuàng)建 Kubernetes 客戶端失敗: %v", err)
 }

 // 存儲每個(gè) Pod 的事件和日志信息
 result := make(map[string][]string)
 processedPods := make(map[string]bool) // 避免重復(fù)處理同一個(gè) Pod

 // 獲取 Warning 級別的事件
 events, err := clientGo.Clientset.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
  FieldSelector: "type=Warning",
 })
 if err != nil {
  return nil, fmt.Errorf("獲取事件失敗: %v", err)
 }

 for _, event := range events.Items {
  // 只處理 Pod 相關(guān)的事件
  if event.InvolvedObject.Kind != "Pod" {
   continue
  }

  podName := event.InvolvedObject.Name
  namespace := event.InvolvedObject.Namespace
  message := event.Message
  podKey := fmt.Sprintf("%s/%s", namespace, podName)

  // 避免重復(fù)處理同一個(gè) Pod
  if processedPods[podKey] {
   // 如果已經(jīng)處理過這個(gè) Pod,只添加新的事件信息
   result[podKey] = append(result[podKey], fmt.Sprintf("Additional Event: %s", message))
   continue
  }

  // 標(biāo)記為已處理
  processedPods[podKey] = true

  // 獲取 Pod 日志(添加限制和更好的錯(cuò)誤處理)
  logOptions := &corev1.PodLogOptions{
   TailLines: int64Ptr(100), // 限制日志行數(shù)為最后100行
   LimitBytes: int64Ptr(1024 * 1024), // 限制日志大小為1MB
  }

  req := clientGo.Clientset.CoreV1().Pods(namespace).GetLogs(podName, logOptions)
  podLogs, err := req.Stream(context.TODO())
  if err != nil {
   // 即使獲取日志失敗,也保存事件信息
   result[podKey] = append(result[podKey], fmt.Sprintf("Event Message: %s", message))
   result[podKey] = append(result[podKey], fmt.Sprintf("Namespace: %s", namespace))
   result[podKey] = append(result[podKey], fmt.Sprintf("日志獲取失敗: %v", err))
   continue
  }

  // 使用匿名函數(shù)確保資源及時(shí)釋放
  func() {
   defer podLogs.Close()

   buf := new(bytes.Buffer)
   _, err = buf.ReadFrom(podLogs)
   if err != nil {
    // 日志讀取失敗,但仍保存事件信息
    result[podKey] = append(result[podKey], fmt.Sprintf("Event Message: %s", message))
    result[podKey] = append(result[podKey], fmt.Sprintf("Namespace: %s", namespace))
    result[podKey] = append(result[podKey], fmt.Sprintf("日志讀取失敗: %v", err))
    return
   }

   // 成功獲取日志,保存完整信息
   result[podKey] = append(result[podKey], fmt.Sprintf("Event Message: %s", message))
   result[podKey] = append(result[podKey], fmt.Sprintf("Namespace: %s", namespace))
   result[podKey] = append(result[podKey], fmt.Sprintf("Logs:\n%s", buf.String()))
  }()
 }

 return result, nil
}

我們使用一個(gè) map[string][]string 來保存 pod 的事件和日志信息,然后通過 client-go 獲取 warning 級別的事件,最后過濾需要的 pod 事件以及 pod 相關(guān)信息,然后繼續(xù)通過 client-go 獲取對應(yīng) pod 的日志,然后把這些信息放到 map 中。

(4)設(shè)計(jì)一個(gè) sendToChatGPT 的方法,接受 pod 的事件和日志信息,然后通過 AI 對其進(jìn)行分析

// sendToChatGPT 函數(shù)接受 podInfo map,發(fā)送給 OpenAI 的 ChatGPT 獲取診斷建議
func sendToChatGPT(podInfo map[string][]string) (string, error) {
 // 檢查輸入數(shù)據(jù)
 if len(podInfo) == 0 {
  return "未發(fā)現(xiàn)任何 Pod Warning 事件", nil
 }

 // 創(chuàng)建 OpenAI 客戶端
 client, err := utils.NewOpenAIClient()
 if err != nil {
  return "", fmt.Errorf("創(chuàng)建 OpenAI 客戶端失敗: %v", err)
 }

 // 構(gòu)建結(jié)構(gòu)化的信息字符串
 combinedInfo := buildPodInfoString(podInfo)

 // 輸出調(diào)試信息(可選,生產(chǎn)環(huán)境可移除)
 fmt.Printf("正在分析 %d 個(gè) Pod 的問題...\n", len(podInfo))
 fmt.Println("詳細(xì)信息:")
 fmt.Println(combinedInfo)
 fmt.Println("正在請求 AI 分析...")

 // 構(gòu)造優(yōu)化的 ChatGPT 請求消息
 messages := []openai.ChatCompletionMessage{
  {
   Role: openai.ChatMessageRoleSystem,
   Content: `您是一位資深的 Kubernetes 專家和故障診斷專家。您的任務(wù)是:
1. 分析 Pod 的 Warning 事件和日志
2. 識別根本原因
3. 提供具體的、可操作的解決方案
4. 優(yōu)先推薦命令行解決方案,必要時(shí)提供 YAML 配置
5. 按問題嚴(yán)重程度排序建議`,
  },
  {
   Role: openai.ChatMessageRoleUser,
   Content: fmt.Sprintf(`請分析以下 Kubernetes Pod 問題:

%s

請?zhí)峁?1. 問題根本原因分析
2. 具體解決步驟(優(yōu)先使用 kubectl 命令)
3. 預(yù)防措施建議
4. 如果需要 YAML 配置,請?zhí)峁┩暾纠?
請確保建議具體可操作,避免泛泛而談。`, combinedInfo),
  },
 }

 // 請求 ChatGPT 獲取建議
 resp, err := client.Client.CreateChatCompletion(
  context.TODO(),
  openai.ChatCompletionRequest{
   Model:       openai.GPT4oMini,
   Messages:    messages,
   MaxTokens:   2000, // 限制響應(yīng)長度
   Temperature: 0.1,  // 降低隨機(jī)性,提高一致性
  },
 )
 if err != nil {
  return "", fmt.Errorf("調(diào)用 OpenAI API 失敗: %v", err)
 }

 // 驗(yàn)證響應(yīng)
 if len(resp.Choices) == 0 {
  return "", fmt.Errorf("OpenAI 返回空響應(yīng)")
 }

 responseText := resp.Choices[0].Message.Content
 if responseText == "" {
  return "AI 分析完成,但未返回具體建議", nil
 }

 return responseText, nil
}

// buildPodInfoString 構(gòu)建格式化的 Pod 信息字符串
func buildPodInfoString(podInfo map[string][]string) string {
 var builder strings.Builder
 builder.WriteString("發(fā)現(xiàn)以下 Pod Warning 事件及其日志:\n\n")

 podCount := 0
 for podKey, info := range podInfo {
  podCount++
  builder.WriteString(fmt.Sprintf("=== Pod %d: %s ===\n", podCount, podKey))

  // 分類顯示信息
  for _, line := range info {
   if strings.HasPrefix(line, "Event Message:") {
    builder.WriteString(fmt.Sprintf("?? %s\n", line))
   } else if strings.HasPrefix(line, "Namespace:") {
    builder.WriteString(fmt.Sprintf("?? %s\n", line))
   } else if strings.HasPrefix(line, "Logs:") {
    builder.WriteString(fmt.Sprintf("?? %s\n", line))
   } else if strings.HasPrefix(line, "Additional Event:") {
    builder.WriteString(fmt.Sprintf("?? %s\n", line))
   } else {
    builder.WriteString(fmt.Sprintf("%s\n", line))
   }
  }
  builder.WriteString("\n")
 }

 return builder.String()
}

和 AI 的對話主要就是 prompt 的設(shè)計(jì),然后把具體的參數(shù)傳進(jìn)去即可,沒有特別的地方。

(5)使用 k8scopilot.exe analyze event 進(jìn)行分析驗(yàn)證

分析結(jié)果如下:

正在請求 AI 分析...
根據(jù)您提供的 Kubernetes Pod 日志和事件信息,以下是對問題的根本原因分析、解決步驟、預(yù)防措施建議以及必要的 YAML 配置示例。

### 1. 問題根本原因分析

- **資源不足**:
  - 多個(gè) Pod 報(bào)告了 `ephemeral-storage` 不足的問題,導(dǎo)致 Pod 無法正常運(yùn)行或重啟。
  - 許多 Pod 由于節(jié)點(diǎn)的 `DiskPressure` 狀態(tài)而無法調(diào)度或運(yùn)行。

- **網(wǎng)絡(luò)連接問題**:
  - 多個(gè) Pod 的就緒探針和存活探針失敗,顯示連接超時(shí)或連接被拒絕,表明服務(wù)未能在指定端口上啟動。

- **依賴注入失敗**:
  - 一些 Pod 報(bào)告了 Spring Boot 應(yīng)用程序的依賴注入失敗,特別是與 Dubbo 相關(guān)的服務(wù)未能正確配置。

- **鏡像拉取失敗**:
  - 一些 Pod 報(bào)告了 `ImagePullBackOff`,這通常是由于鏡像不存在或訪問權(quán)限問題。

### 2. 具體解決步驟

#### 2.1 解決資源不足問題

- **清理節(jié)點(diǎn)上的不必要的資源**:
  kubectl delete pod --all -n kube-system
  kubectl delete pod --all -n log

- **增加節(jié)點(diǎn)的存儲資源**:
  如果可能,增加節(jié)點(diǎn)的存儲容量,或者添加新的節(jié)點(diǎn)。

- **調(diào)整 Pod 的資源請求和限制**:
  確保 Pod 的 `ephemeral-storage` 請求和限制設(shè)置合理??梢酝ㄟ^以下命令編輯 Pod 的 YAML 配置:
  ```bash
  kubectl edit deployment <deployment-name> -n <namespace>

  在容器部分添加:
  resources:
    requests:
      ephemeral-storage: "100Mi"
    limits:
      ephemeral-storage: "200Mi"

#### 2.2 解決網(wǎng)絡(luò)連接問題

- **檢查服務(wù)是否正常運(yùn)行**:
  確保 Pod 中的服務(wù)在預(yù)期的端口上啟動??梢酝ㄟ^以下命令查看 Pod 的狀態(tài):
  ```bash
  kubectl get pods -n <namespace>

- **查看 Pod 日志**:
  kubectl logs <pod-name> -n <namespace>

- **增加探針的超時(shí)時(shí)間**:
  如果服務(wù)啟動較慢,可以增加就緒探針和存活探針的超時(shí)時(shí)間:
  readinessProbe:
    httpGet:
      path: /health
      port: 8080
    initialDelaySeconds: 30
    periodSeconds: 10
    timeoutSeconds: 5

#### 2.3 解決依賴注入失敗

- **檢查 Dubbo 配置**:
  確保 Dubbo 的注冊中心配置正確??梢栽趹?yīng)用的配置文件中添加:
  dubbo:
    registry:
      address: "zookeeper://localhost:2181"

- **重啟相關(guān) Pod**:
  ```bash
  kubectl rollout restart deployment <deployment-name> -n <namespace>

#### 2.4 解決鏡像拉取失敗

- **檢查鏡像是否存在**:
  確保指定的鏡像在容器注冊中心中存在,并且訪問權(quán)限正確。

- **更新鏡像標(biāo)簽**:
  如果鏡像標(biāo)簽不正確,可以更新為正確的標(biāo)簽:
  kubectl set image deployment/<deployment-name> <container-name>=<new-image>:<tag> -n <namespace>

### 3. 預(yù)防措施建議

- **監(jiān)控資源使用情況**:
  使用 Kubernetes 的監(jiān)控工具(如 Prometheus 和 Grafana)監(jiān)控節(jié)點(diǎn)和 Pod 的資源使用情況,及時(shí)發(fā)現(xiàn)并解決資源不足的問題。

- **設(shè)置合理的資源請求和限制**:
  在 Pod 的 YAML 配置中設(shè)置合理的資源請求和限制,以避免資源爭用。

- **定期清理不必要的資源**:
  定期檢查和清理不再使用的 Pod 和鏡像,以釋放存儲空間。

從上面的分析結(jié)果可以看到基本能夠給出比較準(zhǔn)確的建議。

當(dāng)然,這里只是診斷問題,還可以對其功能進(jìn)行擴(kuò)展,比如:

  1. 故障自愈:
  • 結(jié)合 Function Calling 實(shí)現(xiàn)自動修復(fù)簡單問題
  1. 增強(qiáng)分析:
  • 增加更多診斷數(shù)據(jù)源(metrics、節(jié)點(diǎn)狀態(tài)等)
  • 實(shí)現(xiàn)歷史問題匹配和知識庫
  1. 可視化:
  • 生成 HTML 格式的診斷報(bào)告
  • 支持問題嚴(yán)重程度分級展示

最后

本文在《開發(fā) K8s Chat 命令行工具》的基礎(chǔ)上,進(jìn)一步實(shí)現(xiàn)了 Kubernetes 故障診斷功能,核心思路是通過工具獲取集群中 Warning 級別的事件及對應(yīng) Pod 的日志,再借助大模型分析并輸出解決方案,為運(yùn)維工作提供了便捷的故障排查途徑。

具體而言,開發(fā)過程通過 cobra-cli 新增 analyze 命令及子命令 event,構(gòu)建 getPodEventsAndLogs 方法獲取相關(guān)事件與日志,設(shè)計(jì) sendToChatGPT 方法將信息傳入大模型進(jìn)行分析。

責(zé)任編輯:武曉燕 來源: 運(yùn)維開發(fā)故事
相關(guān)推薦

2025-08-06 01:45:00

2010-09-26 12:19:28

DHCP故障診斷

2013-05-22 17:18:13

2023-09-15 07:34:15

AIOps云原生項(xiàng)目

2021-12-21 08:31:07

k8s診斷工具kubectl-deb

2009-11-11 17:07:13

路由器故障

2010-08-03 13:41:22

路由器命令

2021-11-25 10:36:04

DNS命令Linux

2009-05-19 16:40:41

TTL網(wǎng)絡(luò)故障科來軟件

2009-11-17 18:44:44

2011-07-28 11:22:50

2012-10-09 16:00:35

交換機(jī)故障

2009-11-12 14:07:16

路由器故障

2020-05-03 12:52:39

VMware Hori虛擬桌面虛擬機(jī)

2009-11-24 18:34:23

網(wǎng)絡(luò)故障診斷路由器

2021-04-23 08:35:16

k8s故障檢測

2011-05-07 14:29:26

復(fù)合機(jī)

2022-04-22 13:32:01

K8s容器引擎架構(gòu)

2009-12-23 10:50:51

網(wǎng)絡(luò)故障診斷

2011-04-22 16:06:17

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號