Docker-compose部署单主机zookeeper集群
Docker安装可以参考我以前写的这个zookeeper官网zookeeper简要介绍ZooKeeper是分布式应用程序的高性能协调服务,用于维护配置信息、命名、提供分布式同步和提供组服务。众所周知,协调服务很难做好。它们特别容易出现诸如竞争条件和死锁之类的错误。ZooKeeper 背后的动机是减轻分布式应用程序从头开始实现协调服务的责任。分布式应用程序可以基于ZooKeeper实现诸如数据发布/
Docker-compose安装 可以参考这个
zookeeper简要介绍
ZooKeeper是分布式应用程序的高性能协调服务,用于维护配置信息、命名、提供分布式同步和提供组服务。众所周知,协调服务很难做好。它们特别容易出现诸如竞争条件和死锁之类的错误。ZooKeeper 背后的动机是减轻分布式应用程序从头开始实现协调服务的责任。
zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
ZooKeeper常用的使用场景就是用于担任服务注册中心。服务提供者将自己的信息注册到ZooKeeper,服务消费者在进行服务调用的时候先到ZooKeeper中查找服务,获取到服务提供者的信息之后,再去调用服务提供者的接口。
搜索zookeeper可用镜像
docker search zookeeper
安装官方最新版镜像(先不手动拉取也可以,这里安装了,后面docker-compose就不会从远程仓库拉取了,不然他会先从远程仓库拉取镜像)
docker pull zookeeper:latest
查看这个镜像的详细信息
docker inspect zookeeper
查看镜像元信息可以得知,我们使用的是zookeeper-3.7.0
创建文件夹
在服务器上部署三个zookeeper节点
服务器创建如下文件夹,便于后面容器zookeeper的指定文件夹(日志文件,配置文件等)的挂载
mkdir -p /home/xt/zookeeper/zookeeper-1/data
mkdir -p /home/xt/zookeeper/zookeeper-1/datalog
mkdir -p /home/xt/zookeeper/zookeeper-1/logs
mkdir -p /home/xt/zookeeper/zookeeper-1/conf
mkdir -p /home/xt/zookeeper/zookeeper-2/data
mkdir -p /home/xt/zookeeper/zookeeper-2/datalog
mkdir -p /home/xt/zookeeper/zookeeper-2/logs
mkdir -p /home/xt/zookeeper/zookeeper-2/conf
mkdir -p /home/xt/zookeeper/zookeeper-3/data
mkdir -p /home/xt/zookeeper/zookeeper-3/datalog
mkdir -p /home/xt/zookeeper/zookeeper-3/logs
mkdir -p /home/xt/zookeeper/zookeeper-3/conf
赋予所有用户对/home/xt/zookeeper文件下的所有文件的读写可执行权限
-R 对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
真正开发的时候不建议赋予所有用户最高权限(自己分好用户组,分别给不同的用户组以不同的权限,避免其他用户不小心修改或删除文件)
chmod -R 777 /home/xt/zookeeper
在每个zookeeper文件夹下面的conf文件夹下创建配置文件zoo.cfg
clientPort=2181
dataDir=/data
dataLogDir=/datalog
tickTime=2000
initLimit=5
syncLimit=2
autopurge.snapRetainCount=3
autopurge.purgeInterval=0
maxClientCnxns=60
standaloneEnabled=true
admin.enableServer=true
#和下面的docker-compose 创建的docker container实例对应
server.1=zookeeper-1:2888:3888
server.2=zookeeper-2:2888:3888
server.3=zookeeper-3:2888:3888
clientPort:客户端连接端口,监听客户端连接的端口(默认2181)
dataDir:数据文件目录+数据持久化路径
dataLogDir:日志文件目录
tickTime:通信心跳数,Zookeeper服务器心跳时间,单位毫秒 ,ZooKeeper中最小的时间单位长度 (默认2000ms)
Zookeeper使用的基本时间,服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳,时间单位为毫秒。它用于心跳机制,并且设置最小的session超时时间为两倍心跳时间。(session的最小超时时间是2*tickTime)
initLimit:leader节点和follower节点的初始通信时限,follower节点启动后与leader节点完成数据同步的时间(指定为tickTime的倍数,默认10倍,即20s)。
集群中的followe节点与leader节点之间初始连接时能容忍的最多心跳数(tickTime的数量),用它来限定集群中的Zookeeper服务器连接到Leader的时限。投票选举新leader的初始化时间。
Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。Leader允许follower节点在initLimit时间内完成这个工作。
syncLimit:leader节点和follower节点同步通信时限,进行心跳检测的最大延迟时间(指定为tickTime的倍数,默认5倍,即10s)。
集群中Leader节点与Follower节点之间的最大响应时间单位,假如响应超过syncLimit *
tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。如果leader节点发出心跳包在syncLimit之后,还没有从follower节点那收到响应,那么就认为这个follower节点已经不在线了。
将log4j.properties日志配置文件也放在每个zookeeper文件夹下面的conf文件夹下
自己下一个指定版本的zookeeper包,自己通过xftp软件移动到服务器上面
这里我把log4j的日志输出文件路径修改了一下,修改到/logs,然后挂载到服务器的logs文件件,我们可以在这里查看log4j的日志文件
zookeeper.log.dir=/logs
# Copyright 2012 The Apache Software Foundation
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=/logs
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=INFO
zookeeper.log.maxfilesize=256MB
zookeeper.log.maxbackupindex=20
zookeeper.tracelog.dir=${zookeeper.log.dir}
zookeeper.tracelog.file=zookeeper_trace.log
log4j.rootLogger=${zookeeper.root.logger}
#
# console
# Add "console" to rootlogger above if you want to use this
#
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
#
# Add ROLLINGFILE to rootLogger to get log file output
#
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=${zookeeper.log.maxfilesize}
log4j.appender.ROLLINGFILE.MaxBackupIndex=${zookeeper.log.maxbackupindex}
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
#
# Add TRACEFILE to rootLogger to get log file output
# Log TRACE level and above messages to a log file
#
log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
log4j.appender.TRACEFILE.Threshold=TRACE
log4j.appender.TRACEFILE.File=${zookeeper.tracelog.dir}/${zookeeper.tracelog.file}
log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
### Notice we are including log4j's NDC here (%x)
log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n
#
# zk audit logging
#
zookeeper.auditlog.file=zookeeper_audit.log
zookeeper.auditlog.threshold=INFO
audit.logger=INFO, RFAAUDIT
log4j.logger.org.apache.zookeeper.audit.Log4jAuditLogger=${audit.logger}
log4j.additivity.org.apache.zookeeper.audit.Log4jAuditLogger=false
log4j.appender.RFAAUDIT=org.apache.log4j.RollingFileAppender
log4j.appender.RFAAUDIT.File=${zookeeper.log.dir}/${zookeeper.auditlog.file}
log4j.appender.RFAAUDIT.layout=org.apache.log4j.PatternLayout
log4j.appender.RFAAUDIT.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n
log4j.appender.RFAAUDIT.Threshold=${zookeeper.auditlog.threshold}
# Max log file size of 10MB
log4j.appender.RFAAUDIT.MaxFileSize=10MB
log4j.appender.RFAAUDIT.MaxBackupIndex=10
创建docker-compose.yml
zookeeper文件夹下创建docker-compose.yml文件如下
version: '3.9'
# 配置zk集群
# container services下的每一个子配置都对应一个zk节点的docker container
# 给zk集群配置一个网络,网络名为zookeeper-net
networks:
zookeeper-net:
name:zookeeper-net
driver: bridge
services:
zookeeper-1:
image: zookeeper
container_name: zookeeper-1
restart: always
# 配置docker container和宿主机的端口映射
ports:
- 2181:2181
- 8081:8080
# 将docker container上的路径挂载到宿主机上 实现宿主机和docker container的数据共享
volumes:
- "/home/xt/zookeeper/zookeeper-1/data:/data"
- "/home/xt/zookeeper/zookeeper-1/datalog:/datalog"
- "/home/xt/zookeeper/zookeeper-1/logs:/logs"
- "/home/xt/zookeeper/zookeeper-1/conf:/conf"
# 配置docker container的环境变量
environment:
# 当前zk实例的id
ZOO_MY_ID: 1
# 整个zk集群的机器、端口列表
ZOO_SERVERS: server.1=zookeeper-1:2888:3888 server.2=zookeeper-2:2888:3888 server.3=zookeeper-3:2888:3888
networks:
- zookeeper-net
zookeeper-2:
image: zookeeper
# 配置docker container和宿主机的端口映射
container_name: zookeeper-2
restart: always
ports:
- 2182:2181
- 8082:8080
# 将docker container上的路径挂载到宿主机上 实现宿主机和docker container的数据共享
volumes:
- "/home/xt/zookeeper/zookeeper-2/data:/data"
- "/home/xt/zookeeper/zookeeper-2/datalog:/datalog"
- "/home/xt/zookeeper/zookeeper-2/logs:/logs"
- "/home/xt/zookeeper/zookeeper-2/conf:/conf"
# 配置docker container的环境变量
environment:
# 当前zk实例的id
ZOO_MY_ID: 2
# 整个zk集群的机器、端口列表
ZOO_SERVERS: server.1=zookeeper-1:2888:3888 server.2=zookeeper-2:2888:3888 server.3=zookeeper-3:2888:3888
networks:
- zookeeper-net
zookeeper-3:
image: zookeeper
container_name: zookeeper-3
restart: always
# 配置docker container和宿主机的端口映射
ports:
- 2183:2181
- 8083:8080
# 将docker container上的路径挂载到宿主机上 实现宿主机和docker container的数据共享
volumes:
- "/home/xt/zookeeper/zookeeper-3/data:/data"
- "/home/xt/zookeeper/zookeeper-3/datalog:/datalog"
- "/home/xt/zookeeper/zookeeper-3/logs:/logs"
- "/home/xt/zookeeper/zookeeper-3/conf:/conf"
# 配置docker container的环境变量
environment:
# 当前zk实例的id
ZOO_MY_ID: 3
# 整个zk集群的机器、端口列表
ZOO_SERVERS: server.1=zookeeper-1:2888:3888 server.2=zookeeper-2:2888:3888 server.3=zookeeper-3:2888:3888
networks:
- zookeeper-net
Zookeeper一共需要用到三个端口:
1、2181:对client端提供服务的端口
2、3888:选举leader使用
3、2888:集群内机器通讯使用(Leader监听此端口)
启动容器
在zookeeper文件夹下,也就是docker-compose.yml文件所在的地方
-d 后台运行
docker-compose up -d
容器启动成功后,可以通过下面命令查看容器状态
docker ps -a
容器转态为UP,启动成功
防火墙开放端口,便于外界访问服务器,如果服务器部署了安全组,则安全组也要开放这些端口(如果运行以下命令没用,建议去服务器控制台手动添加端口,我不太明白,好像两种方式添加的端口,效果不一样,服务器控制台手动添加的端口,用firewall-cmd命令查看不到,如果有知道的大佬烦请评论区评论一下)
firewall-cmd --permanent --add-port=2181/tcp
firewall-cmd --permanent --add-port=2182/tcp
firewall-cmd --permanent --add-port=2183/tcp
firewall-cmd --permanent --add-port=8081/tcp
firewall-cmd --permanent --add-port=8082/tcp
firewall-cmd --permanent --add-port=8083/tcp
重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
查看开放了那些端口
firewall-cmd --list-ports
端口开放好了之后,由于在配置文件中,将zookeeper-1、zookeeper-2、zookeeper-3的容器内部8080端口分别映射到了宿主机上的8081、8082、8083端口,所以我们可以在自己的电脑上通过浏览器访问这三个zk实例内嵌的web控制台:
http://服务器ip:8081/commands
在configuration目录下我们可以看到zk实例的基本配置信息,比如server_id、提供客户端服务的端口、数据目录、日志目录等
在stats目录下可以看到zk实例的运行状态信息,比如节点身份、数据大小、日志大小等.这里三个节点(一个leader,两个follower)
docker-compose.yml文件部分讲解
在启动完容器之后,我们可以查看部分信息
1、网络配置
顶级的networks标签指定创建了一个标识为zookeeper-net的隔离网络,并且给该网络命名为zookeeper-net。虽然这里将标识和命名都设置为zookeeper-net,但其实他们是不同的配置:
网络标志符是为了配置docker container属于某个网络的标志,而命名是为了开发者能够查看和区分宿主机上的所有网络环境,便于了解宿主机上的系统运行情况
查看宿主机上所有网络
docker network ls
services标签下的每一个子标签代表一个docker container实例,以zookeeper-1为例。zookeeper-1标签下的networks子标签,表示将zookeeper-1所对应的docker container加入到标识为zookeeper-net的子网中。
所以这里三个节点在一个网络zookeeper-net里面。
通过如下命令查看容器元数据
docker inspect zookeeper-1
docker inspect zookeeper-2
docker inspect zookeeper-3
zookeeper-1、zookeeper-2、zookeeper-3同属于名为zookeeper-net的网络,该网络的网关是192.168.32.1,zookeeper-1、zookeeper-2、zookeeper-3的ip地址分别为
192.168.32.4、192.168.32.3、192.168.32.2
2、环境变量
zookeeper-1、zookeeper-2、zookeeper-3标签下都有一个environment标签,该标签配置的是容器的环境变量。配置在environment标签下的环境变量最终会被添加到docker container的环境变量中,同样可以通过
docker inspect zookeeper-1
Env标签下除了我们在yml文件中显式配置的环境变量以外,还有一些容器自带的环境变量
ZOO_MY_ID 表示当前zookeeper实例在zookeeper集群中的编号,范围为1-255,所以一个zk集群最多有255个节点
ZOO_SERVERS 表示当前zookeeper实例所在zookeeper集群中的所有节点的编号、端口、主机名(或IP地址)配置
3. 挂载文件
查看容器文件夹的挂载,其他两个zookeeper也一样。(将日志,配置等文件持久化到宿主机)
docker inspect zookeeper-1
我后面将log文件夹修改为了logs(前文配置已修改,主要是log4j的日志输出)
4. 端口映射
查看容器端口映射方面的信息,其余的两个zookeeper也是一样
访问宿主机的2181就等于访问到容器的2181端口
docker inspect zookeeper-1
HostIp:0.0.0.0 代表宿主机的所有IPV4地址
::,代表宿主机的所有IPV6地址
References:
- https://blog.csdn.net/qq_37960603/article/details/121321242
- https://blog.csdn.net/ypp91zr/article/details/89423878
- https://blog.csdn.net/weixin_41622183/article/details/90714190
- https://blog.csdn.net/qq_39340792/article/details/109139406?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_paycolumn_v2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_paycolumn_v2&utm_relevant_index=1
- https://www.cnblogs.com/kingkoo/p/8732448.html
- https://blog.csdn.net/baidu_38432732/article/details/116763281
- https://blog.csdn.net/killer_999/article/details/93762479
- https://blog.csdn.net/milhua/article/details/78931672
- https://zhuanlan.zhihu.com/p/121728783
- https://www.runoob.com/docker/docker-dockerfile.html
(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料和自己的实践,整理不易,但是难免有不足之处,如有错误,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源。)
更多推荐
所有评论(0)