閱讀路徑
- 谷歌搜索kafka中文介紹及翻譯
- 學習成熟的kafka的dockerfile及compose
- 閱讀官方文檔介紹性章節(jié)
- 閱讀官方文檔security章節(jié)
主要問題
-
重啟要全面
- 更改了配置文件重啟測試時,記得先刪除kafka的log(數(shù)據(jù))目錄
- zookeeper也需要一并重置
- 不然的話可能會遇到
1 partitions have leader brokers without a matching listener, including [test-0]
-
先配置認證
- kafka調試3A的時候最好先不開啟鑒權崎页,先調試認證
- kafka貌嫡、hbase等apache家一眾的java大數(shù)據(jù)項目的認證是類似的评矩,涉及SASL和JAAS和SSL
- kafka配置SSL可以用于傳輸層的加密吃嘿,同時可選用于認證
- JAAS是java語言內部的認證授權框架塞关,實現(xiàn)了(或使用內置的)具體認證細節(jié)的模塊后晕讲,可以用它處理認證過程贵白、管理認證session和鑒權policy等等
- SASL是規(guī)定了一些認證流程和接口&不涉及具體認證細節(jié)算法的認證規(guī)范
- SASL是一個規(guī)范,自然就有對應的實現(xiàn)倍谜,網絡服務以及客戶端可以調用其實現(xiàn)進行符合SASL框架的認證交互
-
在kafka中配置SASL的大部分配置是寫在JAAS所負責解析的配置文件中的迈螟,自然就產生了在kafka中JAAS和SASL的調用關系是什么的問題,誰在誰之上尔崔?還是并列調用(JAAS只是讀個配置而已)答毫?
- 在讀了認證模塊相關代碼后,確認是先調用JAAS加載kafka自己編寫的認證模塊季春,而這個模塊是一個adapter適配器洗搂,在其中調用sasl進行認證。即由JAAS調用SASL
- 吐槽一下载弄,如果用kerberos的話加上GSSAPI會有JAAS-SASL-GSSAPI三層類似的認證抽象層層調用耘拇,這就是架構嘛hhhh
-
再配置鑒權
- 場景中多用戶多topic再開啟鑒權比較好,不然徒增不少麻煩
- 不認證但開啟鑒權的問題:
- 一般outside外部訪問方向會開啟認證
- inside集群內部訪問不開啟認證且使用PLAINTEXT明文傳輸
- 導致不開啟認證 && 開啟鑒權時宇攻,kafka會為inside方向沒有認證的請求默認判定為User:ANONYMOUS用戶
- kafka的所有broker需要走inside方向登錄自己以及其他broker進行同步
- 鑒權所使用的訪問控制ACL規(guī)則存儲在zk中驼鞭,不手動顯式進行添加就不存在ACL規(guī)則
- 最終導致kafka啟動后無法登錄自己,且日志中顯示有User:ANONYMOUS用戶的請求并被拒絕
- 此時讀寫消息會報錯
Error while fetching metadata with correlation id 28 : {test=LEADER_NOT_AVAILABLE}
- 此時讀寫消息會報錯
- 解決的辦法至少有下面幾種
- 在properties中設置User:ANONYMOUS是superuser尺碰,擁有絕對的權限
- 或為User:ANONYMOUS配置相應的高權限ACL規(guī)則(還沒有做具體實驗)
- 在outside方向沒有ANONYMOUS用戶存在時,我覺得安全性可以接受,盡管superuser和anonymous放一起很怪
- inside方向傳輸層使用SSL亲桥,并給與證書對應的用戶superuser
- 同理也可以給證書用戶很高的訪問控制權限
- 安全性最高洛心,但配置也麻煩
- properties開啟KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND
- 即不存在ACL策略應用于本資源時,任何人都可以訪問题篷,非常不安全
- 在properties中設置User:ANONYMOUS是superuser尺碰,擁有絕對的權限
搭建運行
鏡像
- 在dockerhub和google搜索kafka容器化相關內容词身,找到wurstmeister/kafka-docker/
- 下載量大,star多
- Dockerfile entrypoint清晰
- Tag管理簡潔規(guī)范
- Env配置注入靈活
編排
- 編排目前使用docker-compose
- 示例中zookeeper沒有特殊的配置
- 示例中kafka
- 配置主要通過環(huán)境變量注入
- 認證相關的jaas配置文件通過volume掛載進etc目錄
zookeeper:
image: wurstmeister/zookeeper:3.4.6
ports:
- "172.26.0.2:2181:2181"
networks:
ninestates: {}
kafka:
image: wurstmeister/kafka:2.13-2.6.0
ports:
- "172.26.0.2:9092:9092"
- "172.26.0.2:9093:9093"
environment:
# kafka基礎配置
KAFKA_BROKER_ID: 1
KAFKA_CREATE_TOPICS: "test:1:1"
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: INSIDE://172.26.0.2:9092,OUTSIDE://172.26.0.2:9093
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:SASL_PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
# 以下是認證鑒權相關配置
#KAFKA_HEAP_OPTS: "-Xmx1G -Xms1G -Djava.security.auth.login.config=\\/etc\\/jaas\\/kafka_server_jaas.conf"
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/jaas/kafka_server_jaas.conf"
KAFKA_SASL_MECHANISM: PLAIN
KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
KAFKA_SUPER_USERS: "User:admin;User:ANONYMOUS"
KAFKA_AUTHORIZER_CLASS_NAME: kafka.security.authorizer.AclAuthorizer
#KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true"
volumes:
- "/var/kafka/:/kafka"
- "./kafka/jaas/:/etc/jaas"
networks:
ninestates: {}
配置約定
基礎配置
配置解釋
- KAFKA_BROKER_ID:每個broker在集群中的唯一ID
- KAFKA_CREATE_TOPICS:啟動時自動創(chuàng)建topic番枚,
topic名:分區(qū)數(shù):副本數(shù)
- KAFKA_ZOOKEEPER_CONNECT:kafka集群使用的zk集群地址
- KAFKA_ADVERTISED_LISTENERS法严、KAFKA_LISTENERS
- URI的協(xié)議名INSIDE和OUTSIDE是別名,kafka并不理解其含義
- 多個Listener通過指定不同的URI監(jiān)聽不同的socket葫笼,為不同的客戶端差異服務
- SECURITY_PROTOCOL_MAP是別名到傳輸層安全機制的映射深啤,如OUTSIDE使用SASL認證,傳輸層使用PLAINTEXT明文傳輸
- INTER_BROKER_LISTENER_NAME指定哪個別名所屬的listener用于集群內部通信
安全配置
配置解釋
- KAFKA_HEAP_OPTS 或 KAFKA_OPTS:指定java啟動時讀取jaas配置文件的路徑
- KAFKA_SASL_MECHANISM:SASL框架內使用的插件認證機制
- KAFKA_SASL_ENABLED_MECHANISMS:SASL框架內允許使用插件認證機制
- KAFKA_SUPER_USERS:超級用戶路星,分號分割
- KAFKA_AUTHORIZER_CLASS_NAME:
- 指定鑒權插件路徑
- 同時也是鑒權開啟開關
- 關閉Authorization的話注釋此項即可
JAAS配置文件
- 以下是kafka開啟SASL認證時溯街,通過jaas配置文件傳遞給sasl的配置內容
- username和password是kafka集群內部通訊使用的用戶名和密碼
- 但是目前的配置在outside的listener開啟認證,所以不涉及內部通訊
- user_username="password"是用于登陸的用戶名和密碼
- 可以看到sasl使用plain認證機制時用戶名和密碼是明文寫在配置文件中的
kafka_server_jaas.conf:
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="admin-secret"
user_admin="admin-secret"
user_alice="alice-secret";
};
- 以下是客戶端與服務端對稱的jaas配置文件
- 由于配置內容不多洋丐,所以可以寫在客戶端的properties配置文件中呈昔,如下下圖
- 如果非要使用jaas.conf文件的話,java程序啟動時同樣需要指定
-Djava.security.auth.login.config=
路徑
kafka_client_jaas.conf:
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="alice" \
password="alice-secret";
kafka_client_alice.properties:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="alice" password="alice-secret";
group.id=test-group
生產消費
無認證鑒權
- 消費
./kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test
- 生產
./kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic test --from-beginning
有認證鑒權
- 消費
./kafka-console-consumer.sh --bootstrap-server 172.26.0.2:9093 --topic test --from-beginning --consumer.config /etc/jaas/kafka_client.properties
- 生產
./kafka-console-producer.sh --bootstrap-server 172.26.0.2:9093 --topic test --producer.config /etc/jaas/kafka_client.properties
ACL配置
- 進入kafka容器后需要
unset KAFKA_OPTS
避免去讀取用于連接zookeeper的jaas配置 ./kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=zookeeper:2181 --add --allow-principal User:alice --operation Read --topic test
-
./kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=zookeeper:2181 --add --allow-principal User:alice --operation Read --group test-group
- 注意consumer讀取時涉及對自己所屬consumer-group的組相關信息的讀取
- 不加的話會報
org.apache.kafka.common.errors.GroupAuthorizationException: Not authorized to access group: console-consumer-5462
Finally
- 第一次記錄大數(shù)據(jù)平臺方面的學習友绝,歡迎評論交流