使用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 '\n' ' '`)
      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節點掛掉。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM