阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

官方Tomcat镜像Dockerfile分析及镜像使用

167次阅读
没有评论

共计 7554 个字符,预计需要花费 19 分钟才能阅读完成。

这两天学习了 Dockerfile 感觉这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记。

官方 Tomcat 镜像

地址:https://hub.docker.com/_/tomcat/

镜像的 Full Description 中,我们可以得到许多信息,这里简单介绍几个:

1.Supported tags and respective Dockerfile links

支持的标签,以及对应的 Dockerfile 链接。一个 Dockerfile 可以对应多个标签,我们将以 8.5.16-jre8 版本的 Dockerfile 进行分析。

2.How to use this image

如何使用本镜像,包括了以不同方式运行容器的命令,以及一些主要环境变量。这里讲的不够详细,我们会详细讲解。

准备知识:APR、Tomcat Native、Tomcat 的 APR 模式

APR 是 Apache Portable Runtime 的简写,其实就是一组用 C 语言编写的动态链接库,提供统一的 API 接口,用于访问操作系统底层。详见:http://apr.apache.org/。

Tomcat Native 的主要作用是为 tomcat 提供访问本地资源的功能。即利用 APR 库,访问网络、生成随机数等。Tomcat Native 依赖于 APR、OpenSSL、JDK。详见:http://tomcat.apache.org/native-doc/。

在配置好 Tomcat Native 后,可以在 tomcat 配置文件中开启 APR 模式。开启之后,Tomcat 就会直接调用 APR 库访问网络,不用再通过 jvm 中转。

因为 APR 和 Tomcat Native 是和具体的操作系统紧密关联的,并不像 Java 应用那样编译好后就可以跨平台使用。所以 tomcat 默认不安装这些功能,而是根据需要,以及具体操作系统,手工编译源码安装。从一些资料上来看,开启 tomcat 的 APR 模式后,对 tomcat 的性能并不一定会有很大的提升(在某些情况下甚至可能下降)。是否开启 APR 模式要看具体的情况。个人认为,一般情况下,真到了要挖掘 Tomcat 性能的时候,使用 tomcat 集群将会是一种更好的解决方案,这对系统的性能、稳定性、可靠性都有提升。

分析 Dockerfile(tomcat:8.5.16-jre8)

地址:https://github.com/docker-library/tomcat/blob/master/8.5/jre8/Dockerfile

注意,这里以 master 分支的 Dockerfile 链接为例,和 DockerHub 上的 Dockerfile 链接可能会不一致,不过不影响我们接下来的分析。以下就是这个 Dockerfile 的内容,我加了注释加以说明:

# 本镜像的基础镜像。有兴趣的话,可以自行在 DockerHub 上搜索 openjdk,分析官方的 openjdk 镜像的 Dockerfile 文件。这里为什么不用 Oracle 提供的 jdk(jre)?简单地讲,版权问题。
FROM openjdk:8-jre
 
# 声明 CATALINA_HOME 环境变量,这个变量大家都了解。
ENV CATALINA_HOME /usr/local/tomcat
# 将 Tomcat 下的 bin 路径加入到 PATH 环境变量中。
ENV PATH $CATALINA_HOME/bin:$PATH
# 创建 tomcat 路径。
RUN mkdir -p “$CATALINA_HOME”
# 指定 RUN、CMD、ENTRYPOINT 命令的当前工作路径。
WORKDIR $CATALINA_HOME
 
#Tomcat Native 路径配置。
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
# 将 TOMCAT_NATIVE_LIBDIR 加入到 LD_LIBRARY_PATH 环境变量中,这样 Tomcat 在查找 Tomcat Native 相关的动态链接库时,会去查找 TOMCAT_NATIVE_LIBDIR 环境变量指定的路径。
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR
 
# 检查、更新 OpenSSL,这块的细节我没深究。
ENV OPENSSL_VERSION 1.1.0f-3
RUN {\
  echo ‘deb http://deb.debian.org/debian stretch main’; \
 } > /etc/apt/sources.list.d/stretch.list \
 && {\
  echo ‘Package: *’; \
  echo ‘Pin: release n=stretch’; \
  echo ‘Pin-Priority: -10’; \
  echo; \
  echo ‘Package: openssl libssl*’; \
  echo “Pin: version $OPENSSL_VERSION”; \
  echo ‘Pin-Priority: 990’; \
 } > /etc/apt/preferences.d/stretch-openssl
