在分散式系統中,跨資料中心資料複製和安全性是兩大關鍵議題。本文首先介紹 Uber 的 uReplicator 和 LinkedIn 的 Brooklin 等方案,如何解決 Kafka 跨資料中心映象的挑戰。接著,文章探討 Kafka 安全性的重要性,並詳細說明身份驗證、授權、加密、稽核和配額等機制,如何確保資料的機密性和完整性。最後,文章提供 SSL/TLS 的實作,包含監聽器組態、客戶端設定、憑證管理等實務技巧,協助工程師開發更安全的 Kafka 環境。
跨資料中心映象解決方案的演進與實作
在處理跨資料中心或跨叢集的資料複製時,企業經常面臨到擴充套件性、容錯性和操作的挑戰。傳統的 MirrorMaker 工具雖然能滿足基本需求,但在規模擴大後,其維護和操作上的困難促使各大企業開發自有的解決方案。本篇文章將探討 Uber 的 uReplicator、LinkedIn 的 Brooklin,以及 Confluent 提供的多種跨資料中心映象解決方案。
Uber 的 uReplicator
Uber 在使用傳統 MirrorMaker 時遇到了諸多問題,包括難以維護的 topic 名稱列表、頻繁的 rebalance 等。為瞭解決這些問題,Uber 開發了 uReplicator,一個根據 Apache Helix 的 MirrorMaker 分支。uReplicator 使用 Apache Helix 作為中央控制器來管理 topic 列表和分割槽分配,避免了傳統 MirrorMaker 的 rebalance 問題。
關鍵技術:
- Apache Helix:作為中央控制器管理分割槽分配。
- Helix Consumer:取代了 Kafka 消費者,直接從 Helix 取得分割槽分配。
程式碼範例:
// Helix Consumer 的基本組態範例
Properties props = new Properties();
props.put("group.id", "ureplicator-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
HelixConsumer consumer = new HelixConsumer(props);
consumer.subscribe("topic-name");
內容解密:
- Helix Consumer 組態:這裡展示瞭如何初始化一個 Helix Consumer,包括設定 group.id 和反序列化器。
- 訂閱 Topic:透過
subscribe方法訂閱指定的 topic。
LinkedIn 的 Brooklin
LinkedIn 也面臨了類別似的挑戰,並開發了 Brooklin,一個通用的資料流系統,不僅能用於 Kafka 叢集之間的映象,也能支援其他異構資料源之間的資料傳輸。
關鍵技術:
- 分散式服務:設計用於高可靠性,能夠處理大量的資料管道。
- REST API:提供管理介面,用於操作和監控。
Brooklin 架構圖
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 關鍵技術:
rectangle "資料流" as node1
rectangle "傳輸" as node2
rectangle "控制" as node3
node1 --> node2
node2 --> node3
@enduml此圖示展示了 Brooklin 的基本架構,包括資料源、資料流向目標系統,以及 REST API 的控制介面。
Confluent 的跨資料中心映象解決方案
Confluent 提供了多種解決方案,包括 Confluent Replicator 和 Multi-Region Clusters (MRC)。
Confluent Replicator
根據 Kafka Connect 框架,支援多種拓撲結構的資料複製,並提供豐富的監控指標。
Multi-Region Clusters (MRC)
結契約步和非同步複製,提供低延遲和高耐久性,適合跨區域佈署。
多叢集管理與安全性的強化
在前一章節中,我們探討了多叢集架構的設計與實作,並比較了不同的 Failover 架構與工具選擇。現在,我們將進一步討論 Kafka 的安全性議題,這對於建構一個穩固且可靠的資料處理系統至關重要。
Kafka 安全性的重要性
Kafka 廣泛應用於各種場景,從網站活動追蹤、指標管道到病患紀錄管理和線上支付。每種使用案例對安全性、效能、可靠性和可用性都有不同的要求。雖然使用最強大和最新的安全功能總是首選,但增加安全性往往會影響效能、成本和使用者經驗,因此需要在這些因素之間進行權衡。
Kafka 的安全功能
Kafka 支援多種標準安全技術,並提供一系列組態選項,以便根據每個使用案例量身定製安全性。就像效能和可靠性一樣,安全性是整個系統必須解決的一個方面,而不是單獨針對某個元件。系統的安全性取決於最薄弱的環節,因此必須在整個系統中實施安全流程和政策,包括底層平台。
主要安全機制
- 身份驗證(Authentication):確認身份,確定「你是誰」。
- 授權(Authorization):決定「你被允許做什麼」。
- 加密(Encryption):保護資料免受竊聽和篡改。
- 稽核(Auditing):跟蹤「你做了什麼」或「你試圖做什麼」。
- 配額(Quotas):控制「你可以利用多少資源」。
鎖定 Kafka 佈署
要了解如何鎖定 Kafka 佈署,首先需要檢視資料如何在 Kafka 叢集中流動。圖 11-1 說明瞭一個範例資料流程中的主要步驟。在本章中,我們將使用這個範例流程來檢查 Kafka 可以組態的不同方式,以保護每個步驟中的資料,確保整個佈署的安全性。
資料流程範例
- Alice 向名為
customerOrders的主題的某個分割槽生成一條客戶訂單記錄,該記錄被傳送到該分割槽的長官者。 - 長官者 broker 將記錄寫入其本地日誌檔案。
- 一個 follower broker 從長官者那裡取得訊息並寫入其本地副本日誌檔案。
- 長官者 broker 更新 ZooKeeper 中的分割槽狀態,以更新同步副本(如有必要)。
- Bob 從
customerOrders主題消費客戶訂單記錄,接收由 Alice 生成的記錄。
安全性最佳實踐
在本章中,我們將討論 Kafka 中的安全功能,並探討它們如何解決不同的安全問題,為整個 Kafka 安裝的安全性做出貢獻。同時,我們還將分享最佳實踐、潛在威脅以及緩解這些威脅的技術。此外,我們還將檢視用於保護 ZooKeeper 和其他平台元件的其他措施。
加強 Kafka 的安全措施
為了確保 Kafka 叢集的安全,需要採取一系列措施來保護資料在傳輸和儲存過程中的安全性。這包括但不限於加密、身份驗證和授權機制。
使用加密保護資料
加密是保護資料免受未授權存取的重要手段。Kafka 支援使用 SSL/TLS 對資料進行加密傳輸,以防止資料在傳輸過程中被竊聽或篡改。
身份驗證和授權
Kafka 提供了多種身份驗證機制,包括 SSL/TLS 客戶端身份驗證、SASL/PLAIN 和 SASL/SCRAM 等。這些機制可以確保只有授權的使用者和應用程式能夠存取 Kafka 叢集。此外,Kafka 的授權機制允許管理員對使用者的操作進行細粒度的控制,例如允許或拒絕使用者對特定主題的讀寫操作。
稽核和監控
為了及時發現潛在的安全威脅,需要對 Kafka 叢集進行稽核和監控。這包括跟蹤使用者的操作、日誌分析和效能監控等。透過這些措施,可以及時發現異常行為並採取相應的措施。
Kafka 安全佈署
在現代分散式系統中,訊息佇列扮演著至關重要的角色。Apache Kafka 作為一個高效能、具擴充套件性的訊息佇列系統,其安全佈署對於保障資料傳輸的可靠性與隱私性至關重要。本文將探討 Kafka 的安全特性,分析如何實作使用者端與伺服器端的身份驗證、資料加密、存取控制等關鍵安全措施。
安全需求分析
在設計 Kafka 安全佈署方案時,需要滿足以下核心安全需求:
- 使用者端真實性:當使用者端(如 Alice)建立與 Kafka 代理的連線時,代理需驗證使用者端的身份,確保訊息來源的真實性。
- 伺服器端真實性:在使用者端傳送訊息前,需驗證其連線的是否為真正的 Kafka 代理,防止中間人攻擊。
- 資料隱私:所有傳輸中的資料以及儲存訊息的磁碟都需要進行加密或物理保護,以防止資料被竊取或竄改。
- 資料完整性:在不安全的網路傳輸中,需包含訊息摘要以檢測資料是否被竄改。
- 存取控制:Kafka 代理在寫入訊息到日誌前,需驗證使用者端是否有寫入特定主題的許可權;同樣,在傳回訊息給消費者時,也需驗證其是否有讀取該主題的許可權。
- 可稽核性:系統需記錄所有由代理、生產者、消費者等執行的操作,以供稽核使用。
- 可用性:Kafka 代理需實施配額和限制,以防止某些使用者佔用所有可用頻寬或發起拒絕服務攻擊。
安全協定
Kafka 支援多種安全協定,以滿足不同的安全需求。這些協定結合了傳輸層(PLAINTEXT 或 SSL)與可選的身份驗證層(SSL 或 SASL):
- PLAINTEXT:無身份驗證的明文傳輸,僅適用於處理非敏感資料的私有網路。
- SSL:支援加密以及使用者端和伺服器端的身份驗證,適用於不安全的網路環境。
- SASL_PLAINTEXT:使用 SASL 進行使用者端身份驗證,但不支援加密,僅適用於私有網路。
- SASL_SSL:結合 SSL 傳輸層與 SASL 身份驗證,支援加密和雙向身份驗證,適用於不安全的網路環境。
TLS/SSL 技術詳解
TLS(Transport Layer Security)是一種廣泛使用的加密協定,用於在公網上提供資料傳輸的隱私性和完整性。其依賴於公開金鑰基礎設施(PKI)來建立和管理數位憑證,實作非對稱加密,並在握手過程中生成對稱加密的會話金鑰,以提高後續資料傳輸的效率。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title TLS/SSL 技術詳解
rectangle "TLS 握手" as node1
rectangle "憑證驗證" as node2
rectangle "會話金鑰生成" as node3
rectangle "加密資料傳輸" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml此圖示說明瞭 TLS 握手過程及憑證驗證機制,使用者端與伺服器端透過 TLS 協定建立安全的連線。
組態與實作
為了實作 Kafka 的安全佈署,需對 Kafka 代理進行相應的安全組態,包括但不限於:
- 設定
inter.broker.listener.name或security.inter.broker.protocol以選擇用於代理間通訊的安全協定。 - 為不同監聽器組態不同的安全設定,以滿足不同網路環境下的安全需求。
程式碼範例
# Kafka 代理組態範例
listeners=SSL://localhost:9093
security.inter.broker.protocol=SSL
ssl.keystore.location=/path/to/keystore.jks
ssl.keystore.password=keystore_password
ssl.key.password=key_password
內容解密:
此組態範例展示瞭如何為 Kafka 代理設定 SSL/TLS 安全協定,包括指定監聽器、安全協定、以及金鑰儲存位置和密碼。這些設定確保了代理間通訊的安全性。
listeners=SSL://localhost:9093指定了 Kafka 代理監聽 SSL 連線的位址和埠號。security.inter.broker.protocol=SSL設定了代理間通訊使用 SSL/TLS 協定。ssl.keystore.location和相關密碼欄位指定了金鑰儲存的位置和密碼,用於存放伺服器的私鑰和憑證。
Kafka 安全組態與 SSL/TLS 實作
Kafka 的安全性對於現代分散式系統至關重要,尤其是在處理敏感資料時。正確組態 Kafka 的安全設定,可以有效保護資料傳輸過程中的機密性與完整性。本文將探討 Kafka 的 SSL/TLS 組態,以及相關的安全機制。
監聽器組態與安全協定對映
在 Kafka 中,監聽器(listeners)的組態是安全架構的基礎。以下是一個典型的組態範例:
listeners=EXTERNAL://:9092,INTERNAL://10.0.0.2:9093,BROKER://10.0.0.2:9094
advertised.listeners=EXTERNAL://broker1.example.com:9092,INTERNAL://broker1.local:9093,BROKER://broker1.local:9094
listener.security.protocol.map=EXTERNAL:SASL_SSL,INTERNAL:SSL,BROKER:SSL
inter.broker.listener.name=BROKER
內容解密:
listeners定義了 Kafka broker 監聽的三個不同介面:外部存取、內部通訊和 broker 間通訊。advertised.listeners指定了客戶端應該連線的實際位址。listener.security.protocol.map將每個監聽器對映到特定的安全協定:EXTERNAL使用 SASL_SSL(需要身份驗證和加密)INTERNAL和BROKER使用 SSL(僅加密)
inter.broker.listener.name指定了 broker 之間通訊使用的監聽器名稱。
客戶端組態與安全協定
客戶端需要正確組態安全協定和引導伺服器:
security.protocol=SASL_SSL
bootstrap.servers=broker1.example.com:9092,broker2.example.com:9092
內容解密:
security.protocol=SASL_SSL指定客戶端使用 SASL_SSL 協定連線到 Kafka。bootstrap.servers列出了初始連線的 broker 位址,用於取得叢集的 metadata。
身份驗證機制
Kafka 使用身份驗證來建立客戶端和伺服器的身份。主要有兩種方式:
- 伺服器身份驗證:確保客戶端連線到正確的 broker。
- 客戶端身份驗證:驗證客戶端的身份,防止冒充。
Kafka 使用 KafkaPrincipal 代表客戶端身份,用於授權和配額管理。
SSL/TLS 組態詳解
當使用 SSL 或 SASL_SSL 時,TLS 成為連線的安全傳輸層。主要步驟包括:
- 伺服器組態:broker 需要組態 key store 包含私鑰和憑證。
- 客戶端組態:客戶端需要組態 trust store 包含 broker 憑證或 CA 憑證。
- 憑證驗證:客戶端驗證伺服器主機名稱是否與憑證中的 Subject Alternative Name (SAN) 或 Common Name (CN) 相符。
SSL效能考量
SSL 加密會引入額外的 CPU 開銷,可能導致效能下降 20-30%。主要原因包括:
- 加密和解密過程需要額外的運算資源。
- 目前不支援 SSL 的 zero-copy 傳輸。
主機名稱驗證的重要性
預設情況下,Kafka 客戶端會驗證伺服器憑證中的主機名稱。這是防止中間人攻擊的重要機制,在生產環境中不應停用。
客戶端身份驗證組態
可以透過設定 ssl.client.auth=required 強制要求客戶端提供憑證進行身份驗證。客戶端需要組態 key store,而 broker 需要組態 trust store 來驗證客戶端憑證。
ssl.client.auth=requested
將客戶端身份驗證設定為可選,未提供憑證的客戶端將被視為 User:ANONYMOUS。
建立金鑰函式庫和信任函式庫
以下是建立自簽名 CA 和相關憑證的步驟:
# 生成自簽名 CA 金鑰對
$ keytool -genkeypair -keyalg RSA -keysize 2048 -keystore server.ca.p12 \
-storetype PKCS12 -storepass server-ca-password -keypass server-ca-password \
-alias ca -dname "CN=BrokerCA" -ext bc=ca:true -validity 365
# 匯出 CA 憑證
$ keytool -export -file server.ca.crt -keystore server.ca.p12 \
-storetype PKCS12 -storepass server-ca-password -alias ca -rfc
內容解密:
- 使用
keytool建立一個 PKCS12 格式的金鑰函式庫server.ca.p12。 - 設定金鑰函式庫和金鑰的密碼為
server-ca-password。 - 建立一個有效期 365 天的 CA 憑證。
- 將 CA 憑證匯出到
server.ca.crt檔案中,供後續使用。