最近在做一个演示项目 https://github.com/cnscud/cavedemo, 自然为了方便, 也做了docker打包, 发现zookeeper的镜像没有导入初始化数据的功能, 于是自己做了一个镜像, 还是蛮简单的.

镜像已经发布在 https://hub.docker.com/r/cnscud/zookeeper 官方仓库.

使用方法1: 命令行直接运行

没参数的话和官方镜像一样, 也可以指定参数, 建议用docker-compose.

docker run --name zk1 -d -p 2181:2181 cnscud/zookeeper:zk3.6-0.1

使用docker-compose, 方便设定参数

下面是一个例子: samples/docker-compose1/docker-compose.yml:

version: '3'
services:
cnscud-zookeeper:
image: cnscud/zookeeper:zk3.6-0.1
volumes:
- ./init.data:/init.data/
- ./rundata/data:/data
- ./rundata/logs:/datalog
container_name: cnscud-sample-zk1
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ports:
- "2181:2181"
restart: on-failure
## use the hostname in project
hostname: cnscud-sample-zk1.cnscud.com

你可以在 samples/docker-compose1 目录下发现所需的所有文件: https://github.com/cnscud/cnscud-docker/tree/main/docker-zookeeper/samples/docker-compose1

初始化数据使用说明

我们可以看到, 在volume里绑定了一个 /init.data/ 目录, 那么还有什么特定规则哪?

需要准备一个 脚本文件 "import.data.zk.sh", 放在这个目录里, 用来初始化数据, 至于文件内容, 就根据你的需要来编写了.

下面是一个例子, 是从文件里读取节点内容, 并设置到zookeeper的节点上去.

#!/bin/bash

## for init zookeeper data, you need update this file.
##
## author: felix zhang https://github.com/cnscud/ 2021.8.22
##
## please make sure the file 755
## CMD=`which zkCli.sh`
find="1"
if [ -z $CMD ]
then
find="0"
fi if [ $find = "0" ]
then
CMD="$ZK_HOME/bin/zkCli.sh"
fi echo $CMD if [ -z $CMD ]
then
echo "not found zkCli.sh, please check!!!"
exit 1
fi $CMD create /xpower "1"
$CMD create /xpower/cache "1"
$CMD create /xpower/config "1"
$CMD create /xpower/dbn "1" ## read from file!!!
## read from file!!!
## read from file!!!
$CMD create /xpower/cache/redis.test "`cat /init.data/redis.test.conf`"
$CMD create /xpower/config/kafka "`cat /init.data/kafka.conf`"
$CMD create /xpower/dbn/cavedemo "`cat /init.data/mysql.cavedemo.conf`"

我们可以看到这个脚本做了几件事:

  • 查找zkCli.sh, 并设置正确的路径
  • 创建各级节点
  • 创建最终的节点, 节点的内容是从文件读取的, 可以支持换行和双引号等, 要特别注意这个语法.

在这个脚本里, 使用zookeeper自带的zkCli.sh 脚本创建你的节点, 可以通过下面的命令从文件读入节点内容:

"cat /init.data/kafka.conf"

要注意这个脚本里用到的文件要实现放到统一目录下, 或者其他绑定的目录下.

更多配置选项

因为继承的是官方的zookeeper docker镜像, 所以更多信息可以参考 https://hub.docker.com/_/zookeeper.

原理分析

我们用 docker inspect 或者直接查看git仓库可以看到官方docker的设置:

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["zkServer.sh", "start-foreground"]

如果我们需要导入数据, 则需要先后台启动zookeeper, 执行导入操作, 然后重启zookeeper, 不过要放在foreground方式启动.

看看这个重写的dockerfile:

FROM zookeeper:3.6

##
## docker image for zookeeper with init data feature.
##
## author: Felix Zhang<cnscud@gmail.com> 2021.8.23
## website: https://github.com/cnscud/cnscud-docker LABEL OG=cnscud.com
LABEL maintainer="Felix Zhang<cnscud@gmail.com>"
LABEL reference="https://github.com/cnscud/cnscud-docker" ## my entrypoint script
ADD cnscud-docker-entrypoint.sh / ## timezone
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ## declare the volumen for init data
VOLUME /init.data ## declare the port
EXPOSE 2181 ## =================================== ## from official zookeeper as reference
# ENTRYPOINT ["/docker-entrypoint.sh"]
# CMD ["zkServer.sh" "start-foreground"] ENTRYPOINT ["/cnscud-docker-entrypoint.sh"]
CMD ["zkServer.sh","start-foreground"]

里面重新声明了ENTRYPOINT, 换成了自定义版本的 cnscud-docker-entrypoint.sh. 里面还声明了VOLUME /init.data .

当然我们尽量复用原有的脚本, 而不是改的面目全非(毕竟那么乱...), 我们来看看:

#!/bin/bash
## script for support import data with zookeeper
## author: felix zhang 2021.8.22
## please make sure the file 755 # set -e initedfile="/data/zk.cnscud.inited"
initcmdfile='/init.data/import.data.zk.sh' needcallinit="Y" #
if [ ! -f "$initedfile" ]
then
needcallinit="Y${needcallinit}"
else
echo "[cnscud] data had inited, will not init again."
fi if [ -f "$initcmdfile" ]
then
needcallinit="Y${needcallinit}"
else
echo "[cnscud] not found script for init data, skip."
fi echo "check needcallinit is: $needcallinit" ## start my import data ====================
if [ $needcallinit = "YYY" ]
then ## start in backgroup by original entry point
/docker-entrypoint.sh zkServer.sh start ## waiting for zookeeper
sleep 10 echo "[cnscud] call init data now..."
date > "$initedfile" ##import data
sh $initcmdfile >> $initedfile /docker-entrypoint.sh zkServer.sh stop ## mark
echo "[cnscud] mark: init was finished!"
date >> "$initedfile"
echo "done" >> "$initedfile"
fi ## end my import data ==================== echo "[cnscud] Starting Zookeeper in foreground mode..."
/docker-entrypoint.sh $@

我们可以看到这个代码其实很简单, 虽然很多行:

  • 首选判断是否已经执行过, 用 /data/zk.cnscud.inited 文件方式来标记
  • 如果没有初始化过, 则后台方式启动zkServer
  • 执行初始化脚本
  • 停止 zkServer
  • 重新按默认参数或传入的参数启动zkServer.

感想

其实很简单, 只不过第一次发布镜像到docker hub, 没想到社区非常开放, 任何人都能发布镜像上去, 就导致很混乱, 很多镜像没有说明, 没有人维护, 但下载量很大. 希望不要像npm那么出现问题.

docker很好, 准备好内存和硬盘~!

感谢

感谢google, stackoverflow, withpy 以及我的家人.

支持初始化数据的Zookeeper Docker镜像的更多相关文章

  1. 给Ocelot做一个Docker 镜像

    写在前面 在微服务架构中,ApiGateway起到了承前启后,不仅可以根据客户端进行分类,也可以根据功能业务进行分类,而且对于服务调用服务也起到了很好的接口作用.目前在各个云端中,基本上都提供了Api ...

  2. docker 镜像仓库 Harbor 部署 以及 跨数据复制

    docker 镜像仓库 Harbor 部署 跨数据复制 Harbor 是 Vmwar 公司开源的 企业级的 Docker Registry 管理项目 它主要 提供 Dcoker Registry 管理 ...

  3. Docker创建支持ssh服务的容器和镜像

    原文链接:Docker创建支持ssh服务的容器和镜像 1. 这里使用的centos作为容器,所以首先下载centos的images # sudo docker pull centos 2. 下载后执行 ...

  4. 如何使用vs将asp.net core项目添加容器支持并发布docker镜像到私有dockerhub和添加k8s/helm管理

    这篇文章介绍一下,如何使用VS2017给asp.net core添加容器支持,并发布镜像到私有docker hub,然后用chart管理容器镜像的操作流程. 话不多说,just do it. 新建项目 ...

  5. 解决UnicodeEncodeError。python的docker镜像增加locale 中文支持

    用pandas的pd.read_excel()打开中文名的xlsx,报错,本来以为是xlrd的问题后来发现,是open()函数就报错: “UnicodeEncodeError: 'ascii' cod ...

  6. Docker使用Dockerfile创建支持ssh服务自启动的容器镜像

    原文链接:Docker使用Dockerfile创建支持ssh服务自启动的容器镜像 1. 首先创建一个Dockerfile文件.文件内容例如以下 # 选择一个已有的os镜像作为基础 FROM cento ...

  7. 花一分钟体验 Apache DolphinScheduler 第一个官方 Docker 镜像

    先前Apache DolphinScheduler 社区一直是发布 Dockerfile 和 K8s Chart.yaml 文件,由用户自行 build 镜像.随着越来越多的用户伙伴们的呼声高涨,社区 ...

  8. Docker 镜像之存储管理

    笔者在<Docker 镜像之进阶篇>中介绍了镜像分层.写时复制以及内容寻址存储(content-addressable storage)等技术特性,为了支持这些特性,docker 设计了一 ...

  9. 操作系统-容器-Docker:如何将应用打包成为 Docker 镜像?

    ylbtech-操作系统-容器-Docker:如何将应用打包成为 Docker 镜像? 1.返回顶部 1. 虽然 DockerHub 提供了大量的镜像,但是由于企业环境的多样性,并不是每个应用都能在 ...

随机推荐

  1. java基础---类和对象(3)

    一.Object类 java.lang.Object类是Java语言中类层次结构的根类,也就是说任何一个类都是该类的直接或者间接子类 如果定义一个Java类时没有使用extends关键字声明其父类,则 ...

  2. 《快来为你的 .NET 应用加个监控吧!》更新版本啦

    目录 导读 三种方式处理监控数据 主动推送 ASP.NET Core 自定义URL .NET diagnostics 自定义监控指标 导读 CZGL.ProcessMetrics 是一个 Metric ...

  3. 常见数据库SELECT结果只显示前几条记录方法汇总

    常见数据库SELECT结果只显示前几条记录方法汇总 为了查看数据表中的数据情况.经常会遇到想让查询结果只显示N行,比如只显示10行的情况.不同的数据库有不同的关键字和SELECT实现语法. 1.SQL ...

  4. java面向对象程序设计(下)-枚举类

    在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有4个对象;再比如行星类,目前只有8个对象,这些实例有限而且固定的类,在Java中被称为枚举类 JDK1.5新增了一个enum关键字,(它与 ...

  5. [刘阳Java]_Web前端入门级练习_迅雷首页第一屏设计

    今天接着上一篇文章<Web前端入门级练习_迅雷官宣网设计>正式开始迅雷首页第一版的设计.如果完成,则最终的效果图如下 第一步:先完成logo部分的设计 logo设计,我们会使用CSS的定位 ...

  6. Appium -- adb monkey操作(一)

    1.Monkey简介在Android的官方自动化测试领域有一只非常著名的"猴子"叫Monkey,这只"猴子"一旦启动,就会让被测的Android应用程序像猴子一 ...

  7. GraphQL 概念入门

    GraphQL 概念入门 Restful is Great! But GraphQL is Better. -- My Humble Opinion. GraphQL will do to REST ...

  8. tensorflow2 自定义损失函数使用的隐藏坑

    Keras的核心原则是逐步揭示复杂性,可以在保持相应的高级便利性的同时,对操作细节进行更多控制.当我们要自定义fit中的训练算法时,可以重写模型中的train_step方法,然后调用fit来训练模型. ...

  9. PAT乙级:1083 是否存在相等的差 (20分)

    PAT乙级:1083 是否存在相等的差 (20分) 题干 给定 N 张卡片,正面分别写上 1.2.--.N,然后全部翻面,洗牌,在背面分别写上 1.2.--.N.将每张牌的正反两面数字相减(大减小), ...

  10. 重新手写一个Vue

    该版把上一次的数据修改就更新全部页面改为了局部更新,相比于上一版的在数据绑定上不是简单的一个监听set再全部更新,具体见下文. 总体流程 仍然是根据自己理解来实现的绑定,相较于上一版的数据更新就全部刷 ...