iT邦幫忙

2025 iThome 鐵人賽

DAY 26
1
DevOps

賢者大叔的容器修煉手札系列 第 26

DevSpace 統一指揮:一鍵啟動完整可觀測性微服務平台 🎯🚀

  • 分享至 

  • xImage
  •  

賢者大叔的容器修煉手札 第 26 篇

DevSpace 統一指揮:一鍵啟動完整可觀測性微服務平台 🎯🚀

經過前兩天分別建立了 Fluent Bit 日誌收集和 OpenTelemetry Collector 可觀測性中樞,今天我們要完成最後的拼圖!就像指揮家統領整個交響樂團一樣,我們將用 DevSpace 的根目錄配置,一鍵啟動包含資料庫、微服務、日誌收集、指標追蹤的完整平台。這不只是技術整合,更是架構思維的昇華!

🎯 今日學習目標

✅ 掌握 DevSpace 多層級依賴管理的精髓

✅ 實戰部署完整的可觀測性微服務架構

✅ 建立統一的開發、測試、監控工作流

✅ 驗證端到端的可觀測性數據流

🎼 從分散到統一:架構演進之路

🎭 昨日回顧:各自為政的時代

# 第 24 天:Fluent Bit Sidecar
cd user-service && devspace dev    # 🏃‍♂️ 啟動用戶服務
cd order-service && devspace dev   # 🏃‍♂️ 啟動訂單服務
kubectl apply -f fluent-bit-config.yaml  # 📝 手動部署日誌配置

# 第 25 天:OTel Collector
cd observability/otel-collector && devspace dev  # 🧠 啟動收集器

# 😵 問題:需要開多個 terminal,手動協調啟動順序

🎯 今日目標:一鍵交響樂

# 🎼 一條指令,啟動整個世界
devspace dev --debug

# ✨ 自動協調:
# 1. 資料庫先啟動
# 2. 配置文件部署
# 3. 微服務並行啟動
# 4. 可觀測性組件就緒
# 5. 所有端口自動轉發

🏗️ 統一架構設計:指揮中心視角

🎪 四層協調架構

層級 組件 DevSpace 角色 啟動順序
🗄️ 基礎設施層 PostgreSQL database/devspace.yaml 1️⃣ 最先啟動
⚙️ 配置層 ConfigMaps, Secrets root/deployments/ 2️⃣ 配置就緒
🚀 應用層 User/Order Services root/deployments/ 3️⃣ 並行啟動
👁️ 觀測層 OTel Collector observability/otel-collector/ 4️⃣ 最後就緒

🎮 DevSpace 根目錄配置

🎯 核心設計理念

# 🎼 依賴編排:像指揮家一樣精確控制
dependencies:
  database:          # 🗄️ 基石:先有數據庫
    path: ./database
  user-service:      # 🏃‍♂️ 服務:依賴數據庫
    path: ./user-service
  order-service:     # 🛒 服務:依賴數據庫
    path: ./order-service
  otel-collector:    # 🧠 觀測:最後啟動
    path: ./observability/otel-collector

# 🎯 部署統一管理:配置和服務分離
deployments:
  services:
    kubectl:
      manifests:
        - ./deployments/user-service.yaml      # 📦 應用部署
        - ./deployments/order-service.yaml     # 📦 應用部署
        - ./deployments/fluent-bit-config.yaml # ⚙️ 日誌配置

🎪 管道設計

# 🎭 多場景管道:不同需求,不同啟動方式
pipelines:
  dev:              # 🎯 完整開發環境
    run: |-
      echo "🚀 Starting full ecommerce platform..."
      create_deployments services    # ⚙️ 先部署配置
      run_dependencies database      # 🗄️ 啟動數據庫
      run_dependencies otel-collector # 🧠 啟動收集器
      start_dev user-service         # 🏃‍♂️ 開發模式服務
      start_dev order-service        # 🛒 開發模式服務
      start_dev otel-collector       # 👁️ 開發模式觀測

  apps:             # 🔧 純應用開發
    run: |-
      create_deployments services
      run_dependencies database
      start_dev user-service
      start_dev order-service

  obs:              # 👁️ 純觀測開發
    run: |-
      create_deployments services
      run_dependencies otel-collector
      start_dev otel-collector

🎛️ 統一端口管理:一站式訪問

🌐 服務端口規劃

dev:
  # 🏃‍♂️ 應用服務端口
  user-service:
    labelSelector:
      app: user-service
    ports:
      - port: "8080:8080"    # 🌐 REST API
    logs:
      enabled: true

  order-service:
    labelSelector:
      app: order-service
    ports:
      - port: "8081:8081"    # 🌐 REST API
    logs:
      enabled: true

  # 🗄️ 數據庫端口
  postgresql:
    labelSelector:
      app: postgresql
    ports:
      - port: "5432:5432"    # 🗄️ PostgreSQL

  # 🧠 觀測中樞端口
  otel-collector:
    labelSelector:
      app: otel-collector
    ports:
      - port: "4317:4317"    # 📡 OTLP gRPC
      - port: "4318:4318"    # 🌐 OTLP HTTP
      - port: "13133:13133"  # ❤️ Health Check
      - port: "8889:8889"    # 📊 Prometheus Metrics
      - port: "55679:55679"  # 🔍 zPages Debug
    open:
      - url: http://localhost:13133      # 🏥 健康檢查
      - url: http://localhost:8889/metrics # 📈 指標查看

🛠️ 統一管理工具:DevSpace Commands

🎯 完整生命週期管理

commands:
  # 📊 系統狀態總覽
  status:
    command: |-
      echo "=== 🏗️ Namespace & Pods ==="
      kubectl get pods -n ecommerce -o wide
      echo "=== 🌐 Services ==="
      kubectl get svc -n ecommerce
      echo "=== 🔍 Quick Health Check ==="
      echo "User Service: $(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health 2>/dev/null || echo 'Not Ready')"
      echo "Order Service: $(curl -s -o /dev/null -w "%{http_code}" http://localhost:8081/health 2>/dev/null || echo 'Not Ready')"
      echo "OTel Collector: $(curl -s -o /dev/null -w "%{http_code}" http://localhost:13133 2>/dev/null || echo 'Not Ready')"

  # 🗃️ 資料庫初始化
  migrate:
    command: |-
      echo "🗃️ Running database migrations..."
      kubectl exec -it deployment/postgresql -n ecommerce -- psql -U postgres -d ecommerce -c "
      CREATE TABLE IF NOT EXISTS users (
          id SERIAL PRIMARY KEY,
          username VARCHAR(50) UNIQUE NOT NULL,
          email VARCHAR(100) UNIQUE NOT NULL,
          created_at TIMESTAMP DEFAULT NOW()
      );
      CREATE TABLE IF NOT EXISTS orders (
          id SERIAL PRIMARY KEY,
          user_id INTEGER REFERENCES users(id),
          product_name VARCHAR(200) NOT NULL,
          quantity INTEGER NOT NULL,
          total_amount DECIMAL(10,2) NOT NULL,
          created_at TIMESTAMP DEFAULT NOW()
      );"

  # 🧪 端到端測試
  test:
    command: |-
      echo "🧪 Running integration tests..."
      echo "1️⃣ Creating test user..."
      USER_RESPONSE=$(curl -s -X POST http://localhost:8080/users \
        -H "Content-Type: application/json" \
        -d '{"username":"testuser","email":"test@example.com"}')
      echo "Response: $USER_RESPONSE"
      
      echo "2️⃣ Creating test order..."
      ORDER_RESPONSE=$(curl -s -X POST http://localhost:8081/orders \
        -H "Content-Type: application/json" \
        -d '{"user_id":1,"product_name":"Test Product","quantity":2,"total_amount":99.99}')
      echo "Response: $ORDER_RESPONSE"

  # 👁️ 可觀測性檢查
  obs-check:
    command: |-
      echo "👁️ Observability Stack Health Check"
      echo "=== OTel Collector ==="
      echo "Health: $(curl -s http://localhost:13133 2>/dev/null || echo 'DOWN')"
      echo "=== Key Metrics ==="
      curl -s http://localhost:8889/metrics 2>/dev/null | grep -E "(otelcol_receiver_received|otelcol_exporter_sent)" | head -10

🔄 智能熱重載:配置變更自動化

🎯 Hooks 自動化

hooks:
  # 🧠 OTel 配置熱重載
  - name: watch-otel-config
    on:
      paths:
        - ./observability/otel-collector/otel-config.yaml
    command: |-
      echo "🔄 [Hook] OTel config changed → reloading..."
      kubectl apply -f ./observability/otel-collector/otel-config.yaml
      kubectl delete pod -l app=otel-collector -n ecommerce --ignore-not-found=true

  # 📝 Fluent Bit 配置熱重載
  - name: watch-fluent-config
    on:
      paths:
        - ./deployments/fluent-bit-config.yaml
    command: |-
      echo "🔄 [Hook] Fluent Bit config changed → reloading..."
      kubectl apply -f ./deployments/fluent-bit-config.yaml
      kubectl delete pod -l app=user-service -n ecommerce --ignore-not-found=true
      kubectl delete pod -l app=order-service -n ecommerce --ignore-not-found=true

