Apache Kafka 作為一個高吞吐量的分散式事件串流平台,已成為現代資料架構的核心組件。然而,其依賴 ZooKeeper 進行協調管理的特性,使得傳統部署流程相對繁瑣。透過 Docker 容器化技術,能將 Kafka 與其依賴環境封裝成獨立、可攜的單元,不僅大幅簡化了開發與測試環境的建置複雜度,也確保了不同環境之間的一致性與可重複性。這種部署模式實現了資源隔離與快速擴展,為開發者提供了一個高效且穩定的 Kafka 實驗與應用基礎,使其能更專注於消息系統的架構設計與業務邏輯實現。

部署與啟動 Apache Kafka 環境:Docker 實踐指南

本節將引導讀者完成部署 Apache Kafka 所需的環境設置,包括安裝 Docker、下載必要的 Docker 映像檔,以及啟動 ZooKeeper 和 Kafka 服務的 Docker 容器。

環境準備與軟體需求

在開始部署 Kafka 之前,確保您的系統滿足以下軟體需求:

  • Docker: 版本 1.8 或更高版本。
  • Apache ZooKeeper Docker 映像檔: 使用 dockerkafka/zookeeper 映像檔(最新版本)。
  • Apache Kafka Docker 映像檔: 使用 dockerkafka/kafka 映像檔(最新版本)。

假設您已透過 SSH 連接到一台 Amazon EC2 實例,並擁有相應的私鑰(例如 docker.pem)來進行訪問。SSH 連接的範例命令如下:

ssh -i "docker.pem" ec2-user@52.91.168.33

安裝與啟動 Docker 服務

在 EC2 實例上,首先需要安裝 Docker 並啟動其服務。

  1. 啟動 Docker 服務: 執行以下命令來啟動 Docker:
    sudo service docker start
    
    若命令執行成功,您將看到一個「OK」的提示信息,表明 Docker 服務已成功啟動。

下載 Docker 映像檔

接下來,需要從 Docker Hub 下載 Apache ZooKeeper 和 Apache Kafka 的 Docker 映像檔。

  1. 下載 ZooKeeper 映像檔: 執行以下命令下載 dockerkafka/zookeeper 映像檔:

    sudo docker pull dockerkafka/zookeeper
    

    下載過程將顯示映像檔的層級信息,直至下載完成。

  2. 下載 Kafka 映像檔: 選擇 dockerkafka/zookeeper 是因為存在對應的 dockerkafka/kafka 映像檔,這使得兩者能夠良好地協同工作。下載 Kafka 映像檔:

    sudo docker pull dockerkafka/kafka
    

    同樣,下載過程將顯示進度,直至完成。

啟動 Kafka 集群所需的 Docker 容器

一個完整的 Kafka 集群需要 Apache ZooKeeper 來進行協調和管理,以及 Kafka Broker 本身來處理消息。因此,我們需要同時啟動這兩個服務的 Docker 容器。

  1. 啟動 ZooKeeper 容器: 使用 docker run 命令啟動一個 detached 模式(後台運行)的 ZooKeeper 容器。我們將 ZooKeeper 的默認端口 2181 映射到主機的 2181 端口,並為容器命名為 zookeeper

    sudo docker run -d --name zookeeper -p 2181:2181 dockerkafka/zookeeper
    
    • -d: detached 模式,容器在後台運行。
    • --name zookeeper: 為容器指定一個易於識別的名稱。
    • -p 2181:2181: 將主機的 2181 端口映射到容器的 2181 端口。
  2. 啟動 Kafka 容器: 接下來,啟動 Kafka Broker 的容器。我們將 Kafka 的默認端口 9092 映射到主機的 9092 端口。關鍵的是,我們使用 --link 參數將 Kafka 容器與 ZooKeeper 容器連接起來,這樣 Kafka 就能夠通過名稱 zookeeper 訪問到 ZooKeeper 服務。

    sudo docker run --name kafka -p 9092:9092 --link zookeeper:zookeeper dockerkafka/kafka
    
    • --name kafka: 為 Kafka 容器指定名稱。
    • -p 9092:9092: 將主機的 9092 端口映射到容器的 9092 端口。
    • --link zookeeper:zookeeper: 將當前容器連結到名為 zookeeper 的容器,並在容器內部將 zookeeper 解析為其 IP 地址。

驗證容器運行狀態

為了確認 ZooKeeper 和 Kafka 容器是否已成功啟動並在運行,可以使用 docker ps 命令。

docker ps

此命令將列出所有當前正在運行的 Docker 容器,您應該能看到名為 zookeeperkafka 的兩個容器。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "EC2 Instance" as EC2_INSTANCE
object "Docker Service" as DOCKER_SERVICE
object "Docker Hub" as DOCKER_HUB
object "ZooKeeper Image" as ZOOKEEPER_IMAGE
object "Kafka Image" as KAFKA_IMAGE
object "ZooKeeper Container" as ZOOKEEPER_CONTAINER
object "Kafka Container" as KAFKA_CONTAINER
object "Kafka Cluster" as KAFKA_CLUSTER

