環境準備
使用包管理工具安裝 kubectl 與 Helm
- 以 Powershell 指令安裝 Scoop
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Get-ExecutionPolicy
$env:SCOOP='D:\Applications\Scoop'
# SetEnvironmentVariable 須要用 administrator 執行
[Environment]::SetEnvironmentVariable('SCOOP', $env:SCOOP, 'Machine')
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop -v
scoop bucket add extras
scoop update
- 安裝 kubectl
scoop install kubectl@1.27.2
- 安裝 Helm
scoop install helm
-
安裝 gcloud CLI
-
git clone Workshop GitHub Repository
導言 (2分鐘)
在當前的微服務架構和容器化部署中,Kubernetes 已成為一個不可或缺的工具。
今天,我們將探討如何在 Kubernetes 環境中集成 OpenTelemetry、FluentBit、Prometheus 和 Grafana,以實現全面的集群監控。將一步步展示如何部署並配置這些工具,以實現對集群運行狀態的全方位監控,包括收集應用和基礎設施的指標,設置數據源,並在 Grafana 中視覺化這些數據。

Kubernetes 和 GKE 簡介 (3分鐘)
- Kubernetes (K8s)
是一個開源容器編排工具,專為自動部署、擴展和管理容器化應用而設計。
- GKE (Google Kubernetes Engine) 則是 Google Cloud 平台上的管理型 Kubernetes 服務。
GKE 上建立集群 (10分鐘)
此 Lab 雖使用 GKE 進行,但在其它 Kubernetes 平台依然可以照著文章步驟完成全棧監控的實做。
首先在瀏覽器用 Google 帳戶登入 GCP Console 控制台新建 Project,紀錄 Project ID。
gcloud auth login
檢查是否登入成功
gcloud auth list
接著,安裝認證組件
gcloud components install gke-gcloud-auth-plugin
查看建立專案清單,複製剛剛建立好的專案 PROJECT_ID
gcloud projects list
設定接下來執行工作所需的專案環境
PROJECT_ID="貼上複製的PROJECT_ID"
gcloud config set project ${PROJECT_ID}
檢查專案環境是否配置正確
gcloud config list
啟用 Kubernetes Engine API
gcloud services enable container.googleapis.com \
--project ${PROJECT_ID}
在 GKE 上建立集群其實就是建立一組運行 Kubernetes 的虛擬機。
gcloud container clusters create "devopsdays-cluster" \
--region asia-northeast1 \
--node-locations asia-northeast1-a,asia-northeast1-b \
--num-nodes=1 \
--machine-type=e2-medium
--region
:選擇集群的地理位置。
--node-locations
:選擇集群的可用區域
(將節點分佈在不同可用區域可以以提高可用性)
--num-node
:每個可用區域的節點數量。
--machine-type
:虛擬機的規格。
接著,取得 kubeconfig 認證
gcloud container clusters get-credentials devopsdays-cluster --region asia-northeast1 --project devopsdays-2023


安裝 Kubernetes Dashboard (Optional 5分鐘)
Kubernetes Dashboard 是 Kubernetes 的官方 Web UI。
- 可視化資源的使用情況
- 進行應用程式的疑難排解
- 用於管理 K8s 集群
因為我們使用 GKE 服務,已經有 UI 管理介面,所以這個步驟可以不用做。
kubernetes-dashboard 7.0.0-alpha1 · helm/k8s-dashboard
(artifacthub.io)
安裝及存取 Dashboard
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
#
helm repo update
#
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
# Get the Kubernetes Dashboard URL by running:
export POD_NAME=$(kubectl get pods -n kubernetes-dashboard -l "app.kubernetes.io/name=kubernetes-dashboard,app.kubernetes.io/instance=kubernetes-dashboard" -o jsonpath="{.items[0].metadata.name}")
#
echo https://127.0.0.1:8443/
#
kubectl -n kubernetes-dashboard port-forward $POD_NAME 8443:8443
安裝 Ingress Controller (5分鐘)
Ingress Controller 讓我們可以設定外部訪問進入 K8s 集群的路由,在 Kubernetes 中是類型為 LoadBalancer
的 Service。
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
#
helm repo update
#
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace

在 GKE 中安裝 Ingress Controller 會創建一個負載平衡器(Load Balancer),GCP 會分配一個暫時性(Ephemeral)的外部 IP 地址(INGRESS_IP)給負載平衡器,但不會自動為它分配一個域名。
因此我們要獲取 INGRESS_IP 並設定為保留 IP(Static IP)。
MY_INGRESS_IP=""
#
MY_INGRESS_IP=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -ojson | jq -j '.status.loadBalancer.ingress[].ip')
#
echo 'MY_INGRESS_IP: '$MY_INGRESS_IP
#
gcloud compute addresses create "devopsdays-cluster-ingress-ip" --addresses=${MY_INGRESS_IP} --region=asia-northeast1
在 GCP Console 可以看到 External IP 變成 Static 類型。

如前述 GCP 不會自動為負載平衡器分配一個域名,所以接著我們要自己配置域名。
因為我們在測試階段,不用真的去購買一個域名,只需要在本機的 hosts
文件中配置將 INGRESS_IP 指向到域名 gke-cluster-demo
即可。
在 Windows 系統中,hosts
文件的位置在:
C:\Windows\System32\drivers\etc
在 Apple 的 macOS 和大多數 Linux 系統中,hosts
文件的位置在:
/etc/hosts
使用 root 權限用文本編輯器打開和並修改它,在文檔最下方加入這一行:
MY.INGRESS.IP gke-cluster-demo
請記住,在進行任何修改之前,總是先備份原始的 hosts
文件。
監控工具 Prometheus (10分鐘)
Prometheus 是一個開源系統監控和警報工具。
在 Kubernetes 中,每個節點、Pod 都是資源。Prometheus
可以幫助我們獲取這些資源的度量指標。
kube-prometheus-stack-ingress.yaml
此文件配置了 Prometheus、Alertmanager 和 Grafana 的 Ingress 設定。
- Prometheus
- 啟用 ingress。
- 使用 nginx 作為 ingress 的類型。
- 定義了外部路徑
/prometheus
。
- Alert Manager
- 警報如何與 Gmail 整合。
- 啟用 ingress。
- 使用 nginx 作為 ingress 的類型。
- 定義了外部路徑
/alertmanager
。
- Grafana
- 服務運行於 3000 端口。
- 環境變數設定了 Grafana 的根 URL 和子路徑。
- 啟用 ingress,路徑設定為
/grafana
。
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
#
helm repo update
#
helm install prometheus prometheus-community/kube-prometheus-stack --set grafana.sidecar.dashboards.enabled=true -f kube-prometheus-stack-ingress.yaml -f kube-prometheus-stack-values.yaml -n prometheus --create-namespace
其中 prometheus-community/kube-prometheus-stack 整合了 Prometheus、Alert Manager 和 Grafana。
我們在 yaml 中配置了 ingress 資源,就可以於瀏覽器輸入以下網址即可看到監控服務的後台介面:
或是用 port-forward 的方式到監控服務的後台介面:
kubectl -n prometheus port-forward prometheus-grafana-75d58479bb-8kth6 3000:3000
其中 prometheus-grafana-75d58479bb-8kth6
依據當時所產生的 pod name 更換。
kubectl -n prometheus port-forward alertmanager-prometheus-kube-prometheus-alertmanager-0 9093:9093
kube-prometheus-stack-values.yaml
此文件定義了 Prometheus 和 Alertmanager 的一些核心參數。
- Prometheus:
- 定義 scrape 和評估的間隔時間。
- 定義了一個自定義的警報規則,如果某實例停止運行超過1分鐘,將觸發警報。
- Alertmanager:
- 設定全局的 SMTP 參數以使用 Gmail 發送警報。
- 定義了路由和接收者的設定。
佈署服務與 Prometheus 監控 (10分鐘)
這裡我們會佈署一個以 Java Spring Boot Web 框架撰寫的示範服務,並對它進行監控。
authorization-server-service-deployment.yaml
此文件定義了授權伺服器的部署、服務和入口。
- 使用 Deployment 來管理 pod。
- Service 定義了如何訪問這些 pod。
- Ingress 定義了如何從外部訪問此服務。
kubectl create namespace demo
kubectl apply -f authorization-server-service-deployment.yaml -n demo
部署完成後,這是一個授權服務器,在這個網址可以看到它的資訊
https://gke-cluster-demo/.well-known/oauth-authorization-server
authorization-server-service-monitor.yaml
這是 ServiceMonitor 的配置,用於告訴 Prometheus 如何發現和抓取授權伺服器的指標。
部署 Prometheus 監控
kubectl apply -f authorization-server-service-monitor.yaml -n demo
查看監控是否部署完成
kubectl get ServiceMonitor --all-namespaces

Grafana Dashboard 監控數據可視化 (10分鐘)
Grafana 是一個開源平台,可以整合 Prometheus、OpenTelemetry、Tempo、Loki 等數據源,提供一個統一的資料可視化界面。
我們新增 Dashboard 將剛剛 Prometheus 監控的數據可視化。
Spring Boot 2.1 System Monitor | Grafana Labs



Log(Tempo) to Trace(OpenTelemetry) and Trace to Log (25分鐘)
安裝 OpenTelemetry
OpenTelemetry 是一個開源專案,用於收集應用程式的追踪、指標和日誌數據。
- OpenTelemetry 提供了一系列的 API、庫、代理和儀器,使開發者能夠添加觀察性到他們的應用程式。
- 被視為 OpenTracing 和 OpenCensus 兩個專案的後繼者,並結合了它們的最佳實踐。
- 允許開發者自動收集和導出性能指標和追踪資料,使其更容易診斷問題和了解應用程式的運行狀況。
otel-collector-sidecar.yaml
這是 OpenTelemetry Collector 的配置。
- 運行在 sidecar 模式。
- 定義了接收、處理和導出跡象數據的流程。
kubectl apply -f cert-manager.yaml
這裡要等一下 cert-manager 與 cert-manager-webhook 兩個 pod 是否已經啟動完成,再裝 opentelemetry-operator。
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
#
helm repo update
#
helm install opentelemetry-operator open-telemetry/opentelemetry-operator -n tracing --create-namespace
kubectl apply -f otel-collector-sidecar.yaml -n demo
安裝 Tempo
Tempo 是 Grafana Labs 出品的一個高度可擴展的、多租戶的、低成本的追踪系統。
- 旨在與其它 Grafana Labs 產品如 Loki、Cortex 等緊密集成。
- Tempo 可以存儲大量的追踪數據。
- 不需要進行進一步的處理或索引,因此存儲成本相對較低。
- 提供分佈式追踪視覺化,幫助開發者分析和優化他們的應用程式。
tempo-values.yaml
這是 Tempo 的簡單配置,用於 Trace 數據。
- 啟用了 gateway 和 queryFrontend。
helm repo add grafana https://grafana.github.io/helm-charts
#
helm repo update
#
helm install tempo grafana/tempo -f tempo-values.yaml -n tracing
安裝 Loki
Loki 是一個水平可擴展的、高可用的、多租戶的日誌聚合系統。
- 由 Grafana Labs 開發,與 Grafana 的監控軟件緊密集成。
- Loki 的設計目標是簡單而有效,它不為日誌數據建立索引,而是為每個日誌流建立索引。
- 提供了一個類似 PromQL 的查詢語言 LogQL,使查詢和整合變得更加簡單。
loki-values.yaml
這是 Loki 的配置,用於日誌數據。
- 禁用了 fluent-bit 和 Prometheus。
- 啟用了 promtail 來收集日誌。
helm repo add grafana https://github.com/grafana/helm-charts
#
helm repo update
#
helm install loki grafana/loki-stack -f loki-values.yaml -n tracing
安裝 FluentBit
FluentBit 是一個輕量級的日誌處理器和轉發器,適用於容器、伺服器、IoT 和邊緣設備。
- 設計用於在低記憶體和CPU消耗下高效運行。
- 提供了豐富的輸入、過濾器和輸出插件。
- FluentBit 常被用作日誌收集器。
fluentbit-configmap.yaml
此文件定義了 FluentBit 的配置。
- 定義了輸入、過濾和輸出的流程。
- 使用正則表達式解析器解析 Spring 應用程序的日誌格式。
helm repo add fluent https://fluent.github.io/helm-charts
#
helm repo update
#
helm install fluent-bit fluent/fluent-bit -n fluentbit --create-namespace
#
kubectl apply -f fluentbit-configmap.yaml -n fluentbit
#
kubectl rollout restart ds fluent-bit -n fluentbit
若要看 fluent-bit 其它可以設定的 values 可以用此指令:
helm show values fluent/fluent-bit > fluentbit-all-values.yaml
再佈署一次服務
因為先前無部署 OpenTelemetryCollector,因此服務都尚未被注入 OTel
Collector sidecar,所以要再部署一次。
kubectl delete -f authorization-server-service-deployment.yaml -n demo
kubectl apply -f authorization-server-service-deployment.yaml -n demo
Grafana UI 配置 DataSources (10分鐘)

http://loki.tracing:3100

http://tempo.tracing:3100

Finished (5分鐘)
Workshop 結束囉,記得將 Cluster 刪除,避免產生額外費用。
gcloud container clusters delete devopsdays-cluster --region=asia-northeast1
這些工具提供了一個完整的監控和觀察性解決方案,幫助了解、診斷和優化其應用程式的性能。
希望透過今天的分享,讓各位有在 Kubernetes
實現全棧監控的基石,其中還有很多能夠補強及完善的地方,我們可以著手持續跌代演進,謝謝大家的參與。
參考資料
- https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml
- https://github.com/open-telemetry/opentelemetry-collector/blob/main/examples/k8s/otel-config.yaml
- https://github.com/grafana/helm-charts/tree/main/charts/tempo
- https://artifacthub.io/packages/helm/grafana/tempo
- https://artifacthub.io/packages/helm/grafana/tempo-distributed
- https://artifacthub.io/packages/helm/loki/loki-stack
- https://github.com/isItObservable/fluentbitv2/tree/master
- https://opentelemetry.io/docs/kubernetes/helm/operator/
- https://medium.com/cloud-native-daily/level-up-your-tracing-platform-opentelemetry-grafana-tempo-8db66d7462e2
- https://blog.cloudtechner.com/log-management-and-distributed-tracing-using-grafana-loki-and-tempo-b9c56392bae7
- https://grafana.com/blog/2020/02/25/step-by-step-guide-to-setting-up-prometheus-alertmanager-with-slack-pagerduty-and-gmail/