iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0
Software Development

用 Golang + Elasticsearch + Kubernetes 打造雲原生搜尋服務系列 第 29

Day 29 - 觀測 & 小故障演練 — 看見系統、擁抱未知

  • 分享至 

  • xImage
  •  

在前面幾天,我們讓系統逐步長出血肉:它會部署、會自我調整資源、會根據負載彈性擴縮。
但這一切的前提是——你能看見它在呼吸。
今天我們讓 cloud-native-search 的叢集第一次有「眼睛」:用最小化的 Prometheus + Grafana 觀測堆疊,並透過一次小型「刪 Pod」演練,測試系統的復原能力(MTTR, Mean Time To Recovery)。


為什麼觀測是必要的?

軟體跑在雲端叢集中,失敗不是例外,而是日常。
Kubernetes 會幫你自動重啟 Pod、重新排程、維持副本,但這些自我修復機制只是「行為」,不是理解。

觀測的目的,是讓你「理解這個行為的節奏」:

  • 它多久恢復?
  • 負載高時誰先吃緊?
  • 服務在復原中,使用者是否短暫受到影響?

而要達到這個層級的理解,我們不需要建立企業級 observability stack,
只要 Prometheus + Grafana + 一次小小的實驗 就足夠。


Step 1. 部署 Prometheus 與 Grafana(最小可行版本)

我們用最輕量的設定,不靠 Helm chart,只靠純 YAML。
建立一個命名空間:

kubectl create namespace monitoring

然後建立 prometheus-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:v2.52.0
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: config
          mountPath: /etc/prometheus/
      volumes:
      - name: config
        configMap:
          name: prometheus-config
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
spec:
  selector:
    app: prometheus
  ports:
    - port: 9090
      targetPort: 9090

接著我們要讓它知道要抓誰的 metrics。
新建 prometheus-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 5s
    scrape_configs:
      - job_name: 'cloud-native-search'
        static_configs:
          - targets: ['cloud-native-search.default.svc.cluster.local:8080']

這樣 Prometheus 會每 5 秒去抓我們服務的 metrics。

然後是 Grafana:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:10.4.0
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: monitoring
spec:
  selector:
    app: grafana
  ports:
    - port: 3000
      targetPort: 3000

部署:

kubectl apply -f prometheus-config.yaml -f prometheus-deploy.yaml -f grafana.yaml

本地 port-forward:

kubectl port-forward svc/grafana 3000:3000 -n monitoring

進入 http://localhost:3000,預設帳密是 admin / admin
再到「Data sources」→ 新增 Prometheus → URL 填 http://prometheus.monitoring.svc.cluster.local:9090


Step 2. 建立最小看板

不需要花哨,只要幾個關鍵指標:

  • Pod restart count
  • Request duration(可從你的 /metrics 中取)
  • HTTP status code ratio(成功與錯誤比例)
  • CPU / Memory 使用率(Node exporter 若未啟用,可忽略)

這樣的看板能讓你一眼看到「穩定性」與「服務回應品質」。


Step 3. 小故障演練:刪掉一個 Pod

讓我們做點壞事:

kubectl delete pod -l app=cloud-native-search

在 Grafana 看看:

  • Prometheus 中 up{job="cloud-native-search"} 是否短暫變成 0?
  • 服務在幾秒內恢復?
  • 使用者流量是否有瞬間 spike 或 error?

這個恢復時間,就是你的 MTTR
若 HPA 或 readinessProbe 沒設好,你可能會看到瞬間的 5xx —— 那正是今天練習的意義所在。


Step 4. 反思:從可見到可預測

當你能看見系統,就能開始預測它的行為。
例如:

  • 「CPU 超過 80% 一分鐘後一定會 scale out」
  • 「Pod 重啟平均花 7 秒」
  • 「在新版本 rollout 時,延遲會增加 100ms」

這些不是數據,而是組織記憶
它們讓團隊能安心地部署、勇敢地試錯,因為大家都知道系統的韌性底線在哪裡。


今日回顧

今天,我們讓系統「看見自己」。
透過最小化的 Prometheus 與 Grafana 部署,學會如何建立基本的觀測基礎,能即時看到服務的運作狀況與資源消耗。
接著,我們做了一次刻意的「刪 Pod」實驗,親眼觀察 Kubernetes 的自我修復過程,也量化了系統的平均恢復時間(MTTR)。

這不是單純的監控練習,而是一次對信任的建立:
我們不再只是「希望」系統沒壞,而是能「知道」它何時壞、為什麼壞、以及多快能恢復。
從這一刻起,我們的系統開始具備「可觀測性」,讓我們可以理解、預測、並信任系統的行為。


上一篇
Day 28 - 邊界與權限:NetworkPolicy + RBAC 實戰
系列文
用 Golang + Elasticsearch + Kubernetes 打造雲原生搜尋服務29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言