partition "Environment Setup" {
  EC2_INSTANCE --> DOCKER_SERVICE : Install & Start Docker
  DOCKER_SERVICE --> DOCKER_HUB : Pull Images
  DOCKER_HUB --> ZOOKEEPER_IMAGE : Download dockerkafka/zookeeper
  DOCKER_HUB --> KAFKA_IMAGE : Download dockerkafka/kafka
}

partition "Container Deployment" {
  EC2_INSTANCE --> DOCKER_SERVICE : Run Container Commands
  DOCKER_SERVICE --> ZOOKEEPER_CONTAINER : Create & Start ZooKeeper (Port 2181, Detached)
  DOCKER_SERVICE --> KAFKA_CONTAINER : Create & Start Kafka (Port 9092, Linked to ZooKeeper)
  ZOOKEEPER_CONTAINER --> KAFKA_CLUSTER : Provides Coordination
  KAFKA_CONTAINER --> KAFKA_CLUSTER : Acts as Broker
}

partition "Verification" {
  EC2_INSTANCE --> DOCKER_SERVICE : List Running Containers
  DOCKER_SERVICE --> EC2_INSTANCE : Output of 'docker ps'
  note right of EC2_INSTANCE
    Verify 'zookeeper' and 'kafka' containers are listed.
  end note
}

@enduml

看圖說話:

此圖示清晰地描繪了部署 Apache Kafka 環境的完整流程,從環境準備到容器啟動的關鍵步驟。圖的左側部分展示了在 EC2 實例上進行的準備工作,包括安裝和啟動 Docker 服務,以及從 Docker Hub 下載 ZooKeeper 和 Kafka 的 Docker 映像檔。中間部分詳細說明了如何創建和啟動這兩個核心容器:首先,一個 detached 模式的 ZooKeeper 容器被啟動,並將其 2181 端口映射到主機;接著,Kafka 容器被啟動,映射其 9092 端口,並通過 --link 參數與 ZooKeeper 容器建立連接,從而構建了一個基本的 Kafka 集群。右側部分則展示了如何使用 docker ps 命令來驗證這兩個容器是否成功運行,確保了環境部署的有效性。整體流程圖直觀地展示了從基礎設施到應用服務的部署過程。

Apache Kafka 實戰:從容器部署到消息流轉

本節將詳細介紹如何利用 Docker 環境部署並配置 Apache Kafka,包括獲取容器 IP 地址、查看服務日誌、創建消息主題、啟動消息生產者與消費者,並最終實現消息的生產與消費流程。

獲取 Kafka 與 ZooKeeper 容器的 IP 地址

