使用Docker构建ZooKeeper镜像
这篇文章中我们将使用 Docker 创建 Zookeeper 镜像,包括如何将 Zookeeper 安装到容器,如何配置 ZooKeeper 应用程序以及如何在宿主机和容器之间共享数据卷。
本教程利用 Dockerfile 来指定容器的内容。如果您需要有关编写 Dockerfile 的更多信息,请参阅官方文档。
1. 指定基础镜像
Docker 容器基于基础 Linux 映像构建而成。这些镜像提供了容器的核心功能,并使用 FROM 命令来指定。FROM 命令允许我们同时指定镜像以及 Tag,其中 Tag 标记了镜像的版本。在下面 Dockerfile 中,我们使用 openjdk 镜像构建容器:
FROM openjdk:8-jre-alpine
使用jdk镜像就不用我们自己安装jdk,操作比较方便。
上述命令足以构建我们的 Docker 镜像,使用如下命令构建 docker-zookeeper 镜像:
wy:Dockerfile wy$ docker build -f Dockerfile-jdk -t smartsi/docker-jdk .
Sending build context to Docker daemon 10.24kB
Step 1/1 : FROM openjdk:8-jre-alpine
8-jre-alpine: Pulling from library/openjdk
e7c96db7181b: Already exists
f910a506b6cb: Already exists
b6abafe80f63: Already exists
Digest: sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193
Status: Downloaded newer image for openjdk:8-jre-alpine
---> f7a292bbb70c
Successfully built f7a292bbb70c
Successfully tagged smartsi/docker-jdk:latest
2. 安装ZooKeeper
现在我们有了基础镜像,我们可以使用 RUN 命令在镜像上安装 Zookeeper。RUN 允许我们在镜像上执行任意命令。在此示例中,我们将 3.5.8 版本的 Zookeeper 安装到 /opt/zookeeper
目录下:
FROM openjdk:8-jre-alpine
# 安装bash
RUN apk add --no-cache wget bash
# 安装zookeeper
RUN wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz
RUN tar -xzf - -C /opt
RUN mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
RUN cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
在 Dockerfile 中执行的每个命令都会创建一个额外的镜像层。每层都复制它前一层的内容,因此每一层都会增加 Docker 镜像的大小。因此,通过组合 Dockerfile 中的语句来最大程度地减少层数被认为是最佳实践。我们需要在可读性和性能之间取得一个平衡,并根据需要调整 Dockerfile。
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
3. 公开端口
Zookeeper 需要打开多个端口才能与其他 Zookeeper 节点和客户端进行通信。我们可以使用 EXPOSE 关键字告诉容器需要侦听的网络端口:
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
EXPOSE 2181 2888 3888
如果要将主机端口映射到容器的端口上,可以使用 -p 命令运行容器。例如,公开容器中的端口并将宿主机端口映射到容器的端口上,我们可以指定要绑定到的多个端口:
docker run -d -p 2181:2181 -p 2888:2888 -p 3888:3888 smartsi/docker-zookeeper:test
4. 设置工作目录
我们将 Zookeeper 安装到 /opt/zookeeper
目录下。由于我们在这个容器上仅运行 Zookeeper,因此将我们的安装目录 /opt/zookeeper
设置为工作目录是最便捷的。这可以通过 WORKDIR 关键字来完成:
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
EXPOSE 2181 2888 3888
WORKDIR /opt/zookeeper
5. 设置配置文件
VOLUME 关键字可以将数据挂载到 Docker 容器上。如果要配置 Zookeeper 实例,我们可以在本地声明我们的配置文件,并让 Docker 使用 VOLUME 命令指定的挂载数据卷读取这些配置文件:
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
EXPOSE 2181 2888 3888
WORKDIR /opt/zookeeper
VOLUME ["/opt/zookeeper/conf"]
如果要将本地目录映射到我们创建的数据卷上,可以使用 docker run 命令的 -v 选项运行容器。在以下示例中,./conf
目录中的所有文件都被映射到容器上的 /opt/zookeeper/conf
目录中:
docker run -it -v conf:/opt/zookeeper/conf smartsi/docker-zookeeper:test /bin/bash
OS X 用户需要使用完整路径而不是相对目录来限定本地目录。
6. 共享数据
Zookeeper 数据默认保存在 /tmp/zookeeper
目录下。我们可以通过 Docker 挂载数据卷将数据保存在宿主机上,从而达到宿主机与容器共享数据:
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
EXPOSE 2181 2888 3888
WORKDIR /opt/zookeeper
VOLUME ["/opt/zookeeper/conf", "/tmp/zookeeper"]
如果我们的 Zookeeper 配置与默认配置不同,请为数据卷使用恰当的挂载点。
7. 运行Zookeeper
此时,我们的 Dockerfile 将会安装 Zookeeper,将端口暴露给宿主机,并为配置和数据文件进行挂载。我们需要的做的最后一件事就是运行 Zookeeper。为此,我们使用 ENTRYPOINT 和 CMD 关键字:
FROM openjdk:8-jre-alpine
RUN apk add --no-cache wget bash
&& wget -q -O - https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz | tar -xzf - -C /opt
&& mv /opt/apache-zookeeper-3.5.8-bin /opt/zookeeper
&& cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
EXPOSE 2181 2888 3888
WORKDIR /opt/zookeeper
VOLUME ["/opt/zookeeper/conf", "/tmp/zookeeper"]
ENTRYPOINT ["/opt/zookeeper/bin/zkServer.sh"]
CMD ["start-foreground"]
ENTRYPOINT 和 CMD 关键字提供了默认可执行文件,默认可执行文件在启动容器时会执行。在此示例中,我们以前台方式启动 Zookeeper 服务器。
8. 构建容器
至此,我们有了一个有效的 Dockerfile,用于构建 Docker 镜像来运行 Zookeeper 实例。要构建 Docker 镜像,需要运行如下命令:
docker build -t smartsi/docker-zookeeper:3.5.8 .
使用默认Dockerfile文件
9. 运行
构建镜像之后运行如下命令启动容器以及 Zookeeper:
docker run -p 2181:2818 -p 2888:2888 -p 3888:3888 --name standalone-zookeeper smartsi/docker-zookeeper:3.5.8
上述命令启动一个名为 standalone-zookeeper
的容器。通过 docker ps
命令查看运行中的 Zookeeper 容器:
通过如下命令进入容器:
docker exec -it standalone-zookeeper /bin/bash
可以通过 zkServer.sh status
命令查看 ZooKeeper 服务状态:
bash-4.4# ./bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: standalone
通过如下命令连接 ZooKeeper 服务:
./bin/zkCli.sh -server localhost:2181
参考:Docker Step By Step: Containerizing Zookeeper
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- tensorflow 大于某个值为1,小于为0的实例
- YII框架模块化处理操作示例
- 基于tensorflow for循环 while循环案例
- 浅谈Python 命令行参数argparse写入图片路径操作
- 硬核干货丨游戏大世界的超远视距处理手法,建议收藏!
- python实现npy格式文件转换为txt文件操作
- 从0开始打造UI框架:动态化框架Scrollview物理学算法解析
- 基于Keras的格式化输出Loss实现方式
- PHP信号处理机制的操作代码讲解
- php防止表单重复提交实例讲解
- Python实现封装打包自己写的代码,被python import
- 创建一个 Serverless 应用,真的没有这么难!
- PHP使用mongoclient简单操作mongodb数据库示例
- 基于TensorFlow的CNN实现Mnist手写数字识别
- django rest framework 自定义返回方式