系統(tǒng)中經(jīng)常出現(xiàn)各種依賴的組件,比如mysql、hive、kafka等等,docker能夠快速地將一個(gè)環(huán)境部署到其他機(jī)器上,節(jié)省了大量的安裝環(huán)境的時(shí)間。只需要寫一個(gè)“recipe”,docker就能如法炮制,復(fù)制一模一樣的環(huán)境到你的機(jī)器上,讓程序員更加專注于開發(fā)。
下面開始手把手建立一個(gè)presto的docker image。Presto是Facebook開源的一個(gè)SQL查詢引擎, 不清楚presto是什么的可以查看https://prestodb.io
Dockerfile制作
1. 基礎(chǔ)環(huán)境準(zhǔ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就像一個(gè)列表清單,告訴docker從頭到尾建立一個(gè)項(xiàng)目都需要準(zhǔn)備什么東西,最后怎么跑起來等。最開始我們要確定一個(gè)項(xiàng)目是基于什么環(huán)境的,比如presto依賴java開發(fā)環(huán)境,所以我們用 From registry.docker-cn.com/library/java:latest
, 這樣就不需要去搭建java環(huán)境了,比如有些開源組件是python寫的,那么這個(gè)FROM
就應(yīng)該去docker registry搜索python相關(guān)的image。利用好FROM
可以讓我們的docker制作過程快速很多,比如我可以先制作一個(gè)python flask web開發(fā)的環(huán)境,如果有其他的docker image也依賴這個(gè)基礎(chǔ)環(huán)境, 就可以直接拿過來用了, 而且構(gòu)建的速度快很多~
- MAINTAINER 設(shè)置docker鏡像的作者信息. 已經(jīng)deprecated, 官方建議使用LABEL
- LABEL 是給這個(gè)docker image打上標(biāo)簽,標(biāo)簽的作用方面統(tǒng)一管理docker images, 可以打多個(gè)標(biāo)簽
- RUN RUN會(huì)執(zhí)行任何shell命令, 并commit結(jié)果, 隨后的命令就能夠獲取到該執(zhí)行結(jié)果.
- 鏡像加速: 國內(nèi)的網(wǎng)速你懂的, 需要修改軟件源為國內(nèi)鏡像加速, 把加速鏈接添加到
/etc/apt/sources.list
文件. 參考國內(nèi)鏡像加速
2. 安裝依賴
上一步做了一些基礎(chǔ)的準(zhǔn)備, 下面開始安裝presto的依賴項(xiàng).
# 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設(shè)置為master和worker共用, 另外在presto內(nèi)部配一個(gè)mysql, 讓presto的catalog能夠訪問到mysql的一些初始化的數(shù)據(jù), 方便用于測試等. 在docker里安裝mysql還是比較tricky的.
- ENTRYPOINT 可以讓容器啟動(dòng)之后執(zhí)行指令. 如果在啟動(dòng)的時(shí)候想要執(zhí)行多條執(zhí)行, 可以把代碼寫到shell腳本中. 因?yàn)閐ockerfile只支持一個(gè)ENTRYPOINT 或 CMD.
完整的項(xiàng)目代碼我放到了github: https://github.com/yamyamyuo/docker/tree/master/presto-docker
3. docker build
有了前期的準(zhǔn)備工作, 就可以進(jìn)入該Dockerfile
目錄, build鏡像.
docker build -t presto:v0.180 -f Dockerfile .
build完成后通過下面命令可以看到我們構(gòu)件好的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
將端口號(hào)進(jìn)行映射, -v /tmp:/data
是將docker鏡像內(nèi)產(chǎn)生的數(shù)據(jù)和目錄掛載到localhost. 也就是說鏡像內(nèi)/data
這個(gè)路徑下的所有文件都可以在本地的/tmp
文件夾下找到.
docker run -it -p 8888:8888 -v /tmp:/data presto:v0.180
尾聲
到此一個(gè)docker鏡像就制作好了, 如果遇到問題可以向我提問~