
以前管 Kubernetes 都是 kubectl 或 Dashboard,出門在外還要 VPN、記指令,超麻煩。這次我直接把 KubeWizard 改造成 LINE Bot Agent API,讓你用手機聊天就能查資源、看 log、重啟服務,還能自動化、擴充工具,維運體驗直接升級。
主要功能:
模型我選 Google Gemini,因為:
Gemini API Rate limits 詳細請看官方:Gemini API Rate limits
整體流程:使用者訊息 → LINE → Webhook → Agent → 工具 → 回覆
架構分四層:
| 層級 | 角色 | 說明 |
|---|---|---|
| 介面層 | LINE Bot / REST API | 多入口、Webhook、告警/事件注入 |
| 智能層 | Agent + LLM | 決策要不要用工具、整合輸出、維持上下文 |
| 工具層 | KubeTool / Search / RequestsGet / 人工介入 | 插拔式設計,擴充容易、權限隔離 |
| 狀態層 | Redis / Kubernetes SDK | 對話記憶、叢集操作、資源快照 |
| 面向 | Python SDK | 直接 kubectl |
|---|---|---|
| 安全性 | 避免字串注入 | 需特別處理指令拼接 |
| 錯誤處理 | 結構化例外 | 文字解析困難 |
| 體積 | 輕量映像 | 需額外安裝 CLI |
| 程式化能力 | 物件操作、易封裝 | 需解析輸出字串 |
| RBAC 整合 | 原生憑證/SA | 需掛載 kubeconfig |
自動偵測環境:
def load_k8s_config():
if os.path.exists("/var/run/secrets/kubernetes.io/serviceaccount/token"):
config.load_incluster_config()
else:
config.load_kube_config()
常見映射:kubectl get pods -n X → v1.list_namespaced_pod(namespace=X)。
前往 LINE Developers:
https://developers.line.biz/console/
建立 Provider
建立 Messaging API Bot
取得 Channel 設定並寫入 .env:
LINE_CHANNEL_SECRET=你的_channel_secret LINE_CHANNEL_ACCESS_TOKEN=你的_access_token
https://your-domain.com/linebot/callback
Webhook 測試可以用 ngrok 讓本地端公開測試。
| 項目 | 設定值 |
|---|---|
| Webhook URL | https://example.com/linebot/callback |
| Use webhook | ✅ 啟用 |
需使用 HTTPS。成功後請點擊 Verify 確認。
預設 KubeWizard 只能問一句答一句,要變成真正好用的 Agent,必須加上記憶、工具判斷、多入口。
| 元件 | 功能 | 技術實現 |
|---|---|---|
| Agent | 分析訊息與決策是否使用 Tools | LangChain OpenAI Tools Agent |
| Tools | 以插件形式提供功能(K8s、Pipeline、AI 等) | LangChain BaseTool |
| Memory | 使用 Redis 儲存上下文與使用者狀態 | RedisChatMessageHistory + ConversationTokenBufferMemory |
| API | 提供 REST API 與 LINE Webhook | FastAPI |
每個功能都獨立成 Tool,擴充超方便。以下是 KubeTool 實作:
from langchain_core.tools import BaseTool
from kubernetes import client, config
from pydantic import BaseModel, Field
class KubeInput(BaseModel):
"""Kubernetes 工具的參數模型"""
commands: str = Field(
...,
example="kubectl get pods",
description="要執行的 kubectl 相關命令"
)
class KubeTool(BaseTool):
"""Kubernetes 工具 - 使用 Python SDK 執行 K8s 操作"""
name: str = "KubeTool"
description: str = """在 Kubernetes 集群上執行 k8s 相關命令的工具。
支援 get/describe/logs/list 等操作。
特別功能:
- 使用 'kubectl list all' 快速查看所有 namespace 和 pods 概覽
- 使用 'kubectl list namespaces' 查看所有 namespace
- 使用 'kubectl list pods' 按 namespace 分組查看所有 pods
"""
args_schema: Type[BaseModel] = KubeInput
def __init__(self, **kwargs):
super().__init__(**kwargs)
# 自動判斷環境並載入配置
try:
config.load_incluster_config() # Pod 內環境
logger.info("使用集群內配置 (Pod 環境)")
except:
config.load_kube_config() # 本地環境
logger.info("使用本地 kubeconfig 配置")
self.v1 = client.CoreV1Api()
self.apps_v1 = client.AppsV1Api()
def _run(self, commands: str) -> str:
"""執行 kubectl 命令並返回結果"""
# 解析命令並轉換為 SDK API 調用
# 例如:kubectl get pods -n default
# 轉換為:self.v1.list_namespaced_pod(namespace="default")
...
# Agent 初始化
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_google_genai import ChatGoogleGenerativeAI
# 定義可用工具
tools = [
KubeTool(),
SearchTool(),
RequestsGet(),
human_console_input()
]
# 創建 Agent
agent = create_openai_tools_agent(
llm=ChatGoogleGenerativeAI(model="gemini-2.0-flash"),
tools=tools,
prompt=system_prompt
)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory,
verbose=True
)
# 執行流程:使用者問題 → Agent 分析 → 選擇工具 → 執行 → 回傳結果
result = agent_executor.invoke({"input": "列出所有 pods"})
這次不是先寫一堆設計文件,而是邊做邊調整,用我自己說的「Vibe Coding」節奏在迭代,大概是這樣玩:
KubeAgent,只接一個 KubeTool,可以在 CLI 回「列出 pods」就算過關。search,就專心測 2~3 個情境,確認它真的會用到,再加下一個 RequestsGet、human_console_input。KubeToolWithApprove,一定要有人按確認才會執行。整體心法很簡單:
這段就當成「我在實作中真的遇到的坑」,挑幾個代表性的來說:
kubectl,改用 Python SDK kubectl,很容易踩到 shell 注入、錯誤訊息也難處理,鏡像還要再裝一個 CLI。 kubectl get pods -n default)用程式解析後,映射到 Python SDK 的呼叫,像是 v1.list_namespaced_pod(namespace="default"),最後再自己排版成表格。 tools/kubetool_sdk.py。kubeconfig,丟進叢集裡又要用 ServiceAccount,如果寫死,很容易哪邊忘記改。 load_incluster_config(),沒有就退回 load_kube_config()。 utils/k8s_config.py。ConversationTokenBufferMemory 控制長度,超過一定筆數就用模型幫忙總結,把舊訊息收斂成一段摘要。 agents/kube_agent.py。user_id,每個人一個獨立的對話空間。 agents/kube_agent.py。KubeTool(安全),以及需要人按確認的 KubeToolWithApprove。真的要動手之前,會先問一次。 tools/kubetool_sdk.py。kube_agent.py 的輸入前處理。values.yaml 控制。 helm/values.yaml 與 RBAC 節。agents/kube_agent.py 的 system prompt 裡。這些其實都不是什麼高深的「AI 技術」,比較像是:把一個會講話的 Bot ,慢慢調整到真的能在維運現場派上用場。
以下為建議的最小必要權限,支援 Namespace Scoped 和 Cluster Wide 兩種模式。
適用場景:
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubewizard-bot
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kubewizard-bot-role
namespace: default
rules:
# Core 資源
- apiGroups: [""]
resources: ["pods", "services", "endpoints", "events", "configmaps", "secrets", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
# Pod logs(只需讀取權限)
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]
# Apps 資源
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
# Batch 資源
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
# Networking 資源
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses", "networkpolicies"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubewizard-bot-binding
namespace: default
subjects:
- kind: ServiceAccount
name: kubewizard-bot
namespace: default
roleRef:
kind: Role
name: kubewizard-bot-role
apiGroup: rbac.authorization.k8s.io
適用場景:
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubewizard-bot
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubewizard-bot-cluster-role
rules:
# Namespace 級別資源(所有 namespace)
- apiGroups: [""]
resources: ["pods", "services", "endpoints", "events", "configmaps", "secrets", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses", "networkpolicies"]
verbs: ["get", "list", "watch"]
# Cluster 級別資源(只讀)
- apiGroups: [""]
resources: ["nodes", "namespaces", "persistentvolumes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubewizard-bot-cluster-binding
subjects:
- kind: ServiceAccount
name: kubewizard-bot
namespace: default
roleRef:
kind: ClusterRole
name: kubewizard-bot-cluster-role
apiGroup: rbac.authorization.k8s.io
專案已包含完整的 Helm Chart,可透過 values.yaml 輕鬆配置:
# values.yaml
# RBAC 配置
rbac:
# 是否創建 RBAC 資源
create: true
# 使用 Role (false) 或 ClusterRole (true)
# 設為 false 可避免需要 cluster-admin 權限
clusterWide: false
# 自定義 RBAC 規則
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
部署方式:
# 1. Namespace Scoped 部署(推薦) helm install kubewizard ./helm \ --set rbac.clusterWide=false \ --set secrets.AI_GOOGLE_API_KEY="your-api-key" \ --namespace default # 2. Cluster Wide 部署 helm install kubewizard ./helm \ --set rbac.clusterWide=true \ --set secrets.AI_GOOGLE_API_KEY="your-api-key" \ --namespace default # 3. 驗證 RBAC 權限 kubectl auth can-i list pods \ --as=system:serviceaccount:default:kubewizard-bot \ -n default
你: 幫我看 default namespace 的 Pods
Bot:
📦 Namespace: default ================================ NAME READY STATUS RESTARTS AGE nginx-deployment-7d8f... 1/1 Running 0 2d redis-master-0 1/1 Running 0 5d payment-service-abc123 0/1 CrashLoopBackOff 5 10m 總計: 3 pods (2 Running, 0 Pending, 1 CrashLoopBackOff) ⚠️ 發現問題: payment-service-abc123 處於 CrashLoopBackOff 狀態 需要查看 Logs 嗎?
你: 看一下那個 Crash 的 Log
Bot:
🔍 payment-service-abc123 的最近日誌: 2025-11-22 10:30:15 [ERROR] Failed to connect to database 2025-11-22 10:30:15 [ERROR] Connection refused: mysql:3306 2025-11-22 10:30:15 [FATAL] Application startup failed 💡 可能原因: 1. MySQL Service 不存在或無法訪問 2. 環境變數配置錯誤(DB_HOST) 3. 網絡策略阻擋連線 建議檢查: - kubectl get svc -n default | grep mysql - 確認 Pod 的環境變數設定
你: 幫我重啟看看
Bot:
🔄 正在重啟 Deployment: payment-service ✅ 已執行:kubectl rollout restart deployment/payment-service -n default ⏳ 等待新 Pod 啟動中... 📊 更新狀態: - 舊版 Pods: 正在終止 - 新版 Pods: 正在創建 - 預計完成時間: ~30 秒 我會持續監控狀態,稍後回報結果。
你: 為什麼我的 Ingress 無法訪問?
Bot: 讓我幫你診斷 Ingress 問題。
🔍 診斷步驟: 1️⃣ 檢查 Ingress 資源 ✅ Ingress 'my-app' 已存在 ✅ Ingress Controller 正常運行 2️⃣ 檢查 Service ✅ Service 'my-app-svc' 已存在 (ClusterIP: 10.96.1.100) 3️⃣ 檢查 Pod ⚠️ 問題發現:Service 後端沒有可用的 Pod! EndpointSlice 資訊: - my-app-svc: 0/3 endpoints ready 📋 建議解決方案: 1. 檢查 Deployment 的 selector 是否與 Service 匹配 2. 檢查 Pod 的 labels 是否正確 3. 執行:kubectl describe service my-app-svc -n default 需要我幫你執行這些檢查嗎?
你: 列出所有 namespace
Bot:
📋 所有 Namespaces: 1. default 2. kube-system 3. kube-public 4. production 5. staging 6. monitoring 總計: 6 個 namespaces
你: production 裡面有什麼?
Bot: (智能記憶前一句的 “production” namespace)
📦 Namespace: production ================================ Deployments: - api-gateway (3/3 Ready) - user-service (2/2 Ready) - order-service (5/5 Ready) Services: - api-gateway-svc (LoadBalancer) - user-service-svc (ClusterIP) - order-service-svc (ClusterIP) 總計: 3 Deployments, 3 Services, 10 Pods (全部正常)
你: 重啟 api-gateway
Bot: (記得我們在談論 production namespace 的 api-gateway)
確認要重啟 production namespace 的 api-gateway 嗎? 這會導致短暫的服務中斷。 [已確認] 🔄 正在執行:kubectl rollout restart deployment/api-gateway -n production ✅ 重啟成功!新 Pods 已啟動並就緒。
這篇筆記示範怎麼把 KubeWizard 整合到 LINE Bot,打造出能聊天管 K8s 的助理,重點: