系統中經常出現各種依賴的組件滴某,比如mysql午乓、hive站宗、kafka等等,docker能夠快速地將一個環(huán)境部署到其他機器上益愈,節(jié)省了大量的安裝環(huán)境的時間梢灭。只需要寫一個“recipe”,docker就能如法炮制蒸其,復制一模一樣的環(huán)境到你的機器上敏释,讓程序員更加專注于開發(fā)。
下面開始手把手建立一個presto的docker image摸袁。Presto是Facebook開源的一個SQL查詢引擎, 不清楚presto是什么的可以查看https://prestodb.io
Dockerfile制作
1. 基礎環(huán)境準備
FROM registry.docker-cn.com/library/java:8
MAINTAINER Jack "Jack@aaa.com"
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從頭到尾建立一個項目都需要準備什么東西,最后怎么跑起來等靠汁。最開始我們要確定一個項目是基于什么環(huán)境的蜂大,比如presto依賴java開發(fā)環(huán)境闽铐,所以我們用 From registry.docker-cn.com/library/java:latest
, 這樣就不需要去搭建java環(huán)境了,比如有些開源組件是python寫的奶浦,那么這個FROM
就應該去docker registry搜索python相關的image兄墅。利用好FROM
可以讓我們的docker制作過程快速很多,比如我可以先制作一個python flask web開發(fā)的環(huán)境澳叉,如果有其他的docker image也依賴這個基礎環(huán)境, 就可以直接拿過來用了, 而且構建的速度快很多~
- MAINTAINER 設置docker鏡像的作者信息. 已經deprecated, 官方建議使用LABEL
- LABEL 是給這個docker image打上標簽隙咸,標簽的作用方面統一管理docker images, 可以打多個標簽
- RUN RUN會執(zhí)行任何shell命令, 并commit結果, 隨后的命令就能夠獲取到該執(zhí)行結果.
- 鏡像加速: 國內的網速你懂的, 需要修改軟件源為國內鏡像加速, 把加速鏈接添加到
/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 可以讓容器啟動之后執(zhí)行指令. 如果在啟動的時候想要執(zhí)行多條執(zhí)行, 可以把代碼寫到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鏡像就制作好了, 如果遇到問題可以向我提問~