zoukankan      html  css  js  c++  java
  • 使用docker或者docker-compose部署Zookeeper集群

      之前有介绍过Zookeeper的安装部署(Zookeeper基础教程(二):Zookeeper安装),但是那里我是基于独立的虚拟机来实现部署的,这种部署方式适合线上集群部署。后来有几次想用一下Zookeeper,我就需要一次性启动好几台虚拟机,用完还得关闭虚拟机,否则占用内存,这样做甚是麻烦,而且几乎每次开启几台虚拟机之后,电脑内存瞬间爆满!后来也是突然冒出个想法,用Docker来做一个Zookeeper集群,只需要一台安装了Docker的虚拟机即可,这样安装的虚拟机开发测试使用是足够的。最近花点时间整理了一下这些东西,要求部署尽可能简单,随时可以启动停掉,发送给他人也可以很轻松的运行起一套zookeeper,以备临时只需。  

      首先,我们需要安装docker(参考:docker简单安装 ),当然,最简单粗暴的部署方式是先使用docker在同一网络下开几个容器,然后获取他们的IP,然后进入容器中,安装之前介绍的方法安装集群,这样部署是可行的,但是很繁琐。现在介绍Zookeeper官方推荐部署方式(参考:https://hub.docker.com/_/zookeeper)。

      首先,获取官方的Zookeeper镜像(先去喝杯茶,下载很慢!):  

        # 查找Zookeeper镜像
        sudo docker search zookeeper
        # 拉取Zookeeper镜像
        sudo docker pull zookeeper

      

      接下来就是部署了。

      如果是单节点部署,只需要执行docker命令启动一个容器即可:  

        # 创建并启动容器
        sudo docker run -d -p 2181:2181 -e "ZOO_MY_ID: 1" -e "ZOO_SERVERS: server.1=zoo1:2888:3888;2181" --name zoo zookeeper
        # 停止并删除容器
        sudo docker stop zoo && sudo docker rm zoo

      其中有两个环境变量:  

        ZOO_MY_ID:Zookeeper节点的Id
        ZOO_SERVERS:Zookeeper节点列表,多个节点之间使用空格隔开

      如果是集群部署,我提供两种方式(下载链接: https://pan.baidu.com/s/1L0LinFZVwHL6J67TNDFH3w 提取码: jgah):

      Shell脚本部署集群

      官方推荐使用docker-compse,而我觉得使用命令行比较灵活,所以我写了一个shell脚本:  

      
    #!/bin/bash
    
    count=3                        #节点数
    network_name="net-zoo"         #集群所在网络名
    client_port_start=2181         #集群绑定主机初始节点(不包括)
    name_prefix="zoo"              #集群容器名前缀
    
    #停止
    zookeeper_stop(){
      for i in $(seq 1 $count); do
        zoo_name="$name_prefix$i"
        echo 停止容器:`sudo docker stop $zoo_name`
      done
    }
    #启动
    zookeeper_start(){
      for i in $(seq 1 $count); do
        zoo_name="$name_prefix$i"
        echo 启动容器:`sudo docker start $zoo_name`
      done
      #打印集群信息
      if [ -z "$client_servers" ];then
        if [ -z "$local_ip" ];then
          ips=(`/sbin/ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | tr -d "addr:" | tr '
    ' ' '`)
          index=${#ips[@]}
          index=`expr $index - 1`
          local_ip=${ips[$index]}
        fi
        for i in $(seq 1 $count); do
          port=`expr $i + $client_port_start` # 客户端服务接口
          if [ $i -eq $count ];then
            client_servers="${client_servers}${local_ip}:${port}"
          else
            client_servers="${client_servers}${local_ip}:${port},"
          fi
        done
      fi
      echo 集群服务地址:$client_servers
    }
    #停止并移除
    zookeeper_down(){
      zookeeper_stop
      for i in $(seq 1 $count); do
        zoo_name="$name_prefix$i"
        echo 删除容器:`sudo docker rm $zoo_name`
      done
      if [ "$1" != "network" ];then
        echo 删除网络:`sudo docker network rm $network_name`
      fi
    }
    #重新启动
    zookeeper_restart(){
      zookeeper_stop
      zookeeper_start
    }
    #查看容器状态
    zookeeper_status(){
      sudo docker ps -a | grep "$name_prefix*"
    }
    #创建
    zookeeper_create(){
      net_exists=`sudo docker network ls | grep "$network_name"`
      if [ -z "$net_exists" ];then
        echo 创建网络:` sudo docker network create --driver bridge $network_name`
      fi
      for i in $(seq 1 $count); do
        index=`expr $i + 1`
        node="server.$i=$name_prefix$i:2888:3888;2181"
        echo 节点:$node
        if [ $i -eq 1 ];then
          servers=$node
        else
          servers="$servers $node"
        fi
      done
      for i in $(seq 1 $count); do
        zoo_port=`expr $i + $client_port_start`
        echo 创建容器:`sudo docker create -i --name $name_prefix$i --hostname $name_prefix$i --restart always -p $zoo_port:2181 -e "ZOO_MY_ID=$i" -e ZOO_SERVERS="$servers" --network $network_name zookeeper`
      done
      echo 创建完成
    }
    #创建并启动
    zookeeper_up(){
      zookeeper_create
      zookeeper_start
    }
    
    if [ ! -z "$1" ];then
      zookeeper_$1 $2
      exit 0
    fi
    
    echo "
    Usage:    $0 COMMAND
    
    可用命令:
    start    启动集群
    create   创建集群
    stop     停止集群服务
    up       创建并启动集群
    down     停止并删除集群
    status   查看集群容器节点信息
    restart  重新启动集群"
    zookeeper.sh

      您可以将上面的shell脚本复制到一个shell文件中,比如复制到一个名为zookeeper.sh的文件中,脚本内容很容易理解,开头有四个配置:

        count:集群节点数
        network_name:集群所在网络名
        client_port_start:集群绑定主机初始节点(不包括这个临界值)
        name_prefix:集群容器名前缀

      然后赋予可执行权限或者直接以bash执行(不要使用dash或者sh命令执行):  

        # 添加可执行权限,不添加可执行权限则可直接使用 /bin/bash zookeeper.sh 执行,用dash或者sh命令可能会报错
        sudo chmod +x zookeeper.sh
        # 启动
        ./zookeeper.sh up
        # 停止 
        ./zookeeper.sh down

      比如我虚拟机IP:192.168.209.128,启动后:

      

      然后使用 192.168.209.128:2182,192.168.209.128:2183,192.168.209.128:2184 就可以连接到容器充的zookeeper了。

       docker-compose部署

      官方给出了docker-compose的部署方案,首先创建一个docker-compose.yml文件,内容如下:

    # yaml 配置
    version: '2'
    services:
        zoo1:
            image: zookeeper
            restart: always
            ports:
                - 2182: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
        zoo2:
            image: zookeeper
            restart: always
            ports:
                - 2183: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
        zoo3:
            image: zookeeper
            restart: always
            ports:
                - 2184: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

      这里有两点需要注意:

      1、ports是提供了客户端端口映射,外部要连接到容器中的zookeeper,需要使用主机的这个映射端口

      2、这里没有使用数据卷,而是直接使用的了环境变量作为配置,启动最主要的就是ZOO_MY_ID和ZOO_SERVERS两个(更多环境变量配置参考:https://hub.docker.com/_/zookeeper):  

        ZOO_MY_ID:节点ID
        ZOO_SERVERS:集群节点地址,多个节点之间使用空格隔开

      说明一下,上面docker-compose.yml中的ZOO_SERVERS环境变量中的zoo1,zoo2,zoo3等表示的是service_name或者container_name,因为在同一网络下,因此容器可以使用service_name或者container_name互通,而不需要配置link或者hosts等。

      然后启动:  

        # 启动
        sudo docker-compose up -d
        # 停止
        sudo docker-compose down

      比如我虚拟机IP:192.168.209.128,启动后:

      

      上面说道ports配置是端口映射,因此使用 192.168.209.128:2182,192.168.209.128:2183,192.168.209.128:2184 就可以连接到容器充的zookeeper了。

       

      总结

      1、使用shell脚本的好处就是可以更灵活,比如要拓展到5个节点的zookeeper集群,只需修改shell中的count变量值为5

      2、使用docker-compose部署相对来说说稍稳定,但是配置更繁琐

      3、使用docker部署zookeeper的做法只适合自己开发测试使用,生产不建议这么使用,因为如果一台服务宕机,会导致服务器上所有的zookeeper节点挂掉。

    一个专注于.NetCore的技术小白
  • 相关阅读:
    某电校园网
    M100(3) 无线数传
    【转】大厦将倾,互联网将如何变革传统行业(下)
    【转】大厦将倾,互联网将如何变革传统行业(上)
    【转】用户十秒离开你网站的25个原因
    web及移动应用测试知识总结
    【转】Watir, Selenium & WebDriver
    ICMP协议
    我不会OOO,仍然可以XXX_转
    查看网络连接数目(解决TIME_WAIT过多造成的问题_转)
  • 原文地址:https://www.cnblogs.com/shanfeng1000/p/14488665.html
Copyright © 2011-2022 走看看