在單獨container中部署使用
首先,kafka依賴zookeeper,即使只是單機使用,也得按叢集的方式來配置……
所以,先下載兩個官方images:
docker pull confluentinc/cp-zookeeper
docker pull confluentinc/cp-kafka
複製程式碼
然後建立一個compose(感謝令狐提供幫助):
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper
container_name: zookeeper
mem_limit: 1024M
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka
container_name: kafka
mem_limit: 1024M
depends_on:
- zookeeper
environment:
KAFKA_BROKER_NO: 1
KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_HEAP_OPTS: "-Xmx512M -Xms16M"
複製程式碼
因為這裡是直接在伺服器上測試的,為安全起見暫不繫結相關埠。
啟動compose:
docker-compose up -d
複製程式碼
現在開啟兩個新的終端視窗,分別用以下命令登入container:
docker exec -it kafka /bin/bash
複製程式碼
在其中一個視窗裡建立topic並執行producer:
kafka-topics --zookeeper zookeeper:2181 --create --replication-factor 1 --partitions 1 --topic kafkatest
kafka-console-producer --broker-list localhost:9092 --topic kafkatest
複製程式碼
在另一個視窗裡執行consumer:
kafka-console-consumer --bootstrap-server localhost:9092 --topic kafkatest --from-beginning
複製程式碼
現在,在producer裡輸入任何內容,都會在consumer裡收到。
跨container的部署
上面的配置只能在單個container裡使用,不實用。這是因為kafka advertised配置在localhost上。
需要跨container訪問,就需要通過docker的網路訪問,要修改這個配置:
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper
container_name: zookeeper
mem_limit: 1024M
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka
container_name: kafka
mem_limit: 1024M
depends_on:
- zookeeper
environment:
KAFKA_BROKER_NO: 1
KAFKA_ADVERTISED_HOST_NAME: domain_name # 修改
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://domain_name:9092 # 修改
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_HEAP_OPTS: "-Xmx512M -Xms16M"
複製程式碼
改完重啟docker-compose,另外,因為zookeeper重啟後,topic不會被持久儲存,所以重啟後需要重新建立topic。
然後啟動兩個新的container模擬網路訪問:
docker run -it --rm --link kafka:domain_name --network kafka_default --name consumer confluentinc/cp-kafka /bin/bash
docker run -it --rm --link kafka:domain_name --network kafka_default --name producer confluentinc/cp-kafka /bin/bash
複製程式碼
注意,需要指定一下docker網路為kafka_default,這是官方image使用的預設網路。
然後分別在consumer和producer兩個container裡測試:
kafka-console-consumer --bootstrap-server domain_name:9092 --topic kafkatest --from-beginning
kafka-console-producer --broker-list domain_name:9092 --topic kafkatest
複製程式碼
效果與單container一樣。
從Docker網路之外訪問的部署
如果需要從docker網路之外訪問,就需要把埠對映到宿主機了。
同樣需要修改配置,增加網路對映等:
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper
container_name: zookeeper
mem_limit: 1024M
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka
container_name: kafka
mem_limit: 1024M
depends_on:
- zookeeper
ports: # 增加
- 9092:9092 # 增加
environment:
KAFKA_BROKER_NO: 1
KAFKA_ADVERTISED_HOST_NAME: domain_name
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://domain_name:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_HEAP_OPTS: "-Xmx512M -Xms16M"
複製程式碼
然後啟動兩個新的container模擬外部網路訪問:
docker run -it --rm --add-host=domain_name:172.17.0.1 --name consumer confluentinc/cp-kafka /bin/bash
docker run -it --rm --add-host=domain_name:172.17.0.1 --name producer confluentinc/cp-kafka /bin/bash
複製程式碼
其中172.17.0.1為docker宿主機在預設docker網路(注意不是kafka_default)裡的IP,具體可以通過以下命令檢視:
ip route
複製程式碼
然後分別在consumer和producer兩個container裡測試:
kafka-console-consumer --bootstrap-server domain_name:9092 --topic kafkatest --from-beginning
kafka-console-producer --broker-list domain_name:9092 --topic kafkatest
複製程式碼
這裡有一個坑需要注意的是:
如果宿主機上有防火牆,需要增加一條規則,允許docker網路訪問宿主機的埠,否則會連線失敗。比如:
# 取得行號
iptables -L INPUT --line-num
# xx為最後一行DROP的行號,插到它前面
iptables -I INPUT xx -p tcp -m tcp -s 172.17.0.0/16 --dport 9092 -j ACCEPT
複製程式碼
效果與前兩個例子相同。