一、需求描述

将 kafka 使用Docker 启动起来

  • 能够单机启动(开发模式)
  • 能够集群启动

注:

  • Kafka重度依赖ZK,是有状态应用,对容器化不友好
  • 跟RocketMQ 为云而生不同,目前kafka (2.7.0)还不支持使用环境变量的方式配置 server.properties 的配置项。
  • 容器重启、重部署,IP 和 端口会漂移
  • Kafka本质是个日志存储系统,持久化需要考虑

二、bitnami/kafka

请点击查看: bitnami docker image
(bitnami 是一家开源软件组织)

2.1 获取镜像

docker pull bitnami/kafka:2.7.0

2.2 持久化数据

一般情况下容器销毁,数据就丢失了,卡夫卡作为存储系统,肯定不能接受。所以需要自己挂载volume,还好这个镜像 已经暴露了 /bitnami/kafka存放数据。
如果是使用 docker-compose.yml

kafka:
  ...
  volumes:
    - /path/to/kafka-persistence:/bitnami/kafka
  ...

2.3 单机启动【重点】

单机启动有两种手段:
第一种:纯人肉

1、拉取镜像
docker pull bitnami/kafka:2.7.0
2、创建网络
docker network create app-tier --driver bridge
3、启动ZK容器
docker run -d --name zookeeper-server \
    --network app-tier \
    -e ALLOW_ANONYMOUS_LOGIN=yes \
    bitnami/zookeeper:latest
4、启动 单kafka instance
docker run -d --name kafka-server \
	-p 9092:9092  \
    --network app-tier \
    -e ALLOW_PLAINTEXT_LISTENER=yes \
    -e KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper-server:2181 \
    -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092   \
    bitnami/kafka:2.7.0
5、验证
telnet localhost 9092

第二种:

version: '2'

networks:
  app-tier:
    driver: bridge

services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    networks:
      - app-tier
  kafka:
    image: 'bitnami/kafka:latest'
    networks:
      - app-tier
  myapp:
    image: 'YOUR_APPLICATION_IMAGE'
    networks:
      - app-tier

这里要补充说明:

  • 可以通过 环境变量来注入ZK 和Kafka的配置,比如重要的 持久化数据的路径
  • 在应用中,使用kafka作为主机名去连接broker。【这里要特别注意,kafka 是一个域名】
  • 支持的环境变量基本覆盖了所有的配置 ,见 连接

2.4 配置

2.4.1 Kafka development setup example

前面一节,我们分别拉起了 ZK kafka 容器,现在尝试使用 docker-compose,一把搞定:

version: "3"
services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
      - '2181:2181'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
    depends_on:
      - zookeeper

2.4.2 Accessing Kafka with internal and external clients

skipped

2.4.3 security

skipped

2.4.4 Setting up a Kafka Cluster(逐个broker启动)

创建网络
docker network create app-tier --driver bridge

起ZK
docker run --name zookeeper \
  --network app-tier \
  -e ALLOW_ANONYMOUS_LOGIN=yes \
  -p 2181:2181 \
  bitnami/zookeeper:latest

起第一个卡夫卡
docker run --name kafka1 \
  --network app-tier \
  -e KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 \
  -e ALLOW_PLAINTEXT_LISTENER=yes \
  -p 9092:9092 \
  bitnami/kafka:latest

假如需要第二个,第三个,将第一个卡夫卡的name 和 port 改掉就行。
即使不改

2.4.5 使用 docker-compose

version: '2'

services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
     - '2181:2181'
    environment:
     - ALLOW_ANONYMOUS_LOGIN=yes
  kafka1:
    image: 'bitnami/kafka:2.7.0'
    ports:
      - '9092'
    environment:
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
  kafka2:
    image: 'bitnami/kafka:2.7.0'
    ports:
      - '9092'
    environment:
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
  kafka3:
    image: 'bitnami/kafka:2.7.0'
    ports:
      - '9092'
    environment:
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes

按照这个docker-compose启动:

[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
8645e8a3e311   bitnami/kafka:2.7.0        "/opt/bitnami/script…"   57 seconds ago   Up 54 seconds   0.0.0.0:49173->9092/tcp                                bitnami_cluster_test_kafka3_1
a96fad0b05d9   bitnami/kafka:2.7.0        "/opt/bitnami/script…"   57 seconds ago   Up 54 seconds   0.0.0.0:49175->9092/tcp                                bitnami_cluster_test_kafka2_1
c961f0f9f8e3   bitnami/kafka:2.7.0        "/opt/bitnami/script…"   57 seconds ago   Up 54 seconds   0.0.0.0:49174->9092/tcp                                bitnami_cluster_test_kafka1_1

可见:虽然yml中指定了端口映射,实际上并没有起作用,docker-compose 会使用 宿主机的随机端口 映射到 容器端口。这样还是不大方便,假如我从另一台主机的应用 访问这个宿主机上的容器,需要指定宿主机的端口,宿主机端口会变化的话,另一台主机的应用难道也要不断跟着改?

所以,将上面yml中的端口指定给改掉,比如 9091:9092 9092:9092 9093:9092,这样在同一个宿主机就跑起来了三个kafka容器。

2.5 tips

  • 上面所言,目标是在 本地或者测试环境中迅速拉起一套环境方式方便测试,假如要上私有云,还是欠缺了很多:
    • 安全配置
    • kafka 作为存储系统,上云后 缩容、扩容后分区均衡分布、性能降低都是不小的问题,此外,kafka的高吞吐是基于page cache的,Kafka对内存的使用量要求特别高,我司的broker 物理内存普遍在 64~96G左右(机器都略老了),即使上云了,对内存资源的节省也不是特别突出。

延伸问题:
如果我有2个宿主机,要部署 2个kafka 集群 ,每个集群2个kafka 实例,那么我肯定希望交叉部署,此时docker-compose还是有点力不从心
在这里插入图片描述
如何像公有云那样做到 集群跨主机部署,同时能方便运维管理呢?

三、wurstmeister/kafka-docker

四、

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