近期想学习一下 Kafka,所以打算在自己的服务器上搭建一个 Kafka 集群供以后自己使用,查阅了资料之后发现可以使用 Docker 搭建,简单快捷,以下整合记录了整个集群的搭建过程。

# 一、搭建 Zookeeper 集群环境

# 1、拉取 zookeeper 镜像

docker pull zookeeper
docker tag docker.io/zookeeper zookeeper
docker rmi docker.io/zookeeper

# 2、安装 docker-compose 工具

ps:如果已经安装可以跳过这一步

# 升级 pip
pip3 install --upgrade pip
# 指定 docker-compose 版本安装
pip install docker-compose==1.22
# 验证是否安装成功,有返回值,说明安装成功
docker-compose -v

# 3、创建相关文件夹

mkdir -p /data/docker-compose/zookeeper
mkdir -p /data/docker-data/zookeeper

# 4、创建 docker-compose.yml

cd /data/docker-compose/zookeeper
vi docker-compose.yml

以下为 docker-compose.yml 的内容 直接复制即可

version: '3.6'
services:
  zoo1:
    image: zookeeper
    restart: always
    hostname: zoo1
    container_name: zoo1
    ports:
      - 2181:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - /data/docker-data/zookeeper/zoo1/data:/data
      - /data/docker-data/zookeeper/zoo1/datalog:/datalog
  zoo2:
    image: zookeeper
    restart: always
    hostname: zoo2
    container_name: zoo2
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - /data/docker-data/zookeeper/zoo2/data:/data
      - /data/docker-data/zookeeper/zoo2/datalog:/datalog
  zoo3:
    image: zookeeper
    restart: always
    hostname: zoo3
    container_name: zoo3
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - /data/docker-data/zookeeper/zoo3/data:/data
      - /data/docker-data/zookeeper/zoo3/datalog:/datalog

粘贴完毕后按键盘 [Esc] 退出编辑 然后 输入 :wq 可以保存退出。

# 5、执行构建 consul 集群

cd /data/docker-compose/zookeeper
docker-compose up -d

# 6、进入容器验证集群是否构建成功

docker exec -it zoo1 bash
zkServer.sh status

返回下面信息,说明集群搭建成功

root@zoo1:/# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower

可以通过命令 exit 退出 docker 容器内部 bash。

# 7、小结

可以看到,zoo1 是 follower 角色

再依次到 zoo2、zoo3 中看,最后发现,zoo3 是 leader 角色,其他两个是 follower 角色,这是三台 zookeeper 内部选举的结果,无需我们干预。

我们通过 docker stop zoo3 把 leader zoo3 关掉,再分别进 zoo1、zoo2,会发现,zoo2 变成 leader 了,这也说明了 zookeeper 集群中,主从角色不需要我们人为干预,其内部会自己进行选举。

到这里,zookeeper 集群就搭建好了。

# 二、搭建 Kafka 集群

# 1、拉取 kafka 镜像

docker pull wurstmeister/kafka
docker tag docker.io/wurstmeister/kafka kafka
docker rmi docker.io/wurstmeister/kafka

# 2、拉取 kafka 可视化管理工具镜像

docker pull sheepkiller/kafka-manager
docker tag docker.io/sheepkiller/kafka-manager kafka-manager
docker rmi docker.io/sheepkiller/kafka-manager

# 3、创建相关文件夹

mkdir -p /data/docker-compose/kafka
mkdir -p /data/docker-data/kafka

# 4、创建网络,用于 kafka 和 zookeeper 共享一个网络段

docker network create --driver bridge zookeeper_kafka_net

# 5、创建 docker-compose.yml

cd /data/docker-compose/kafka
vi docker-compose.yml
version: '3'
services:
  kafka1:
    image: kafka
    restart: always
    container_name: kafka1
    hostname: kafka1
    ports:
      - 9091:9092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_HOST_NAME: kafka1
      KAFKA_ADVERTISED_PORT: 9091
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.78.200:9091
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
      - /data/docker-data/kafka1/docker.sock:/var/run/docker.sock
      - /data/docker-data/kafka1/data:/kafka
    external_links:
      - zoo1
      - zoo2
      - zoo3
  kafka2:
    image: kafka
    restart: always
    container_name: kafka2
    hostname: kafka2
    ports:
      - 9092:9092
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_HOST_NAME: kafka2
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.78.200:9092
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
      - /data/docker-data/kafka2/docker.sock:/var/run/docker.sock
      - /data/docker-data/kafka2/data:/kafka
    external_links:
      - zoo1
      - zoo2
      - zoo3
  kafka3:
    image: kafka
    restart: always
    container_name: kafka3
    hostname: kafka3
    ports:
      - 9093:9092
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ADVERTISED_HOST_NAME: kafka3
      KAFKA_ADVERTISED_PORT: 9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.78.200:9093
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
      - /data/docker-data/kafka3/docker.sock:/var/run/docker.sock
      - /data/docker-data/kafka3/data:/kafka
    external_links:
      - zoo1
      - zoo2
      - zoo3
  kafka-manager:
    image: kafka-manager
    restart: always
    container_name: kafka-manager
    hostname: kafka-manager
    ports:
      - 9010:9000
    links:
      - kafka1
      - kafka2
      - kafka3
    external_links:
      - zoo1
      - zoo2
      - zoo3
    environment:
      ZK_HOSTS: zoo1:2181,zoo2:2181,zoo3:2181

注:links 是引入当前 docker-compose 内部的 service,external_links 引入的是当前 docker-compose 外部的 service

# 6、执行构建

docker-compose up -d

# 7、将所有 kafka 和 zookeeper 加入一个网络

docker network connect zookeeper_kafka_net zoo1
docker network connect zookeeper_kafka_net zoo2
docker network connect zookeeper_kafka_net zoo3
docker network connect zookeeper_kafka_net kafka1
docker network connect zookeeper_kafka_net kafka2
docker network connect zookeeper_kafka_net kafka3
docker network connect zookeeper_kafka_net kafka-manager

之所以这样指定网络而不是在编排文件中指定网络为一个网络段的原因是因为考虑到后面可能 kafka 和 zookeeper 分布在 6 台机器上,到时使用 docker swarm 构建 docker 集群,网络处理就很方便,不用修改编排文件

# 8、验证结果

浏览器访问 kafka-manager 管理界面

http://kafka.yypdreamland.cn/ 我这里是用域名配置了 nginx 的代理,如果你没做任何配置那么访问地址是你的主机 ip:9010 的格式)

集群构建好了,并且 kafka 集群已经完成了和 zookeeper 集群的互通