Kafka: GitHub Actions 與 GitLab CI

直接從您的 GitHub Actions 或 GitLab CI pipeline 啟動一個真實的 Kafka 服務,執行測試,並自動銷毀服務

👋 歡迎來到 Stackhero 文件中心!

Stackhero 讓您輕鬆開始使用全受管理的 Kafka cloud 解決方案。您可以期待以下特色:

  • 無限制的訊息大小與傳輸,滿足您日益成長的資料需求。
  • 輕鬆更新,只需一鍵即可套用最新改進。
  • 頂級效能與強大安全性,全部運行於您專屬的私有專用 VM

如果您想節省時間並簡化工作流程,非常推薦您試用 Stackhero 的 Kafka cloud hosting。只需約 5 分鐘即可快速上線!

本指南將帶您一步步在 CI pipeline 中運行一個真實、專屬的 Kafka 服務,可選擇 GitHub ActionsGitLab CI。依照這些步驟,您可以在接近正式環境的條件下,針對實際的 Kafka 實例測試您的程式碼,無需再依賴 mock 或模擬器。Apache Kafka is a distributed event streaming platform built to carry huge streams of events through your systems in real time.

每次 pipeline 執行時,您都會獲得一個全新的 Kafka 實例。這代表您的測試將與正式環境中用戶所見的服務完全一致。此流程會自動建立一個臨時 stack,新增 Kafka,等待服務就緒,取得產生的認證資訊,利用 netcat (a TCP check) 執行 smoke test,最後在流程結束時自動清理所有資源。

您將會使用 Stackhero CLI,這是一個獨立的命令列工具,可讓您快速且簡單地啟動與管理 Stackhero 服務。

為了讓 CLI 能以非互動方式運作,您需要一組 access token(格式:usr-xxxxxx:tokenId)。這個 token 只需建立一次,然後將其加入您的 CI pipeline,作為安全加密的機密變數。

  1. 建立 token: 在您的 Stackhero 控制台,點擊右上角的大頭貼,進入 您的帳戶,選擇 Access tokens,然後點擊 Create token
  2. GitHub Actions: 在您的 repository,前往 Settings > Secrets and variables > Actions > New repository secret,將 token 輸入為 STACKHERO_TOKEN
  3. GitLab CI: 在您的專案,前往 Settings > CI/CD > Variables > Add variable,將 key 設為 STACKHERO_TOKEN,並勾選 Masked(如果您的 CI 僅在受保護分支執行,也可勾選 Protected)。

請勿將 access token 直接寫在 pipeline 的 YAML 檔案中。如果 token 出現在 YAML 內,任何有 repository 存取權的人都可能看到,甚至可能出現在建置日誌中。將其儲存為 CI 機密可確保加密與遮蔽,讓您的 token 保持安全。

以下是一個完整的腳本範例,涵蓋服務的全生命週期。您會發現設定非常簡單,只需幾個指令即可。您可以直接從下方各平台區段複製對應的 YAML 配置。

#!/bin/bash
set -euo pipefail

# STACKHERO_TOKEN 由 CI 機密提供,CLI 會自動讀取。

stackName="ci-kafka-$$"          # 每次執行唯一的 stack 名稱
serviceStore="kafka"             # Kafka 服務 store
instance="10G"        # 如有需要可調整(見步驟 3)
region="europe"                         # 區域名稱(可用 stackhero regions-list 查詢)

# 1. 在 runner 上安裝 CLI
curl -fsSL https://www.stackhero.io/install.sh | sh

# 2. 安裝 smoke test 所需的 client(jq + curl 為基本需求)
apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd

# 3. 為本次執行建立專屬 stack
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack created: $stackId"

# 4. 新增 Kafka 並取得其 service id
serviceId=$(stackhero --format=script service-add \
  --stack="$stackId" \
  --service-store="$serviceStore" \
  --instance="$instance" \
  --region="$region")
echo "Service added: $serviceId"

# 5. 等待服務啟動(可能需數分鐘)
stackhero service-wait-for --service="$serviceId"

# 6. 讀取設定(包含產生的認證資訊)
config=$(stackhero service-configuration-get --service="$serviceId" --format=json)

# 7. 取得所需認證資訊
host=$(echo "$config" | jq -r '.configuration.domain')

