• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Docker搭建Zookeeper&Kafka集群的实现

    最近在学习Kafka,准备测试集群状态的时候感觉无论是开三台虚拟机或者在一台虚拟机开辟三个不同的端口号都太麻烦了(嗯。。主要是懒)。

    环境准备

    一台可以上网且有CentOS7虚拟机的电脑

    为什么使用虚拟机?因为使用的笔记本,所以每次连接网络IP都会改变,还要总是修改配置文件的,过于繁琐,不方便测试。(通过Docker虚拟网络的方式可以避免此问题,当时实验的时候没有了解到)

    Docker 安装

    如果已经安装Docker请忽略此步骤

    yum安装

    Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看上文的前提条件来验证你的CentOS 版本是否支持 Docker 。

    # 查看内核版本
    $ uname -a
    #安装 Docker
    $ yum -y install docker
    #启动 Docker 后台服务
    $ service docker start
    # 由于本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并在容器内运行。
    $ docker run hello-world

    脚本安装

    使用 sudo 或 root 权限登录 Centos。

    确保 yum 包更新到最新。

    $ sudo yum update

    获取并执行 Docker 安装脚本。

    $ curl -fsSL https://get.docker.com -o get-docker.sh
    # 执行这个脚本会添加 docker.repo 源并安装 Docker。
    $ sudo sh get-docker.sh

    启动Docker

    $ sudo systemctl start docker
    # 验证 docker 是否安装成功并在容器中执行一个测试的镜像。
    $ sudo docker run hello-world
    $ docker ps

    镜像加速

    开始让我配置国内镜像源的时候我是拒绝的,但是使用之后发现那下载速度 duang~ 的一下就上去了。所以强烈建议大家配置国内镜像源。

    打开/创建 /etc/docker/daemon.json 文件,添加以下内容:

    {
     "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }

    Zookeeper集群搭建

    Zookeeper镜像:zookeeper:3.4

    镜像准备

    $ docker pull zookeeper:3.4

    查找镜像可以去 https://hub.docker.com/

    docker pull images:TAG // 代表拉取 TAG 版本的 image 镜像

    建立独立Zookeeper容器

    我们首先用最简单的方式创建一个独立的Zookeeper节点,然后我们根据这个例子创建出其他的节点。

    $ docker run --name zookeeper -p 2181:2181 -d zookeeper:3.4

    默认的,容器内配置文件在, /conf/zoo.cfg,数据和日志目录默认在 /data/datalog,需要的话可以将上述目录映射到宿主机。

    参数解释

    --name:指定容器名字
    -p:为容器暴露出来的端口分配端口号
    -d:在后台运行容器并打印容器ID

    集群搭建

    其它节点的Zookeeper容器创建方式与创建独立容器类似,需要注意的是,要分别指定节点的id和修改文件中多节点的配置,相应的创建命令如下:

    新建docker网络

    $ docker network create zoo_kafka
    $ docker network ls

    Zookeeper容器1

    $ docker run -d \
    
       --restart=always \
    
       -v /opt/docker/zookeeper/zoo1/data:/data \
    
       -v /opt/docker/zookeeper/zoo1/datalog:/datalog \
    
       -e ZOO_MY_ID=1 \
    
       -p 2181:2181 \
    
       -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" \
    
       --name=zoo1 \
    
       --net=viemall-zookeeper \
    
       --privileged \
    
       zookeeper:3.4

    Zookeeper容器2

    $ docker run -d \
    
       --restart=always \
    
       -v /opt/docker/zookeeper/zoo2/data:/data \
    
       -v /opt/docker/zookeeper/zoo2/datalog:/datalog \
    
       -e ZOO_MY_ID=2 \
    
       -p 2182:2181 \
    
       -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" \
    
       --name=zoo2 \
    
       --net=viemall-zookeeper \
    
       --privileged \
    
       zookeeper:3.4

    Zookeeper容器3

    $ docker run -d \
    
       --restart=always \
    
       -v /opt/docker/zookeeper/zoo3/data:/data \
    
       -v /opt/docker/zookeeper/zoo3/datalog:/datalog \
    
       -e ZOO_MY_ID=3 \
    
       -p 2183:2181 \
    
       -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" \
    
       --name=zoo3 \
    
       --net=viemall-zookeeper \
    
       --privileged \
    
       zookeeper:3.4

    这种方式虽然也实现了我们想要的,但是步骤过于繁琐,而且维护起来麻烦(懒癌晚期),所以我们使用 docker-compose 的方式来实现。

    docker-compose 搭建zookeeper集群

    新建docker网络

    $ docker network create viemall-zookeeper
    $ docker network ls

    编写 docker-compose.yml 脚本

    使用方式:

    安装 docker-compose

    # 获取脚本
    $ curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    # 赋予执行权限
    $chmod +x /usr/local/bin/docker-compose

    任意目录下新建 docker-compose.yml 文件,复制以下内容

    执行命令 docker-compose up -d

    命令对照
    |命令|解释|
    |-|-|
    |docker-compose up|启动所有容器|
    |docker-compose up -d|后台启动并运行所有容器|
    |docker-compose up --no-recreate -d|不重新创建已经停止的容器|
    |docker-compose up -d test2|只启动test2这个容器|
    |docker-compose stop|停止容器|
    |docker-compose start|启动容器|
    |docker-compose down|停止并销毁容器|

    docker-compose.yml下载地址:https://github.com/JacianLiu/docker-compose/tree/master/zookeeper
    docker-compose.yml详情

    version: '2'
    services:
     zoo1:
      image: zookeeper:3.4 # 镜像名称
      restart: always # 当发生错误时自动重启
      hostname: zoo1
      container_name: zoo1
      privileged: true
      ports: # 端口
       - 2181:2181
      volumes: # 挂载数据卷
       - ./zoo1/data:/data
       - ./zoo1/datalog:/datalog 
      environment:
       TZ: Asia/Shanghai
       ZOO_MY_ID: 1 # 节点ID
       ZOO_PORT: 2181 # zookeeper端口号
       ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 # zookeeper节点列表
      networks:
       default:
        ipv4_address: 172.23.0.11
    
     zoo2:
      image: zookeeper:3.4
      restart: always
      hostname: zoo2
      container_name: zoo2
      privileged: true
      ports:
       - 2182:2181
      volumes:
       - ./zoo2/data:/data
       - ./zoo2/datalog:/datalog
      environment:
       TZ: Asia/Shanghai
       ZOO_MY_ID: 2
       ZOO_PORT: 2181
       ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
      networks:
       default:
        ipv4_address: 172.23.0.12
    
     zoo3:
      image: zookeeper:3.4
      restart: always
      hostname: zoo3
      container_name: zoo3
      privileged: true
      ports:
       - 2183:2181
      volumes:
       - ./zoo3/data:/data
       - ./zoo3/datalog:/datalog
      environment:
       TZ: Asia/Shanghai
       ZOO_MY_ID: 3
       ZOO_PORT: 2181
       ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
      networks:
       default:
        ipv4_address: 172.23.0.13
    
    networks:
     default:
      external:
       name: zoo_kafka

    验证

    从图中我们可以看出,有一个Leader,两个Flower,至此我们的Zookeeper集群就已经搭建好了

    Kafka集群搭建

    有了上面的基础,再去搞Kafka集群还是问题吗?其实就是几个变量值不同而已。

    有了上边的例子,就不费劲去搞单节点的Kafka了,直接使用docker-compose的方式,部署三个节点,其实方式大同小异,上边也说到,其实就是一些属性不同而已;这时候我们就不需要再去新建 Docker 网络了,直接使用前边搭建 Zookeeper 集群时创建的网络即可!

    环境准备

    Kafka镜像:wurstmeister/kafka
    Kafka-Manager镜像:sheepkiller/kafka-manager

    # 不指定版本默认拉取最新版本的镜像
    docker pull wurstmeister/kafka
    docker pull sheepkiller/kafka-manager

    编写 docker-compose.yml 脚本

    使用方式:

    安装 docker-compose

    # 获取脚本
    $ curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    # 赋予执行权限
    $chmod +x /usr/local/bin/docker-compose

    任意目录下新建 docker-compose.yml 文件,复制以下内容

    执行命令 docker-compose up -d

    命令对照
    |命令|解释|
    |-|-|-|
    |docker-compose up|启动所有容器|
    |docker-compose up -d|后台启动并运行所有容器|
    |docker-compose up --no-recreate -d|不重新创建已经停止的容器|
    |docker-compose up -d test2|只启动test2这个容器|
    |docker-compose stop|停止容器|
    |docker-compose start|启动容器|
    |docker-compose down|停止并销毁容器|

    docker-compose.yml下载地址:https://github.com/JacianLiu/docker-compose/tree/master/zookeeper
    docker-compose.yml详细内容

    version: '2'
    
    services:
     broker1:
      image: wurstmeister/kafka
      restart: always
      hostname: broker1
      container_name: broker1
      privileged: true
      ports:
       - "9091:9092"
      environment:
       KAFKA_BROKER_ID: 1
       KAFKA_LISTENERS: PLAINTEXT://broker1:9092
       KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker1:9092
       KAFKA_ADVERTISED_HOST_NAME: broker1
       KAFKA_ADVERTISED_PORT: 9092
       KAFKA_ZOOKEEPER_CONNECT: zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1
       JMX_PORT: 9988
      volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./broker1:/kafka/kafka\-logs\-broker1
      external_links:
      - zoo1
      - zoo2
      - zoo3
      networks:
       default:
        ipv4_address: 172.23.0.14
    
     broker2:
      image: wurstmeister/kafka
      restart: always
      hostname: broker2
      container_name: broker2
      privileged: true
      ports:
       - "9092:9092"
      environment:
       KAFKA_BROKER_ID: 2
       KAFKA_LISTENERS: PLAINTEXT://broker2:9092
       KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker2:9092
       KAFKA_ADVERTISED_HOST_NAME: broker2
       KAFKA_ADVERTISED_PORT: 9092
       KAFKA_ZOOKEEPER_CONNECT: zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1
       JMX_PORT: 9988
      volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./broker2:/kafka/kafka\-logs\-broker2
      external_links: # 连接本compose文件以外的container
      - zoo1
      - zoo2
      - zoo3
      networks:
       default:
        ipv4_address: 172.23.0.15
    
     broker3:
      image: wurstmeister/kafka
      restart: always
      hostname: broker3
      container_name: broker3
      privileged: true
      ports:
       - "9093:9092"
      environment:
       KAFKA_BROKER_ID: 3
       KAFKA_LISTENERS: PLAINTEXT://broker3:9092
       KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker3:9092
       KAFKA_ADVERTISED_HOST_NAME: broker3
       KAFKA_ADVERTISED_PORT: 9092
       KAFKA_ZOOKEEPER_CONNECT: zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1
       JMX_PORT: 9988
      volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./broker3:/kafka/kafka\-logs\-broker3
      external_links: # 连接本compose文件以外的container
      - zoo1
      - zoo2
      - zoo3
      networks:
       default:
        ipv4_address: 172.23.0.16
    
     kafka-manager:
      image: sheepkiller/kafka-manager:latest
      restart: always
      container_name: kafka-manager
      hostname: kafka-manager
      ports:
       - "9000:9000"
      links:      # 连接本compose文件创建的container
       - broker1
       - broker2
       - broker3
      external_links:  # 连接本compose文件以外的container
       - zoo1
       - zoo2
       - zoo3
      environment:
       ZK_HOSTS: zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1
       KAFKA_BROKERS: broker1:9092,broker2:9092,broker3:9092
       APPLICATION_SECRET: letmein
       KM_ARGS: -Djava.net.preferIPv4Stack=true
      networks:
       default:
        ipv4_address: 172.23.0.10
    
    networks:
     default:
      external:  # 使用已创建的网络
       name: zoo_kafka

    验证

    我们打开kafka-manager的管理页面,访问路径是,宿主机ip:9000;


    如果所示,填写上Zookeeper集群的地址,划到最下边点击save

    点击刚刚添加的集群,可以看到,集群中有三个节点

    搭建过程中遇到的问题

    挂载数据卷无限重启,查看log提示:chown: changing ownership of ‘/var/lib/mysql/....‘: Permission denied

    解决方式:

    kafka-manager报jmx相关错误,

    解决方法:

    [error] k.m.j.KafkaJMX$ - Failed to connect to service:jmx:rmi:///jndi/rmi://9.11.8.48:-1/jmxrmi java.lang.IllegalArgumentException: requirement failed: No jmx port but jmx polling enabled!

    在容器中查看topic时报以下错误(不仅仅是topic的命令,好像所有的都会出错)

    $ bin/kafka-topics.sh --list --zookeeper zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1
    # 以下是错误
    Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 7203; nested exception is:
        java.net.BindException: Address already in use

    解决方法:

    在命令前加上unset JMX_PORT;指令,上边的命令改造为:

    $ unset JMX_PORT;bin/kafka-topics.sh --list --zookeeper zoo1:2181/kafka1,zoo2:2181/kafka1,zoo3:2181/kafka1

    附:Docker常用指令

    # 查看所有镜像
    docker images
    # 查看所有运行中的容器
    docker ps
    # 查看所有容器
    docker ps -a
    # 获取所有容器ip
    $ docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
    # 查看容器内部日志
    $ docker logs -f <容器ID>
    # 进入容器内部
    $ docker exec -it <容器ID> /bin/basj
    # 创建容器 -d代表后台启动
    docker run --name <容器名称> -e <参数> -v <挂载数据卷> <容器ID>
    # 重启容器
    docker restart <容器ID>
    # 关闭容器
    docker stop <容器id>
    # 运行容器
    docker start <容器id>

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    上一篇:利用docker-compsoe部署前后端分离的项目方法
    下一篇:linux模糊查找文件用什么命令比较好
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Docker搭建Zookeeper&Kafka集群的实现 Docker,搭建,Zookeeper,amp,Kafka,