Zookeeper简介

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

特点:

  • 顺序一致性:从一个客户端发起的事务请求,最终都会严格按照其发起顺序被应用到 Zookeeper 中;
  • 原子性:所有事务请求的处理结果在整个集群中所有机器上都是一致的;不存在部分机器应用了该事务,而另一部分没有应用的情况;
  • 单一视图:所有客户端看到的服务端数据模型都是一致的;
  • 可靠性:一旦服务端成功应用了一个事务,则其引起的改变会一直保留,直到被另外一个事务所更改;
  • 实时性:一旦一个事务被成功应用后,Zookeeper 可以保证客户端立即可以读取到这个事务变更后的最新状态的数据。

官方网站:Docker Hub

1.前期准备

拉取镜像:[root@localhost user]# docker pull zookeeper

查看镜像元数据:docker search zookeeper

#可以看到暴露端口
"ExposedPorts": {
    "2181/tcp": {},
    "2888/tcp": {},
    "3888/tcp": {},
    "8080/tcp": {}
},
#挂载文件位置
"Volumes": {
	"/data": {},
	"/datalog": {},
	"/logs": {}
},

新建brige网络

a50909d91e3a06f3d7f486346b90a86f4c592b7a5102378fa45f9b50033962f4
[root@localhost Documents]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a50909d91e3a   bnet      bridge    local
2c7af5b0b1e8   bridge    bridge    local
bb48cb62ce59   host      host      local
3e98202319e6   none      null      local
[root@localhost Documents]# docker inspect bnet 
[
    {
        "Name": "bnet",
        "Id": "a50909d91e3a06f3d7f486346b90a86f4c592b7a5102378fa45f9b50033962f4",
        "Created": "2022-07-14T08:05:58.64086024+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.88.0.0/16",
                    "Gateway": "172.88.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

2.创建容器并加入网络

#取消开机自启动的话使用docker update --restart=no <容器id>
#选择一个自己想要挂载的目录下面执行下面命令
docker run -d -p 2181:2181 --name zookeeper_1 --privileged --restart always --network bnet --ip 172.88.0.2 \
-v $PWD/zookeeper_nodes/node_1/volumes/data:/data \
-v $PWD/zookeeper_nodes/node_1/volumes/datalog:/datalog \
-v $PWD/zookeeper_nodes/node_1/volumes/logs:/logs \
-e ZOO_MY_ID=1 \
-e "ZOO_SERVERS=server.1=172.88.0.2:2888:3888;2181 server.2=172.88.0.3:2888:3888;2181 server.3=172.88.0.4:2888:3888;2181" \
zookeeper:latest

docker run -d -p 2182:2181 --name zookeeper_2 --privileged --restart always --network bnet --ip 172.88.0.3 \
-v $PWD/zookeeper_nodes/node_2/volumes/data:/data \
-v $PWD/zookeeper_nodes/node_2/volumes/datalog:/datalog \
-v $PWD/zookeeper_nodes/node_2/volumes/logs:/logs \
-e ZOO_MY_ID=2 \
-e "ZOO_SERVERS=server.1=172.88.0.2:2888:3888;2181 server.2=172.88.0.3:2888:3888;2181 server.3=172.88.0.4:2888:3888;2181" \
zookeeper:latest

docker run -d -p 2183:2181 --name zookeeper_3 --privileged --restart always --network bnet --ip 172.88.0.4 \
-v $PWD/zookeeper_nodes/node_3/volumes/data:/data \
-v $PWD/zookeeper_nodes/node_3/volumes/datalog:/datalog \
-v $PWD/zookeeper_nodes/node_3/volumes/logs:/logs \
-e ZOO_MY_ID=3 \
-e "ZOO_SERVERS=server.1=172.88.0.2:2888:3888;2181 server.2=172.88.0.3:2888:3888;2181 server.3=172.88.0.4:2888:3888;2181" \
zookeeper:latest

查看节点状态

CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                                                     NAMES
e320f64c4464   zookeeper:latest   "/docker-entrypoint.…"   8 seconds ago   Up 6 seconds   2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2183->2181/tcp, :::2183->2181/tcp   zookeeper_3
a4319d506690   zookeeper:latest   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2182->2181/tcp, :::2182->2181/tcp   zookeeper_2
9005598985e5   zookeeper:latest   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 8080/tcp   zookeeper_1
[root@localhost home]# docker exec -it zookeeper_1 /bin/bash
root@9005598985e5:/apache-zookeeper-3.7.0-bin# ./bin/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

root@a4319d506690:/apache-zookeeper-3.7.0-bin# ./bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader

[root@localhost home]# docker exec -it zookeeper_3 /bin/bash
root@e320f64c4464:/apache-zookeeper-3.7.0-bin# ./bin/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

集群生成脚本

#!/bin/bash

echo "删除所有zookeeper容器"
sudo docker ps -a | grep zookeeper_ | awk '{print $1}' | xargs -I {} sudo docker rm -f {}

# 设置节点个数
num_nodes=3
if [ $# -ge 1 ] && [ $1 -ge 0 ];then
    num_nodes=$1
fi

# 设置存储位置
data_path=/data/zookeeper_nodes
if [ -d $data_path ];then
    sudo rm -rf $data_path
fi

# 设置集群IP
ip_prefix="172.88.0"
servers=""
for i in `seq $num_nodes`; do
    servers="$servers server.$i=zookeeper_$i:2888:3888;2181"
done
servers=${servers#* }

temp_file="init_containers.sh"
echo > $temp_file

for i in `seq $num_nodes`; do
    cmd="sudo docker run -d 
    -p `expr 2181 + $i`:2181 
    --name zookeeper_$i 
    --hostname zookeeper_$i 
    --privileged 
    --restart always 
    --network bnet 
    --ip $ip_prefix.`expr $i + 1` 
    -v $data_path/zookeeper_nodes/node_$i/volumes/data:/data 
    -v $data_path/zookeeper_nodes/node_$i/volumes/datalog:/datalog 
    -v $data_path/zookeeper_nodes/node_$i/volumes/logs:/logs 
    -e ZOO_MY_ID=$i 
    -e ZOO_SERVERS='$servers' 
    zookeeper:latest"
    echo $cmd >> $temp_file
    echo >> $temp_file
done
echo "创建具有$num_nodes个节点的zookeeper集群"
sh $temp_file && rm -f $temp_file