🚀 實戰驗證:完整工作流

🎯 啟動序列

# 🎼 一鍵啟動完整平台
> devspace dev --debug

23:38:20 info Using namespace 'ecommerce'
23:38:20 info Using kube context 'kind-demo'
23:38:21 debug Run pipeline:
name: dev
run: |-
    run_dependencies --all
    ensure_pull_secrets --all
    build_images --all
    create_deployments --all
    start_dev --all


23:38:21 run_dependencies --all
23:38:21 Marked project excluded: ecommerce-microservices
23:38:21 Namespace  is the default Devspace namespace
23:38:21 Namespace  is the default Devspace namespace
23:38:21 Namespace  is the default Devspace namespace
23:38:21 otel-collector create_deployments --all
23:38:21 Namespace  is the default Devspace namespace
23:38:21 database run_dependencies --all
23:38:21 order-service run_dependencies --all
23:38:21 user-service run_dependencies --all
23:38:21 database ensure_pull_secrets --all
23:38:21 user-service ensure_pull_secrets --all
23:38:21 database build_images --all
23:38:21 otel-collector Deploying 2 deployments concurrently...
23:38:21 user-service build_images --all
23:38:21 database create_deployments --all
23:38:21 database Deploying 2 deployments concurrently...
23:38:59 debug Wait for dev to finish

佈署完成後,我們能透過 devspace ui 看見所有服務都如預期的起來了。
https://ithelp.ithome.com.tw/upload/images/20250910/20104930MqanCWwXnd.png

能看到 OTel collector 也確實收到了 FluentBit 傳送過來的 application tracing data
https://ithelp.ithome.com.tw/upload/images/20250910/20104930YJoJR6HAxV.png

FluentBit Config

我想回顧的是Host otel-collector.ecommerce.svc.cluster.local,這是很完整的 FQDN格式 。
我們之前有一篇學習 K8s Service
也能是Host otel-collector,畢竟都在同一個namespace下的pod。

https://ithelp.ithome.com.tw/upload/images/20250911/20104930UZzzOL6IRn.png

    # 輸出到 OpenTelemetry Collector
    [OUTPUT]
        Name                 opentelemetry
        Match                app.logs
        Host                 otel-collector.ecommerce.svc.cluster.local
        Port                 4318
        Logs_uri             /v1/logs
        Log_response_payload True
        Tls                  Off
        Tls.verify           Off
        # 🔥 使用環境變數動態添加資源屬性
        add_label            service.name ${SERVICE_NAME}
        add_label            service.version ${SERVICE_VERSION}
        add_label            deployment.environment ${ENVIRONMENT}

總結

恩...就零散的服務慢慢連結起來了。
有需要的話也是能透過之前分享過得 DevSpace Profile,來決定啟用多少服務。

# ================
# Profiles (不同運行模式)
# ================
profiles:
  - name: apps-only
    description: "只啟動應用服務,不包含觀測組件"
    replace:
      pipelines:
        dev:
          run: |-
            echo "🔧 Apps-only mode"
            create_deployments services
            run_dependencies database
            start_dev user-service
            start_dev order-service

  - name: obs-only
    description: "只啟動觀測組件"
    replace:
      pipelines:
        dev:
          run: |-
            echo "👁️ Observability-only mode"
            create_deployments services
            run_dependencies otel-collector
            start_dev otel-collector

  - name: minimal
    description: "最小化部署,單一副本"
    patches:
      - op: replace
        path: deployments.services.kubectl.manifests
        value:
          - ./deployments/fluent-bit-config.yaml

  - name: debug
    description: "除錯模式,開啟所有日誌和端口"
    patches:
      - op: add
        path: dev.user-service.open
        value:
          - url: http://localhost:8080
      - op: add
        path: dev.order-service.open
        value:
          - url: http://localhost:8081

今天我們完成了從「分散管理」到「統一指揮」的重大躍進。這不只是技術整合,更是思維模式的轉變。就像從手工作坊進化到現代化工廠,我們建立了標準化、自動化、可觀測的微服務平台。
記住:優秀的架構規劃不是寫最多程式的人,而是用最少的配置實現最大價值的人。DevSpace 讓我們做到了這一點!


上一篇
DevSpace 驅動的 OpenTelemetry Collector:一鍵部署可觀測性中樞 🎯🚀
系列文
賢者大叔的容器修煉手札26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言