手把手教你制作一个Presto的docker镜像

系统中经常出现各种依赖的组件,比如mysql、hive、kafka等等,docker能够快速地将一个环境部署到其他机器上,节省了大量的安装环境的时间。只需要写一个“recipe”,docker就能如法炮制,复制一模一样的环境到你的机器上,让程序员更加专注于开发。
下面开始手把手建立一个presto的docker image。Presto是Facebook开源的一个SQL查询引擎, 不清楚presto是什么的可以查看https://prestodb.io

Dockerfile制作

1. 基础环境准备

FROM registry.docker-cn.com/library/java:8
MAINTAINER Jack "[email protected]"

LABEL os="debian"
LABEL app="presto"
LABEL version="0.180"

RUN echo 'deb http://mirrors.aliyun.com/debian/ jessie main non-free contrib\n\
deb http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\n\
deb-src http://mirrors.aliyun.com/debian/ jessie main non-free contrib\n\
deb-src http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\n'\  >/etc/apt/sources.list

RUN java -version

Dockerfile就像一个列表清单,告诉docker从头到尾建立一个项目都需要准备什么东西,最后怎么跑起来等。最开始我们要确定一个项目是基于什么环境的,比如presto依赖java开发环境,所以我们用 From registry.docker-cn.com/library/java:latest , 这样就不需要去搭建java环境了,比如有些开源组件是python写的,那么这个FROM就应该去docker registry搜索python相关的image。利用好FROM 可以让我们的docker制作过程快速很多,比如我可以先制作一个python flask web开发的环境,如果有其他的docker image也依赖这个基础环境, 就可以直接拿过来用了, 而且构建的速度快很多~

  • MAINTAINER 设置docker镜像的作者信息. 已经deprecated, 官方建议使用LABEL
  • LABEL 是给这个docker image打上标签,标签的作用方面统一管理docker images, 可以打多个标签
  • RUN RUN会执行任何shell命令, 并commit结果, 随后的命令就能够获取到该执行结果.
  • 镜像加速: 国内的网速你懂的, 需要修改软件源为国内镜像加速, 把加速链接添加到/etc/apt/sources.list文件. 参考国内镜像加速

2. 安装依赖

上一步做了一些基础的准备, 下面开始安装presto的依赖项.


# install python
RUN apt-get update
RUN apt-get install -y python2.7
RUN mv /usr/bin/python2.7 /usr/bin/python
RUN python --version

# install mysql no password prompt
RUN apt-get install -y debconf-utils
# set password same as that in presto catalog below
RUN echo 'mysql-server mysql-server/root_password password 123456' | debconf-set-selections
RUN echo 'mysql-server mysql-server/root_password_again password 123456' | debconf-set-selections
RUN apt-get update && apt-get -y install mysql-server
RUN mysql --version
RUN apt-get install -y mysql-client

# change user root to mysql in order to start mysql properly
RUN touch /var/run/mysqld/mysqld.sock
RUN chown -R mysql:mysql /var/run/mysqld
RUN chown -R mysql:mysql /var/lib/mysql


ENV PRESTO_VERSION 0.180
ENV PRESTO_DIR /opt/presto
ENV PRESTO_ETC_DIR /opt/presto/etc
ENV PRESTO_DATA_DIR /data


RUN mkdir -p ${PRESTO_DIR} ${PRESTO_ETC_DIR}/catalog \
 && curl -s https://repo1.maven.org/maven2/com/facebook/presto/presto-server/${PRESTO_VERSION}/presto-server-${PRESTO_VERSION}.tar.gz \
 | tar --strip 1 -vxzC ${PRESTO_DIR}

WORKDIR ${PRESTO_DIR}
RUN pwd

# config node.properties
RUN echo "node.environment=ci\n\
node.id=faaaafffffff-ffff-ffff-ffff-ffffffffffff\n\
node.data-dir=${PRESTO_DATA_DIR}\n"\ > ${PRESTO_ETC_DIR}/node.properties

# config jvm.config
RUN echo '-server\n\
-Xmx1G\n\
-XX:+UseG1GC\n\
-XX:G1HeapRegionSize=32M\n\
-XX:+UseGCOverheadLimit\n\
-XX:+ExplicitGCInvokesConcurrent\n\
-XX:+HeapDumpOnOutOfMemoryError\n\
-XX:+ExitOnOutOfMemoryError\n'\ > ${PRESTO_ETC_DIR}/jvm.config

# config log.properties
RUN echo 'coordinator=true\n\
node-scheduler.include-coordinator=true\n\
http-server.http.port=8888\n\
query.max-memory=0.4GB\n\
query.max-memory-per-node=0.2GB\n\
discovery-server.enabled=true\n\
discovery.uri=http://127.0.0.1:8888\n'\ > ${PRESTO_ETC_DIR}/config.properties

# config log.properties
RUN echo 'com.facebook.presto=WARN\n'\ > ${PRESTO_ETC_DIR}/log.properties

# Set the following mysql catalog values: password same as mysql-server installation above
# bind the port to 3307 to avoid port has been used invalid in local env 
RUN echo 'connector.name=mysql\n\
connection-url=jdbc:mysql://127.0.0.1:3307\n\
connection-user=root\n\
connection-password=123456\n'\ > ${PRESTO_ETC_DIR}/catalog/mysql.properties

RUN echo "change mysql port from 3306 to 3307 ..."
RUN sed -i 's/^\(port\s*=\s*\).*$/\13307/' /etc/mysql/my.cnf

COPY ./presto_docker_entrypoint.sh /presto_docker_entrypoint.sh
COPY ./test_presto_catalog_init.sql /test_presto_catalog_init.sql
ENTRYPOINT ["bash", "/presto_docker_entrypoint.sh"]

Presto要求java8版本, 另外也需要python依赖, 修改ENV PRESTO_VERSION 0.180可以安装你指定的官方版本. 按照Presto官方的deployment方法 将config文件在dockerfile中配置好, 我将presto的coordinator设置为master和worker共用, 另外在presto内部配一个mysql, 让presto的catalog能够访问到mysql的一些初始化的数据, 方便用于测试等. 在docker里安装mysql还是比较tricky的.

  • ENTRYPOINT 可以让容器启动之后执行指令. 如果在启动的时候想要执行多条执行, 可以把代码写到shell脚本中. 因为dockerfile只支持一个ENTRYPOINT 或 CMD.

完整的项目代码我放到了github: https://github.com/yamyamyuo/docker/tree/master/presto-docker

3. docker build

有了前期的准备工作, 就可以进入该Dockerfile目录, build镜像.

docker build -t presto:v0.180 -f Dockerfile .

build完成后通过下面命令可以看到我们构件好的docker image

docker/presto-docker(master) » docker images                                        
REPOSITORY    TAG     IMAGE ID    CREATED          SIZE
presto       v0.180   ea18f17c0494  24 seconds ago      1.16GB

4. docker run

把制作好的镜像跑起来看看, 可以通过-p 8888:8888将端口号进行映射, -v /tmp:/data 是将docker镜像内产生的数据和目录挂载到localhost. 也就是说镜像内/data这个路径下的所有文件都可以在本地的/tmp文件夹下找到.

docker run -it -p 8888:8888 -v /tmp:/data presto:v0.180

尾声

到此一个docker镜像就制作好了, 如果遇到问题可以向我提问~

你可能感兴趣的:(手把手教你制作一个Presto的docker镜像)