docker 下搭建zookeeper+kafka集群

前言

最近在学docker,随着微服务的发展,服务直接部署到云主机上似乎有点浪费,于是容器化部署就被提出,并且发展迅速。学了docker总要练练,于是就学习了zookeeper和kafka,来用它们来搭建集群,在网上看了许多其他大神的博客,有多机器搭建集群,也有单节点搭建的伪集群,做了参考,我这里计划单节点搭建集群。话不多说,直接开始。

环境

CPU: 1核
内存: 2 GiB
操作系统: CentOS 7.4 64位
配置属实有点垃圾,租的便宜云主机,不过没关系,勉强够用。docker不是说启动容器占用的资源小吗,单个机器能起上千个吗。(当然不是我这个配置)

集群规划

因为只有一台机器,集群中的服务要映射到宿主机的不同端口。
zookeeper

zookeeper ip 宿主机端口->容器端口
zoo1 172.21.0.11 2184->2181
zoo2 172.21.0.12 2185->2181
zoo3 172.21.0.13 2186->2181

kafka

kafka ip 宿主机端口->容器端口
kafka1 172.21.0.14 9092->9092
kafka2 172.21.0.15 9093->9093
kafka3 172.21.0.16 9094->9094

kafka的默认端口是9092,容器端口都可以映射到9092,不过我在参考(搬运?)别人配置时,修改了kafka的环境变量,指定了kafka的端口,所以这里就这样配了。

搭建前的准备

安装docker,和docker-compose;拉取zookeeper,kafka镜像。

//安装前的配置
yum install -y yum-utils device-mapper-persistent-data lvm2 //安装前的配置
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
//安装
yum install docker-ce
//安装docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose 
//拉取镜像
docker pull zookeeper
docker pull wurstmeister/kafka

创建名为zk的network

docker network create --driver bridge  --subnet=172.21.0.0/16 --gateway 172.21.0.1  zk

查看
docker 下搭建zookeeper+kafka集群_第1张图片

搭建zookeeper集群

使用docker-compose快速搭建zookeeper集群
zk-compose.yml

version: '3.4'
services:
  zoo1:
    image: zookeeper
    restart: always
    hostname: zoo1
    container_name: zoo1
    ports:
    - 2184:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
    networks:
      zk:
        ipv4_address: 172.21.0.11
  zoo2:
    image: zookeeper
    restart: always
    hostname: zoo2
    container_name: zoo2
    ports:
    - 2185:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888
    networks:
      zk:
        ipv4_address: 172.21.0.12


  zoo3:
    image: zookeeper
    restart: always
    hostname: zoo3
    container_name: zoo3
    ports:
    - 2186:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888
    networks:
      zk:
        ipv4_address: 172.21.0.13
        
networks:
  zk:
    external:
      name: zk


//在zk-compoe.yml文件目录下执行
docker-compose -f ./zk-compose.yml up -d

查看启动的集群 docker ps
在这里插入图片描述进入容器查看集群状态
docker exec -it 952ec71dbd5f bash

docker exec -it 952ec71dbd5f bash //进入zoo1
zkServer.sh status //查看节点状态

docker 下搭建zookeeper+kafka集群_第2张图片
可以看到zoo1启动成功,并且是follower。
踩坑一:这里如果没有启动成功,提示找不到zoo.cfg文件,需要自己添加。我是
直接自己复制一个到容器中的/conf目录下。
zoo.cfg

dataDir=/data
dataLogDir=/datalog
tickTime=2000
initLimit=5
syncLimit=2
clientPort=2181
autopurge.snapRetainCount=3
autopurge.purgeInterval=0
maxClientCnxns=60
standaloneEnabled=true
admin.enableServer=true
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

宿主机与容器间可以复制文件

docker cp ./zoo.cfg 952ec71dbd5f:/conf/

三个节点都复制后重启就行了。

也可以使用nc在宿主机上查看节点:
docker 下搭建zookeeper+kafka集群_第3张图片
2184端口对应的是zoo1,可以看到是follower节点。这里我的kafka也搭好了,可以看到连上了zookeeper。
踩坑二:这里使用nc可能会提示连接被拒绝,因为没有加入白名单。
解决:修改zkServer.sh脚本文件。添加一行。

 ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"
 添加在77行
    72   fi
    73 else
    74     echo "JMX disabled by user request" >&2
    75     ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
    76 fi
    77 ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"
    78 if [ "x$SERVER_JVMFLAGS" != "x" ]

可以用sed命令添加,容器里没有vi,vim;也可以复制到宿主机上,改完在复制回去。

zkCli.sh是自带的命令行客户端。使用我就不说了,可以自己看。

搭建kafka集群

搭建完zookeeper后就可以搭建kafka集群了。
同样使用docker-compose
kafka-compose.yml

version: '2'