# 8. Smoke test:Open a TCP connection to the broker port.
nc -z -w 5 "$host" 9092

echo "✅ Kafka 已可從 CI 存取。"

資源清理(刪除服務、等待刪除完成、再刪除 stack)會在下方各平台專屬區段說明。這種做法可確保即使 smoke test 失敗也會進行完整清理。

Stack 必須為空才能刪除。請務必先刪除服務並等待其移除,再刪除 stack。service-wait-for 指令可確保服務已啟動或已刪除,是等待刪除的最佳工具。

下方範例預設使用 Kafka 的入門實例 10G。這對大多數工作負載來說已相當合適,您也可依需求調整。若要查詢 Kafka 所有可用實例類型,可執行:

# NAME 欄位即為 --instance 參數值
stackhero instances-store-list --service-store=kafka

請將下列內容儲存為 .github/workflows/ci.yml。從此之後,每次 push 或 pull request 都會針對真實的 Kafka 實例執行測試。

name: 使用 Kafka  CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
      STACK_NAME: ci-kafka-${{ github.run_id }}-${{ github.run_attempt }}
      INSTANCE: "10G"   # 如有需要可調整(見步驟 3)
      REGION: europe
    steps:
      - uses: actions/checkout@v4

      - name: 安裝 Stackhero CLI  client
        run: |
          curl -fsSL https://www.stackhero.io/install.sh | sh
          apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd

      - name: 建立 Kafka 服務
        run: |
          set -euo pipefail
          STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
          echo "STACK_ID=$STACK_ID" >> "$GITHUB_ENV"
          SERVICE_ID=$(stackhero --format=script service-add \
            --stack="$STACK_ID" \
            --service-store="kafka" \
            --instance="$INSTANCE" \
            --region="$REGION")
          echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
          stackhero service-wait-for --service="$SERVICE_ID"

      - name: 執行 Kafka 測試
        run: |
          set -euo pipefail
          config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
          host=$(echo "$config" | jq -r '.configuration.domain')
          # Open a TCP connection to the broker port.
          nc -z -w 5 "$host" 9092
          echo "✅ Kafka 已可從 CI 存取。"
          # 您也可以在此使用上述認證資訊執行自訂測試 ...

      - name: 清理資源(無論成功或失敗皆執行)
        if: always()
        run: |
          if [ -n "${SERVICE_ID:-}" ]; then
            stackhero service-delete --service="$SERVICE_ID" --confirm
            stackhero service-wait-for --service="$SERVICE_ID"
          fi
          if [ -n "${STACK_ID:-}" ]; then
            stackhero stack-delete --stack="$STACK_ID" --confirm
          fi

清理步驟設定為 if: always(),確保無論流程結果如何都會執行,讓您的 Kafka 實例被刪除,避免產生不必要的資源費用。

請將下列設定儲存為 .gitlab-ci.yml。每次 pipeline 執行時都會建立一個全新的 Kafka 實例供測試使用。

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-kafka-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "10G"   # 如有需要可調整(見步驟 3)
    REGION: "europe"
    SERVICE_STORE: "kafka"
  # STACKHERO_TOKEN 來自您於步驟 1 建立的 CI/CD 變數。
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
    # Open a TCP connection to the broker port.
    - nc -z -w 5 "$host" 9092
    - echo "✅ Kafka 已可從 CI 存取。"
    # 您也可以在此使用上述認證資訊執行自訂測試 ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

在 GitLab 中,資源清理會寫在 after_script 區塊。這個區塊無論 job 成功或失敗都會執行,確保您的 Kafka 資源被移除,避免產生不必要的費用。

在 GitLab,after_script 會在一個全新 shell中執行。為了處理這點,腳本會在 job 過程中將 service 與 stack 的 ID 寫入 deploy.env,並於清理前重新載入。如此即使 job 執行中途失敗,您的資源仍能被正確清除。

這就是 Kafka 的完整 CI 生命週期:建立 stack、加入服務、等待、取得認證、smoke test,並始終進行清理。每次 pipeline 執行都會獲得一個真實、隔離的服務,流程結束後不會有任何資源殘留。如需更多可用指令與非互動式 STACKHERO_TOKEN 認證說明,歡迎參考 完整 CLI 文件