實(shí)用 | 從Apache Kafka到Apache Spark安全讀取數(shù)據(jù)
引言
隨著在CDH平臺(tái)上物聯(lián)網(wǎng)(IoT)使用案例的不斷增加,針對(duì)這些工作負(fù)載的安全性顯得至關(guān)重要。本篇博文對(duì)如何以安全的方式在Spark中使用來自Kafka的數(shù)據(jù),以及針對(duì)物聯(lián)網(wǎng)(IoT)使用案例的兩個(gè)關(guān)鍵組件進(jìn)行了說明。
Cloudera Distribution of Apache Kafka 2.0.0版本(基于Apache Kafka 0.9.0)引入了一種新型的Kafka消費(fèi)者API,可以允許消費(fèi)者從安全的Kafka集群中讀取數(shù)據(jù)。這樣可以允許管理員鎖定其Kafka集群,并要求客戶通過Kerberos進(jìn)行身份驗(yàn)證。此外,也可以允許客戶在與Kafka brokers(通過SSL/TLS)通信時(shí)加密數(shù)據(jù)隨后,在Cloudera Distribution of Apache Kafka 2.1.0版本中,Kafka通過Apache Sentry引入了支持授權(quán)功能。這樣可以允許Kafka管理員鎖定某些主題,并針對(duì)特定角色和用戶授予權(quán)限,充分發(fā)揮基于角色的訪問控制功能。
而現(xiàn)在,從Cloudera Distribution of Spark 2.1的第一次發(fā)行版開始,我們已經(jīng)具備了從Spark中的Kafka內(nèi)安全讀取數(shù)據(jù)的功能。
要求
- Cloudera Distribution Spark 2.1第一次發(fā)行版或更高版本。
- Cloudera Distribution Kafka 2.1.0版本或更高版本。
體系架構(gòu)
使用Spark中新的直接連接器可以支持從安全的Kafka集群中獲取消息。直接連接器不使用單獨(dú)的進(jìn)程(亦稱為接收器)讀取數(shù)據(jù)。相反,Spark驅(qū)動(dòng)程序?qū)⒏櫢鞣NKafka主題分區(qū)的偏移量,并將偏移量發(fā)送到從Kafka中直接讀取數(shù)據(jù)的執(zhí)行程序中。直接連接器的簡單描述如下所示。
圖1:Spark中的Kafka直接連接器
- Spark節(jié)點(diǎn)和Kafka 代理人(broker)不一定在同一地點(diǎn)。
- 一個(gè)Spark分區(qū)對(duì)應(yīng)一個(gè)Kafka主題分區(qū)。
- 如果出于某種原因,多個(gè)主題分區(qū)位于單個(gè)Kafka節(jié)點(diǎn)上,則有多個(gè)Spark執(zhí)行程序可能會(huì)命中該節(jié)點(diǎn)(不過沒關(guān)系)。
- 上圖只是一個(gè)簡單的說明。
非常值得注意的一點(diǎn)是,Spark是以分布式的方式訪問Kafka中的數(shù)據(jù)。Spark中的每一個(gè)任務(wù)都會(huì)從某個(gè)Kafka主題的特定分區(qū)中讀取數(shù)據(jù),該特定分區(qū)稱為主題分區(qū)。主題分區(qū)理想地均勻分布在Kafka 代理人(broker)之間。
但是,為了以分布式的方式從安全的Kafka中讀取數(shù)據(jù),我們需要在Kafka(KAFKA-1696)中使用Hadoop風(fēng)格的授權(quán)令牌,在寫本篇博文時(shí)(2017年春季)還不支持這一功能。
我們已經(jīng)考慮了各種解決這個(gè)問題的方法,但是最終決定采用從Kafka中安全讀取數(shù)據(jù)的建議解決方案(至少應(yīng)實(shí)現(xiàn)Kafka授權(quán)令牌的支持)將是Spark應(yīng)用程序分發(fā)用戶的keytab,以便執(zhí)行程序可以訪問。然后,執(zhí)行程序?qū)⑹褂霉蚕淼挠脩裘荑€表,與Kerberos密鑰分發(fā)中心(KDC)進(jìn)行身份驗(yàn)證,并從Kafka 代理人(broker)中讀取數(shù)據(jù)。YARN分布式緩存用于從客戶端(即網(wǎng)關(guān)節(jié)點(diǎn))向驅(qū)動(dòng)程序和執(zhí)行程序發(fā)送和共享密鑰表。下圖顯示了當(dāng)前解決方案的一覽圖。
圖2:當(dāng)前解決方案(假設(shè)YARN集群模式)
這種方法存在以下一些常見的問題:
a. 這不能被認(rèn)為是發(fā)送鑰匙表的最佳安全實(shí)踐
b.在具有大量Kafka主題分區(qū)的情況下,所有執(zhí)行程序可能會(huì)同時(shí)嘗試登錄KDC,存在導(dǎo)致重送攻擊的潛在風(fēng)險(xiǎn)(類似于DDOS攻擊)。
關(guān)于問題a),Spark已經(jīng)使用分布式緩存將用戶的密鑰表從客戶端(亦稱為網(wǎng)關(guān))節(jié)點(diǎn)發(fā)送到驅(qū)動(dòng)程序,并且由于缺少授權(quán)令牌,所以沒有辦法繞過。管理員可以選擇自己在Spark外部將密鑰表分發(fā)到Spark執(zhí)行程序節(jié)點(diǎn)(即YARN節(jié)點(diǎn),因?yàn)镾park在YARN上運(yùn)行),并調(diào)整優(yōu)化共享的示例應(yīng)用程序以緩解該問題。
關(guān)于問題b),我們?cè)贙afka主題中測(cè)試了1000多個(gè)主題分區(qū),并且在增加分區(qū)數(shù)量后未見對(duì)KDC服務(wù)器產(chǎn)生不利影響。
與Apache Sentry集成
例應(yīng)用程序假設(shè)沒有使用任何Kafka授權(quán)。如果使用了Kafka授權(quán)的話(通過Apache Sentry),則必須確保應(yīng)用程序中指定的消費(fèi)者小組已經(jīng)獲得Sentry授權(quán)。例如,如果應(yīng)用程序的消費(fèi)者小組的名稱是my-consumer-group,則必須同時(shí)對(duì)my-consumer-group和spark-executor-my-consumer-group授予訪問權(quán)限(即您的消費(fèi)者小組名稱前綴為spark-executor-)。這是因?yàn)镾park驅(qū)動(dòng)器使用是該應(yīng)用程序指定的消費(fèi)者小組,但spark執(zhí)行程序在此集成中使用的是不同的消費(fèi)者小組,該集成在驅(qū)動(dòng)程序消費(fèi)者小組的名稱前指定的前綴是spark-executor-。
結(jié)論
簡而言之,您可以使用Cloudera Distribution of Apache Kafka 2.1.0 版本(或更高版本)和Cloudera Distribution of Apache Spark 2.1第一次發(fā)行版(或更高版本),以安全的方式從Kafka中使用Spark內(nèi)的數(shù)據(jù)——包括身份驗(yàn)證(使用Kerberos進(jìn)行身份認(rèn)證)、授權(quán)(使用Sentry進(jìn)行授權(quán))以及線上加密(使用SSL/TLS進(jìn)行加密)。