services:
  kafka1:
    image: wurstmeister/kafka
    restart: always
    hostname: kafka1
    container_name: kafka1
    ports:
    - 9092:9092
    environment:
      KAFKA_ADVERTISED_HOST_NAME: kafka1
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
    - /kafka/k1/logs:/kafka
    external_links:
    - zoo1
    - zoo2
    - zoo3
    networks:
      zk:
        ipv4_address: 172.21.0.14

 kafka2:
    image: wurstmeister/kafka
    restart: always
    hostname: kafka2
    container_name: kafka2
    ports:
    - 9093:9093
    environment:
      KAFKA_ADVERTISED_HOST_NAME: kafka2
      KAFKA_ADVERTISED_PORT: 9093
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
    - /kafka/k2/logs:/kafka
    external_links:
    - zoo1
    - zoo2
    - zoo3
    networks:
      zk:
        ipv4_address: 172.21.0.15

  kafka3:
    image: wurstmeister/kafka
    restart: always
    hostname: kafka3
    container_name: kafka3
    ports:
    - 9094:9094
    environment:
      KAFKA_ADVERTISED_HOST_NAME: kafka3
      KAFKA_ADVERTISED_PORT: 9094
      KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
    volumes:
    - /kafka/k3/logs:/kafka
    external_links:
    - zoo1
    - zoo2
    - zoo3
    networks:
      zk:
        ipv4_address: 172.21.0.16
networks:
  zk:
    external:
      name: zk

可以看到kafka2,与kafka3,修改了端口
ports:
- 9093:9093
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka2
KAFKA_ADVERTISED_PORT: 9093
KAFKA_ZOOKEEPER_CONNECT: zoo1:2181,zoo2:2181,zoo3:2181
这里加黑的是容器自己的端口,我认为可以不用修改保持9092就可以了。我没有验证过,感兴趣可以自己验证。
同样使用docker-compose启动

//启动
docker-compose -f kafka.yml up -d
//查看
docker ps

在这里插入图片描述发现启动成功了,就这么简单?当然不是,这个是我调整过的。
实际上,刚开是是显示up,但过一会所有的kafka都变成了restarting,也无法进入容器。
踩坑三:看容器的启动日志,docker logs [容器id],发现了一大堆日志,找到了几条:

Out of Memory Error (os_linux.cpp:2773), pid=1, tid=0x00007fd89ee21b10

heap address: 0x00000000c0000000, size: 1024 MB, Compressed Oops mode: Non-zero based:0x00000000bffff000

说的是内存不够了,我一看一个kafka的jvm堆大小就占1024M,三个就3G,我总内存就2G,这怎么能启动起来。这让我有点怀疑docker在云主机上到底能不能启动几百上千个容器,是不是虚假宣传(手动滑稽)。
没办法,那就修改启动是的jvm参数吧。
在kafka的容器/opt/kafka_2.12-2.3.0/bin/目录下的kafka-server-start.sh文件

    27 
    28 if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
    29     export KAFKA_HEAP_OPTS="-Xmx256m -Xms256m"
    30 fi

修改第29行,我把1G改成了256m,如果你的内存也是2G的话,我建议及改成128m,应为我的机器改成这个已经很卡了。看看我的内存:

[root@developer bin]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1838        1689          57           0          91          19
Swap:             0           0           0
//可用的只剩19m了,而我仅仅启动了zookeeper和kafka集群。

你要问我怎么找到自己容器上的kafka-server-start.sh的文件在哪?因为容器根本进不去,我直接把容器根目录拷贝到宿主机上找的,没办法,刚开始了解,这能用这种办法,有好办法记得告诉我。
容器虽然没有启动成功,但也可以在宿主机上复制文件,改完在复制过去就行了。

验证

搭建成功后,就可以测试了。进入任意一个kafka容器/opt/kafka/bin/。
建立一个topic

#创建Topic
./kafka-topics.sh --create --zookeeper 172.21.0.11:2181,172.21.0.12:12181,172.21.0.13:2181 --replication-factor 2 --partitions 1 --topic test
 #解释--replication-factor 2   #复制两份--partitions 1 #创建1个分区--topic #主题为test
`

查看创建的topic

./kafka-topics.sh --describe --zookeeper 172.21.0.11:2181 --topic test
//zookeeper也可以是任一节点
Topic:test      PartitionCount:1        ReplicationFactor:2     Configs:        
Topic: test     Partition: 0    Leader: 1       Replicas: 1,3   Isr: 1,3
#分区为为1  复制因子为2   他的  test的分区为0
 #Replicas: 1,3   复制的为1,3# 

创建发布者

./kafka-console-producer.sh --broker-list 172.21.0.14:9092,172.21.0.15:9093,172.21.0.16:9094 --topic test

这里的端口就是构建时的端口。

kafka-console-consumer.sh --bootstrap-server 172.21.0.14:9092 --from-beginning --topic test

创建发布者和消费者这里也会失败:

[2019-10-05 02:54:47,156] WARN [Producer clientId=console-producer] Connection to node -1 (localhost/127.0.0.1:9093) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)

要修改容器/opt/kafka/config/ 下的server.properties文件,添加


#listeners=PLAINTEXT://your_hosts:9092

listeners=PLAINTEXT://172.21.0.14:9092

这个14机器对应的是9092,那么15,16,对应的是是9093,9094,和之前配置的一致。总之这个改好后集群就能正常运行了。

kafka中文官方文档

你可能感兴趣的:(docker,zookeeper,kafka)