日期:2020-04-20
wurstmeister/kafka:2.12-2.3.0
docker-ce 版本18.09
CentOS 7.6
官網:
https://github.com/wurstmeister/kafka-docker
https://github.com/wurstmeister/kafka-docker/wiki/Connectivity
實踐
依賴的zookeeper
KAFKA_ZOOKEEPER_CONNECT 是必須的,指定了kafka 連接哪個 zookeeper。 直接寫zookeeper就可以,因為同一台物理機上,可以使用service的名字找到相應的服務。
兩種寫法
[官網](https://github.com/wurstmeister/kafka-docker/wiki/Connectivity)上說:
Deprecated
KAFKA_HOST:
KAFKA_PORT: 9092
KAFKA_ADVERTISED_HOST_NAME: one.prod.com
KAFKA_ADVERTISED_PORT: 9092
Current
KAFKA_LISTENERS: PLAINTEXT://:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://one.prod.com:9092
經實踐,以下配置都可以正常啟動和使用 kafka 向 topic 發送和消費數據
舊的寫法
version: '3.2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
restart: always
kafka:
image: wurstmeister/kafka:2.12-2.3.0
ports:
- "9092:9092"
environment:
- KAFKA_ADVERTISED_HOST_NAME=${IP}
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
新的寫法
version: '3.2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
restart: always
kafka:
image: wurstmeister/kafka:2.12-2.3.0
ports:
- "9092:9092"
environment:
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${IP}:9092
- KAFKA_LISTENERS=PLAINTEXT://:9092
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
注意 KAFKA_LISTENERS=PLAINTEXT://:9092 不要寫成 KAFKA_LISTENERS=PLAINTEXT://${IP}:9092, 否則啟動kafka時會報錯:
使用了namespace功能的部署方式
docker 有個高級功能 namespace, 它的主要功能就是:將物理機的非 root 用戶映射為 docker 內的 root用戶。這樣 docker 容器內如果寫物理機上的文件夾(文件),它的owner就不是 root 而是普通用戶了。
具體參見另一篇筆記。
如果使用了這個高級功能,使用前面提到的部署方式部署 kafka 就不成了。需要將2種方式結合起來。
version: '3.2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
container_name: "zookeeper"
restart: always
kafka:
image: wurstmeister/kafka:2.12-2.3.0
container_name: "kafka"
ports:
- "9092:9092"
environment:
- TZ=CST-8
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
# 非必須,設置自動創建 topic
- KAFKA_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_ADVERTISED_HOST_NAME=${IP}
- KAFKA_ADVERTISED_PORT=9092
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${IP}:9092
- KAFKA_LISTENERS=PLAINTEXT://:9092
# 非必須,設置對內存
- KAFKA_HEAP_OPTS=-Xmx1G -Xms1G
# 非必須,設置保存7天數據,為默認值
- KAFKA_LOG_RETENTION_HOURS=168
volumes:
# 將 kafka 的數據文件映射出來
- ${DATA_PATH}/kafka:/kafka
- /var/run/docker.sock:/var/run/docker.sock
restart: always
解決問題
在部署 kafka 的過程中遇到了很多問題,每遇到一個問題,就求助於搜索引擎,還問使用過的同事,結果發現效果並不好。因為環境不一樣,kafka的版本不一樣,還會有矛盾的說法,會誤導。比如,我在搜索引擎查到的結果讓我一直認為 KAFKA_LISTENERS 應該配置為:PLAINTEXT://0.0.0.0:9092 或 PLAINTEXT://${IP}:9092,各種試,各種卡,結果發現這根本是錯的。汗~
反思解決問題的過程,發現,最有幫助的是官方文檔和部署過程中打印出來的log。為了以后和給其他人參考,特此記錄下來。
部署失敗解決方式
查看log, 根據 log 提示添加或修改環境變量,解決問題
docker logs kafka
或者
docker-compose up
調試產生和消費數據
查詢kafka log 中的 brokerId,假設 brokerId=1001
docker logs kafka
進入 kafka 的客戶端,如果沒有使用 kafka 容器自帶的
docker exec -ti kafka bash
cd opt/kafa_<版本>/bin
-
查看 kafka 在 zookeeper 中的注冊信息,出現圖中類似的信息表示OK
假設:IP=10.1.10.33
./zookeeper-shell.sh 10.1.10.33 <<< "get /brokers/ids/1001"
如果沒有出現信息,代表 kafka 和 zookeeper 沒有連通,查看是否是部署問題。
注意上圖中紅框部分,如果沒有出現具體 IP 或者映射過的域名,那么,修改環境變量。
-
測試產生數據
# 向k2_test topic寫數據,輸入任意內容后按回車輸入下一條消息,按Crtl+c退出
./kafka-console-producer.sh --broker-list 10.1.10.33:9092 --topic k2_test出現提示符(>),可以打字,就代表可以了。
如果等待了幾分鍾也沒有提示符出現,那么代表 kafka 不通。影響這個的環境變量:KAFKA_ADVERTISED_LISTENERS
-
測試消費數據
# 消費數據,應該能看到上一條命令時輸入的消息,按Crtl+c退出
./kafka-console-consumer.sh --bootstrap-server 10.1.10.33:9092 --from-beginning --topic k2_test如果等待了幾分鍾也沒有提示符出現,那么代表 kafka 不通。影響這個的環境變量:KAFKA_LISTENERS
問題記錄
-
每次 kafka 部署之前要把之前的容器刪除,否則會出現一會成功一會不成功的問題。
docker rm -f kafka zookeeper
-
一般來說,KAFKA_BROKER_ID 是不需要指定的。
每次移除兩個容器后,重新部署后,brokerId 都會從 1001 開始。
如果不移除,brokerId 會自增, zookeeper 中會有之前的 brokerId 殘留,在使用過程中會有一些 warning 但不影響使用
-
kafka 其他配置
docker exec -ti kafka bash
cat opt/kafa_<版本>/config/server.properties比如 kafka 的配置中有 log.retention.hours = 168
在 docker-compose.yml 中配置為 KAFKA_LOG_RETENTION_HOURS