在之前HDFS分布式构建里, 完整的写了如何手动编译运行HDFS3的环境, 但是可以发现整个依赖和编译耗时还是比较繁杂的, 并且不同的系统环境问题也各不一样, 难以复用.
今天说一下用通用的容器(Dockerfile)方式如何构建HDFS3 (并且可以很好地融入CI/CD的流程里, 自动化编译-分发-测试部署)
0x00. 准备
在机器上准备好Docker环境, 包括替换默认.源(此略), 下载官方仓库提供的HDFS3.1.2对应的Dockerfile文件, 参考官方building使用说明, 我们先把前置准备做好
1 2 3 4 5 6 7 8 9 10 11 12
| git clone -b release-3.1.2-RC0 https://github.com/apache/hadoop.git
cd hadoop-3.1.2/dev-support/docker
docker build -t hdfs3:0.1 .
|
特别注意:
- 不同版本对应的依赖和Dockerfile有所不同, 比如官方最新版已经采用了
protobuf3.7
而不是之前祖传的protobuf2.5
, 所以不能混用
- 官方也提供自动构建运行的start-env脚本, 包括挂载目录等, 但是如果你需要定制化建议还是自己修改
0x01. 分析
因为HDFS3.1.2
的Dockerfile有点过时, 安装软件包后未及时清理, 比较臃肿, 参考最新的官方文件, 我更新了一些优化点, 所以建议替换默认的文件.
首先我们先来读懂官方的Dockerfile在做什么, 再说如何修改, 然后加入对EC功能的支持库isal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| FROM ubuntu:xenial
WORKDIR /root
RUN echo APT::Install-Recommends "0"\; > /etc/apt/apt.conf.d/10disableextras RUN echo APT::Install-Suggests "0"\; >> /etc/apt/apt.conf.d/10disableextras ENV DEBIAN_FRONTEND noninteractive ENV DEBCONF_TERSE true
RUN set -x \ && apt-get -q update \ && apt-get -q install -y --no-install-recommends \ apt-utils \ build-essential \ bzip2 \ curl \ doxygen \ fuse \ g++ \ gcc \ git \ gnupg-agent \ libbz2-dev \ libcurl4-openssl-dev \ libfuse-dev \ libprotobuf-dev \ libprotoc-dev \ libsnappy-dev \ libssl-dev \ libtool \ libzstd1-dev \ locales \ make \ pinentry-curses \ pkg-config \ python \ python2.7 \ python-pip \ python-pkg-resources \ python-setuptools \ python-wheel \ rsync \ software-properties-common \ snappy \ sudo \ zlib1g-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
RUN apt-get -q update \ && apt-get -q install -y --no-install-recommends openjdk-8-jdk libbcprov-java \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /opt/cmake && \ curl -L -s -S \ https://cmake.org/files/v3.1/cmake-3.1.0-Linux-x86_64.tar.gz \ -o /opt/cmake.tar.gz && \ tar xzf /opt/cmake.tar.gz --strip-components 1 -C /opt/cmake ENV CMAKE_HOME /opt/cmake ENV PATH "${PATH}:/opt/cmake/bin"
RUN mkdir -p /opt/protobuf-src && \ curl -L -s -S https://github.com/google/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz \ -o /opt/protobuf.tar.gz && \ tar xzf /opt/protobuf.tar.gz --strip-components 1 -C /opt/protobuf-src RUN cd /opt/protobuf-src && ./configure --prefix=/opt/protobuf && make install ENV PROTOBUF_HOME /opt/protobuf ENV PATH "${PATH}:/opt/protobuf/bin"
RUN apt-get -q update \ && apt-get -q install -y --no-install-recommends maven \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ENV MAVEN_HOME /usr
RUN apt-get -q update \ && apt-get -q install -y --no-install-recommends findbugs ant \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ENV FINDBUGS_HOME /usr
RUN add-apt-repository -y ppa:jonathonf/ghc-8.0.2 \ && apt-get -q update \ && apt-get -q install -y --no-install-recommends shellcheck \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
RUN apt-get -q update \ && apt-get -q install -y --no-install-recommends bats \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
RUN pip2 install pylint==1.9.2
RUN pip2 install python-dateutil
RUN apt-get -q update \ && apt-get install -y --no-install-recommends nodejs npm \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && ln -s /usr/bin/nodejs /usr/bin/node \ && npm install npm@latest -g \ && npm install -g jshint
ENV MAVEN_OPTS -Xms256m -Xmx1536m
RUN apt-get -q update \ && apt-get -q install -y --no-install-recommends nasm \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN mkdir -p /opt/isal \ && curl -L -s -S https://github.com/intel/isa-l/archive/v2.28.0.tar.gz -o /opt/isal.tar.gz \ && tar xzf /opt/isal.tar.gz --strip-components 1 -C /opt/isal \ && cd /opt/isal \ && make -f Makefile.unx \ && cp bin/libisal.so* /usr/lib/x86_64-linux-gnu/
ADD hadoop_env_checks.sh /root/hadoop_env_checks.sh RUN chmod 755 /root/hadoop_env_checks.sh \ && echo '~/hadoop_env_checks.sh' >> /root/.bashrc
|
0x02. CentOS版镜像
因为native
库在ubuntu
上打包存在不兼容Cent7/6的相关原因, 实际生产环境如果是用的Cent
,还是得单独用Cent的基础镜像, 并且以最低版本为基准, 因为高版一般可以向下兼容. 低版很可能不兼容高版 (Cent7的包Cent6就不能用)
那如果完全看懂了所有的编译步骤, 也具有一定的动手能力, 就应该尝试自己写出一个Cent6/7兼容的Docker镜像, 下面是我的个人写法: (适用于HDFS3.1.2, github下载地址)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| FROM centos:6
WORKDIR /root
RUN set -x \ && yum -q update -y \ && yum install -y centos-release-scl scl-utils epel-release \ && yum install -y \ devtoolset-7-gcc \ devtoolset-7-gcc-c++ \ python27 \ python-pip \ git \ doxygen \ rsync \ bats \ ncurses-devel \ nasm \ m4 \ sudo \ java-1.8.0-openjdk-devel \ bzip2-devel \ fuse-devel \ openssl-devel \ snappy-devel \ zlib-devel \ libzstd-devel \ && yum clean all \ && rm -rf /var/cache/yum ENV JAVA_HOME "/usr/lib/jvm/java-1.8.0-openjdk.x86_64" ENV PATH "${PATH}:/opt/rh/devtoolset-7/root/usr/bin"
RUN echo "source /opt/rh/devtoolset-7/enable" >> /etc/bashrc && \ source /etc/bashrc && \ mkdir -p /opt/cmake && \ curl -SL https://github.com/Kitware/CMake/releases/download/v3.10.0/cmake-3.10.0-Linux-x86_64.tar.gz \ -o /opt/cmake.tar.gz && \ tar xzf /opt/cmake.tar.gz --strip-components 1 -C /opt/cmake && \ rm -f /opt/cmake.tar.gz ENV CMAKE_HOME /opt/cmake ENV PATH "${PATH}:/opt/cmake/bin"
RUN mkdir -p /opt/autoconf && \ curl -SL http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz \ -o /opt/autoconf.tar.gz && \ tar xzf /opt/autoconf.tar.gz --strip-components 1 -C /opt/autoconf && \ cd /opt/autoconf && \ ./configure && \ make && make install && \ cp ./bin/autoconf /usr/bin && \ rm -f /opt/autoconf.tar.gz
RUN mkdir -p /opt/protobuf-src && \ curl -SL https://github.com/google/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz \ -o /opt/protobuf.tar.gz && \ tar xzf /opt/protobuf.tar.gz --strip-components 1 -C /opt/protobuf-src && \ cd /opt/protobuf-src && ./configure --prefix=/opt/protobuf && \ make install && rm -f /opt/protobuf.tar.gz ENV PROTOBUF_HOME /opt/protobuf ENV PATH "${PATH}:/opt/protobuf/bin"
RUN mkdir -p /opt/maven && \ curl -SL https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz \ -o /opt/maven.tar.gz && \ tar xzf /opt/maven.tar.gz --strip-components 1 -C /opt/maven && \ rm -f /opt/maven.tar.gz ENV MAVEN_HOME /opt/maven ENV PATH "${PATH}:/opt/maven/bin"
RUN pip2 install pylint==1.9.2
RUN pip2 install python-dateutil
RUN mkdir -p /opt/nasm /opt/isal \ && curl -SL https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz -o /opt/nasm.tar.gz \ && tar xzf /opt/nasm.tar.gz --strip-components 1 -C /opt/nasm \ && cd /opt/nasm && ./autogen.sh && ./configure && make && make install \ && cp ./nasm /usr/bin \ && rm -f /opt/nasm.tar.gz
RUN curl -SL https://github.com/intel/isa-l/archive/v2.28.0.tar.gz -o /opt/isal.tar.gz \ && tar xzf /opt/isal.tar.gz --strip-components 1 -C /opt/isal \ && cd /opt/isal && make -f Makefile.unx \ && mv bin/*isa* /usr/lib64/ \ && rm -rf /opt/*tar.gz
ENV MAVEN_OPTS -Xms256m -Xmx1536m
ADD hadoop_env_checks.sh /root/hadoop_env_checks.sh RUN chmod 755 /root/hadoop_env_checks.sh \ && echo '~/hadoop_env_checks.sh' >> /root/.bashrc
|
0x03. 运行编译
构建完成后, 尝试进入容器编译测试, 注意如果没有私有mvn仓库, 务必先修改默认的仓库地址(比如换成阿里云mvn).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
USER_NAME=$(whoami)
docker run -it \ -v "/home/${USER_NAME}/hadoop-3.1.2:/root/hadoop-3.1.2" \ -w "/root/hadoop-3.1.2" \ -v "/home/${USER_NAME}/.m2:/root/.m2" --name hdfs0.1 hdfs:v0.1
docker inspect containerId
mvn install -e -Pdist,native -Dtar -DskipTests -Dmaven.javadoc.skip=true
./hadoop-dist/target/hadoop-3.1.2/bin/hadoop checknative
mvn clean install -e -Pdist,native -Dtar -DskipTests -Dmaven.javadoc.skip=true \ -Drequire.snappy -Drequire.zstd -Drequire.openssl -Drequire.isal \ -Dbundle.snappy -Dsnappy.lib=/usr/lib/x86_64-linux-gnu/ \ -Dbundle.zstd -Dzstd.lib=/usr/lib/x86_64-linux-gnu/ \ -Dbundle.openssl -Dopenssl.lib=/usr/lib/x86_64-linux-gnu/ \ -Dbundle.isal -Disal.lib=/usr/lib/x86_64-linux-gnu/
mvn clean install -e -Pdist,native -Dtar -DskipTests -Dmaven.javadoc.skip=true \ -Drequire.snappy -Drequire.zstd -Drequire.openssl -Drequire.isal \ -Dbundle.snappy -Dsnappy.lib=/usr/lib64/ \ -Dbundle.zstd -Dzstd.lib=/usr/lib64/ \ -Dbundle.openssl -Dopenssl.lib=/usr/lib64/ \ -Dbundle.isal -Disal.lib=/usr/lib64/
./hadoop-dist/target/hadoop-3.1.2/bin/hadoop checknative
|
然后以后带着这份Dockerfile, 就可以在任意的环境上愉快的编译完整的Hadoop的运行环境了, 而且可以确保打出来的包非常可靠.
注意: 如果要用此镜像编译更高版本HDFS, 请注意很可能需取消native
编译, 否则C相关依赖会报错. (比如新引入的PMDK
库)
0x04. 其他
- 同样需要注意的是, 强烈建议在
pom.xml
中添加私有mvn仓库, 或至少添加阿里云等国内仓库, 否则构建速度会非常慢 (必须)
- 如果不修改
pom.xml
, 则需要在构建镜像的时候最后添加一步用你自己添加过mvn仓库的setting
文件替换mvn默认配置
- 将Docker镜像与Jenkins/K8s结合不是本文重心, 就暂时略过.
参考资料:
- hadoop-github
- dockerhub-hadoop-docker-cent6.5