為了讓 Kafka producer 和 consumer 能夠正確地與 Kafka 集群通信,我們需要獲取運行 ZooKeeper 和 Kafka 服務的 Docker 容器的內部 IP 地址。

  1. 導出環境變量: 使用 docker inspect 命令配合 --format 選項,可以提取容器網絡設置中的 IP 地址。我們將這些 IP 地址分別導出到 ZK_IPKAFKA_IP 環境變量中。

    export ZK_IP=$(sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' zookeeper)
    export KAFKA_IP=$(sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' kafka)
    

    執行後,zookeeper 容器的 IP 地址(例如 172.17.0.1)將被賦值給 ZK_IP,而 kafka 容器的 IP 地址(例如 172.17.0.2)則被賦值給 KAFKA_IP

  2. 驗證 IP 地址: 使用 echo 命令可以查看這些環境變量的值,確認 IP 地址是否正確獲取。

    echo $ZK_IP
    echo $KAFKA_IP
    

    這些 IP 地址將在後續的 Kafka 操作中使用。

查看 Kafka 服務日誌

為了確認 Kafka 服務是否已成功啟動並正常運行,我們可以查看 Kafka 容器的日誌。

  1. 輸出 Kafka 日誌: 使用 docker logs 命令並加上 -f 選項(跟蹤日誌輸出),可以實時查看 kafka 容器的日誌。
    sudo docker logs -f kafka
    
    日誌輸出將顯示 Kafka 服務的啟動過程和狀態信息,確認 Kafka 服務已成功啟動。

創建 Kafka 消息主題 (Topic)

在 Kafka 中,消息被組織在稱為「Topic」的邏輯分類中。在生產者發布消息之前,需要先創建一個 Topic。

  1. 進入 Kafka 容器的交互式終端: 使用 docker exec -it 命令進入正在運行的 kafka 容器的 bash 環境。

    sudo docker exec -it kafka bash
    
  2. 創建 Topic: 在容器的交互式終端中,執行 kafka-topics.sh 腳本來創建 Topic。

    kafka-topics.sh --create --topic test --zookeeper $ZK_IP:2181 --replication-factor 1 --partitions 1
    
    • --create: 指定創建操作。
    • --topic test: 指定要創建的 Topic 名稱為 “test”。
    • --zookeeper $ZK_IP:2181: 指定 ZooKeeper 的地址和端口,使用之前獲取的 ZK_IP
    • --replication-factor 1: 設置 Topic 的副本因子為 1(在單節點環境下)。
    • --partitions 1: 設置 Topic 的分區數為 1。 命令執行成功後,會輸出「Created topic “test”」。

啟動 Kafka 消息生產者 (Producer)

Kafka 生產者負責將消息發布到指定的 Topic。

  1. 啟動控制台生產者: 在另一個終端窗口(或者在容器內執行,但通常建議使用新終端以方便交互),啟動 Kafka 的控制台生產者。
    kafka-console-producer.sh --topic test --broker-list $KAFKA_IP:9092
    
    • --topic test: 指定消息將被發布到 “test” Topic。
    • --broker-list $KAFKA_IP:9092: 指定 Kafka Broker 的地址和端口,使用之前獲取的 KAFKA_IP。 啟動後,您將看到一個提示符,表示生產者已準備好接收輸入。

啟動 Kafka 消息消費者 (Consumer)

Kafka 消費者負責訂閱 Topic 並接收其中的消息。

  1. 進入 Kafka 容器的交互式終端: 如果尚未進入,請再次使用 docker exec -it 命令進入 kafka 容器的 bash 環境。

    sudo docker exec -it kafka bash
    
  2. 啟動控制台消費者: 在容器的交互式終端中,執行 kafka-console-consumer.sh 腳本來啟動消費者。

    kafka-console-consumer.sh --topic test --from-beginning --zookeeper $ZK_IP:2181
    
    • --topic test: 指定要消費的 Topic 名稱為 “test”。
    • --from-beginning: 指示消費者從 Topic 的最開始位置開始消費消息,確保所有已發布的消息都能被接收。
    • --zookeeper $ZK_IP:2181: 指定 ZooKeeper 的地址和端口。 啟動後,消費者將等待並顯示從 Topic 中接收到的消息。

生產與消費消息

現在,生產者和消費者都已準備就緒。

  1. 在生產者終端輸入消息: 在啟動 Kafka 生產者的終端中,輸入任意文本,例如 “Hello Kafka!",然後按 Enter 鍵。

  2. 觀察消費者終端: 您會立即在啟動 Kafka 消費者的終端中看到您剛才輸入的消息 “Hello Kafka!” 被打印出來。這證明了消息成功地從生產者發布到 Topic,並被消費者及時接收。您可以繼續在生產者終端輸入更多消息,並觀察它們如何被消費者消費。

看圖說話:

此圖示全面展示了 Apache Kafka 的部署、配置和消息流轉過程。圖的左側部分描述了如何獲取運行 ZooKeeper 和 Kafka 的 Docker 容器的 IP 地址,並通過 docker logs 命令驗證 Kafka 服務的運行狀態。中間部分詳細闡述了創建 Kafka Topic 的步驟,包括進入容器的交互式終端,並使用 kafka-topics.sh 腳本指定 Topic 名稱、ZooKeeper 地址、副本因子和分區數。右側部分則展示了如何啟動 Kafka 生產者和消費者,並實現消息的生產與消費。生產者將消息發布到指定的 Topic,而消費者則從 Topic 的起始位置接收並顯示這些消息。整個流程圖清晰地展示了從環境設置到消息傳遞的完整生命週期,突顯了 Kafka 在分布式消息系統中的關鍵作用。

結論

縱觀這套從環境建置到訊息流轉的完整實踐,其核心價值不僅是技術操作的簡化,更是對傳統基礎設施部署思維的顛覆。相較於傳統的實體機部署,容器化方案顯著降低了團隊導入高階數據工具的門檻,將環境配置的複雜性予以抽象化,實現了開發與測試環境的高度一致性。然而,管理者需清晰認知,此一快捷部署模式雖為敏捷開發的起點,但從原型邁向生產級應用,仍需克服數據持久化、叢集監控與資安策略等進階挑戰,這正是技術紅利背後的隱性成本。

可以預見,將核心數據組件容器化,將成為企業推動微服務架構與即時數據應用的標準路徑。這種「數據基礎設施即程式碼」(Data-Infrastructure-as-Code)的模式,賦予了開發團隊前所未有的自主性與迭代速度,加速了從數據洞察到商業價值的轉化週期。

玄貓認為,對於追求技術卓越與業務敏捷性的高階管理者而言,洞察並投資這類技術整合所帶來的結構性優勢,遠比單純完成一次部署更具長期戰略價值。這代表著組織技術文化從「維運驅動」向「開發驅動」的關鍵轉變。