最近在做一个演示项目 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. PHP大文件分片上传的实现方法

    一.前言 在网站开发中,经常会有上传文件的需求,有的文件size太大直接上传,经常会导致上传过程中耗时太久,大量占用带宽资源,因此有了分片上传. 分片上传主要是前端将一个较大的文件分成等分的几片,标识 ...

  2. python使用笔记24--面向对象编程2

    类方法 类里面自带的方法,不用实例化就可以调用,想象,模型上自带的功能 类方法是公共的,在实例方法里面可以随意调用 但是在类方法里不能调用实例方法,不能使用实例变量,但是他可以调用其他的类方法 1 @ ...

  3. c语言:解释程序和编译程序

    编译程序和解释程序是程序执行的两种不同执行方式. 编译程序:编译程序的功能是把用高级语言书写的源程序翻译成与之等价的目标程序.编译过程划分成词法分析.语法分析.语义分析.中间代码生成.代码优化和目标代 ...

  4. ES6 模块export import

    在 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS(分别是基于 AMD 规范的模块化库, 和基于 CMD 规范的模块化库).ES6 引入了模块化,其设计思想是在编译时就能确定模 ...

  5. Python+Requests+Xpath(解析)爬取某站点简历图片(数据分析三)

    1.环境安装 pip install lxml 2.解析原理 使用通用爬虫爬取网页数据 实例化etree对象,且将页面数据加载到该对象中 使用xpath函数结合xpath表达式进行标签定位和指定数据提 ...

  6. Apache HBase 1.7.1 发布,分布式数据库

    Apache HBase 是一个开源的.分布式的.版本化的.非关系的数据库.Apache HBase 提供对数十亿个数据的低延迟随机访问在非专用硬件上有数百万列的行. 关于 HBase更多内容,请参阅 ...

  7. SQL慢查询排查思路

    前言 平时在工作中每天都会做巡检,将前一天所有超过500ms的慢SQL排查出来 查找原因,是否能进行优化.慢慢中,在形成了一套思路方法论. 我个人认为对于排查慢SQL还是有一定的帮助 (一).是否是S ...

  8. PostgreSQL-WITH AS短语

    WITH提供了一种方式来书写在一个大型查询中使用的辅助语句.这些语句通常被称为公共表表达式或CTE,它们可以被看成是定义只在一个查询中存在的临时表.在WITH子句中的每一个辅助语句可以是一个SELEC ...

  9. 基于pygame框架的打飞机小游戏

    import pygame from pygame.locals import * import time import random class Base(object): "" ...

  10. 选择排序(selection_sort)——Python实现

      # 选择排序 # 作用:对给出的n个顺序不定的数进行排序 # 输入:任意数组A # 输出:按顺序排列的数组A # 时间复杂度 (n(n-1))/2 # 选择排序 # 第一趟:选择第一个元素,依次与 ...