RUN apt-get update && apt-get install -y –no-install-recommends \
  libapr1 \
  openssl=”$OPENSSL_VERSION” \
 && rm -rf /var/lib/apt/lists/*
 
# 从 key 服务器导入 key,用于验证 tomcat 压缩文件的签名,这块也没深究。
ENV GPG_KEYS 05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23
RUN set -ex; \
 for key in $GPG_KEYS; do \
  gpg –keyserver ha.pool.sks-keyservers.net –recv-keys “$key”; \
 done
 
#Tomcat 相关文件的版本。
ENV TOMCAT_MAJOR 8
ENV TOMCAT_VERSION 8.5.16
 
#Tomcat 相关文件下载地址。
ENV TOMCAT_TGZ_URL https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz
ENV TOMCAT_ASC_URL https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc
 
# 执行命令
RUN set -x \
 \
 #下载 Tomcat 压缩文件
 && wget -O tomcat.tar.gz “$TOMCAT_TGZ_URL” \
 && wget -O tomcat.tar.gz.asc “$TOMCAT_ASC_URL” \
 #进行签名验证
 && gpg –batch –verify tomcat.tar.gz.asc tomcat.tar.gz \
 #解压 Tomcat
 && tar -xvf tomcat.tar.gz –strip-components=1 \
 # 删除供 Windows 系统使用的.bat 文件
 && rm bin/*.bat \
 # 删除压缩文件
 && rm tomcat.tar.gz* \
 \
 #安装 Tomcat Native
 && nativeBuildDir=”$(mktemp -d)” \
 && tar -xvf bin/tomcat-native.tar.gz -C “$nativeBuildDir” –strip-components=1 \
 && nativeBuildDeps=” \
  dpkg-dev \
  gcc \
  libapr1-dev \
  libssl-dev \
  make \
  openjdk-${JAVA_VERSION%%[-~bu]*}-jdk=$JAVA_DEBIAN_VERSION \
 ” \
 && apt-get update && apt-get install -y –no-install-recommends $nativeBuildDeps && rm -rf /var/lib/apt/lists/* \
 && (\
  export CATALINA_HOME=”$PWD” \
  && cd “$nativeBuildDir/native” \
  && gnuArch=”$(dpkg-architecture –query DEB_BUILD_GNU_TYPE)” \
  && ./configure \
  –build=”$gnuArch” \
  –libdir=”$TOMCAT_NATIVE_LIBDIR” \
  –prefix=”$CATALINA_HOME” \
  –with-apr=”$(which apr-1-config)” \
  –with-java-home=”$(docker-java-home)” \
  –with-ssl=yes \
  && make -j “$(nproc)” \
  && make install \
 ) \
 && apt-get purge -y –auto-remove $nativeBuildDeps \
 && rm -rf “$nativeBuildDir” \
 && rm bin/tomcat-native.tar.gz
 
# 验证 Tomcat Native 是否安装成功
RUN set -e \
 && nativeLines=”$(catalina.sh configtest 2>&1)” \
 && nativeLines=”$(echo “$nativeLines” | grep ‘Apache Tomcat Native’)” \
 && nativeLines=”$(echo “$nativeLines” | sort -u)” \
 && if ! echo “$nativeLines” | grep ‘INFO: Loaded APR based Apache Tomcat Native library’ >&2; then \
  echo >&2 “$nativeLines”; \
  exit 1; \
 fi
 
# 暴露 8080 端口
EXPOSE 8080
# 容器启动时执行的命令。
CMD [“catalina.sh”, “run”]

——————————————————-

此 Dockerfile 的主要功能可归纳为:

1. 以 openjdk 镜像为基础镜像进行构建。

2. 安装 Tomcat Native,及其依赖库(比如 APR、OpenSSL 等)。验证是否正确安装。

3. 下载 Tomcat,检查签名,解压、清除无用文件等。

4. 暴露 8080 端口,配置入口命令。

总的来说,此 Dockerfile 的功能还是比较清晰的,如果要自己构建自己的 Tomcat 镜像,可以参考本 Dockerfile。另外,Tomcat 的 Dockerfile 应该是自动生成而非手工编写,因为第一,Tomcat 的有很多版本的 Dockerfile,手工维护工作量大;第二,存在一些我认为不是很很合理的地方(比如从 key server 上获取很多 key)。所以大家在分析一些官方 Dockerfile 时,如果遇到一些感觉不是很合理的地方也别太纠结。

如何使用官方镜像

$ docker run -d –name tomcat-test -p 8888:8080 tomcat:8.5.16-jre8

以上指令将使用本镜像启动一个容器,你可以通过 http:// 本机 ip:8888 访问到容器中的 Tomcat。这种方式并没有部署应用,所以其实也没什么实际意义。

$ docker run -d –name tomcat-test -p 8888:8080 \
-v /home/myWebApp:/usr/local/tomcat/webapps/ROOT \
-v /home/myWebAppLogs:/usr/local/tomcat/logs \
tomcat:8.5.16-jre8

以上指令增加了两个 volume,将 /home/myWebApp 挂载到容器中的 /usr/local/tomcat/webapps/ROOT,将 /home/myWebAppLogs 挂载到容器中的 /usr/local/tomcat/logs 路径。容器启动后,tomcat 的根应用将会是 myWebApp(通过 http:// 本机 ip:8888 访问),并且 tomcat 的日志将会输出到 /home/myWebAppLogs 路径下。
 此后,如果容器被删除,应用和应用的日志也不会随容器一起删除。更新应用时,只需要更新 /home/myWebApp 路径,再重启容器即可。

如果不想把应用挂载到根目录下,可以更改 volume 配置,比如:-v /home/myWebApp:/usr/local/tomcat/webapps/myWebApp,再通过 http:// 本机 ip:8888/myWebApp 访问。

注意:如果想把 myWebApp 内部的日志也输出到 /home/myWebAppLogs 路径下,请配置 myWebApp 的日志文件的输出路径为 Tomcat 日志路径(相对路径),���如:logs/myLog.log。这样,myWebApp 的日志文件将会输出至 /usr/local/tomcat/logs 下(因为挂载了 volume,其实是输出到 /home/myWebAppLogs 路径下)。

从规范的角度讲,其实这种应用部署方式并不值得推荐,因为部署还是出现了环境相关性。也就是说,必须先把应用目录、日志目录指定好,才能进行部署。而且如果要一台机上要部署两个相同的应用进行负载均衡也比较麻烦(要建两套应用和日志目录,并且修改容器启动命令),难以实现自动化部署。但话又说回来,我相信这种部署方式还是会受到大部分人欢迎的。目前我们公司在测试环境中也普遍使用这种模式,以便一台测试服务器部署多个应用(Tomcat),彼此之间完全没有关联和影响。

如果要做到完全环境无关性部署,可以考虑自己在官方 Tomcat 镜像的基础上,构建出一个新的镜像。在这个新镜像的 Dockerfile 中直接下载并部署 myWebApp,并使用某些工具或框架,将 Tomcat 和 myWebApp 产生的日志,上传汇总到一个统一的日志服务中。这样,如果要再部署一个相同的应用,只要给我一台装有 Docker 环境的机器,我执行一条指令即可(同一 Docker 环境下注意端口冲突)。这种方式有利于自动化部署,在服务器数量较多的情况下比较合适。当然,这种方式也有比较麻烦的地方,就是每发布以一个应用版本,都要重新构建一个新的镜像。

关于自动化部署,还可以参考 Docker Compose 和 Kubernetes,这里不做深入(主要是本人对这块的了解和应用也不够多)。

官方镜像的不足

在本镜像的实际使用过程中,还是遇到了一些问题:

1. 为了照顾到全球的镜像使用者,官方的 openjdk 镜像和 Tomcat 镜像都没对时区进行定制化配置,默认为 UTC 时间(比北京时间早八小时)。如果应用内部也没有进行时区配置,那么应用获取到的系统时间也将会是 UTC 时间。

2. 在某些机器(或虚拟机)上,jdk 的随机数生成器初始化用时过长,导致 Tomcat 启动用时过长。我用过的阿里云 ECS 就是这种情况。

这些问题将会在之后我们自己构建的 Tomcat 镜像中解决。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 16.04 服务器上配置使用 Docker  http://www.linuxidc.com/Linux/2017-06/145176.htm

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm

Docker 安装实例 http://www.linuxidc.com/Linux/2017-04/142666.htm

Docker 创建基础镜像  http://www.linuxidc.com/Linux/2017-05/144112.htm

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm

使用 Docker 分分钟启动常用应用  http://www.linuxidc.com/Linux/2017-04/142649.htm

Ubuntu 16.04 下 Docker 修改配置文件不生效解决办法  http://www.linuxidc.com/Linux/2017-05/143862.htm 

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-07/145910.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计7554字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中