2

docker学习笔记4-Dockfile实践

 1 year ago
source link: http://saiya.xyz/2020/12/17/docker4/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

构建自定义tomcat镜像的dockfile实践

Dockerfile内容入下:

# 继承镜像
FROM centos:7
# 作者信息
MAINTAINER elvis "[email protected]"
# 指定工作目录
# WORKDIR /home/elvis/dockers
# 把java和tomcat添加到容器中
ADD jdk-8u271-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-7.0.107.tar.gz /usr/local/

# 拷贝自定义的server.xml文件到容器中
COPY server.xml /usr/local/apache-tomcat-7.0.107/conf

# 配置java和tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_271
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.107
ENV CATALINA_BASE /usr/local/apache-tomcat-7.0.107
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

COPY myproject.war /usr/local/apache-tomcat-7.0.107/webapps
#因为已经配置好了环境变量,此处可以直接执行tomcat的startup.sh脚本
CMD ["catalina.sh", "run"]

EXPOSE 8086

解释如下:

FROM:继承镜像centos7

ADD:将jdk和tomcat压缩包add进去

COPY:将tomcat定义端口等设置的server.xml拷贝到容器的相应目录

ENV:配置java和tomcat的环境变量

COPY:myproject.war文件拷贝到tomcat的webapps目录下

ENTRYPOINT:由于构建并启动容器后,容器中的tomcat并没有启动。所以增加启动tomcat命令。此处注意RUN、CMD、ENTRYPOINT三者区别。

构建镜像命令:

docker build -t yzb/tomcat:1.5 .

创建并运行容器

docker run -itd --name my_tomcat_yzb -p 8086:8086 yzb/tomcat:1.4

docker中端口有两个概念,EXPOSE和PUBLISH

EXPOSE 是镜像/容器声明要暴露该端口,可以供其他容器使用。这种声明,在没有设定 –icc=false的时候,实际上只是一种标注,并不强制。也就是说,没有声明 EXPOSE 的端口,其它容器也可以访问。但是当强制 –icc=false 的时候,那么只有 EXPOSE 的端口,其它容器才可以访问。
PUBLISH 则是通过映射宿主端口,将容器的端口公开于外界,也就是说宿主之外的机器,可以通过访问宿主IP及对应的该映射端口,访问到容器对应端口,从而使用容器服务。
EXPOSE 的端口可以不 PUBLISH,这样只有容器间可以访问,宿主之外无法访问。而 PUBLISH 的端口,可以不事先 EXPOSE,换句话说 PUBLISH 等于同时隐式定义了该端口要 EXPOSE。

docker run 命令中的 -p, -P 参数,以及 docker-compose.yml 中的 ports 部分,实际上均是指 PUBLISH。

小写 -p 是端口映射,格式为 [宿主IP:]:,其中宿主端口和容器端口,既可以是一个数字,也可以是一个范围,比如:1000-2000:1000-2000。对于多宿主的机器,可以指定宿主IP,不指定宿主IP时,守护所有接口。

大写 -P 则是自动映射,将所有定义 EXPOSE 的端口,随机映射到宿主的某个端口。

我要映射好几百个端口,难道要一个个 -p 么?
-p 是可以用范围的:

-p 8001-8010:8001-8010

构建时如果没有指定镜像名称和Tag,则都以\来显示。

如果名称与以前的重复,未指定Tag,则新版本的Tag是latest,而就的名称和Tag都是\

删除none镜像

我们一般定义image,都是使用Dockerfile,我们随时可能修改这个文件,然后重新使用docker build -t name . 命令来构建一个新的image。这种情况下,如果我们使用了和之前一样的镜像名来命名,那么docker会把这个名字赋给新的镜像,以前的镜像并不会被删除,但是此时它的名字被新的镜像剥夺了,就成为了一个无名镜像,也就是\:\出现的原因。这种镜像称为虚悬镜像(dangling)。

这个none镜像会占用磁盘空间,所以我们必须删除它。

当然先要删除引它的容器。

然后可以使用如下的一个命令:

docker rmi $(docker images -f "dangling=true" -q)

这里附带说下docker删除的命令。

rm是删除容器的命令

rmi是删除镜像的命令

如果我们要删除全部的镜像,那么可以使用嵌套的命令,先把镜像的id得到。

可以使用docker images命令。-q参数指的是只显示id。-a是显示全部的。-f可以指定类别,这里指定了类别为dangling的镜像。虚悬镜像(dangling image)

删除全部容器也会使用到类似:

docker rmi $(docker ps -aq)

镜像继承自centos7,在此基础上添加了tomcat和jdk,有很多冗余的内容。好处是使用方便。后续为了缩减镜像文件,建议继承下列的这种的基础镜像。可以缩减很多不必要的内容。

  • [, 7.0.107-jdk8-openjdk, 7.0-jdk8-openjdk, 7-jdk8-openjdk, 7.0.107-jdk8, 7.0-jdk8, 7-jdk8, 7.0.107, 7.0, 7]
  • [ 7.0.107-jdk8-openjdk-slim, 7.0-jdk8-openjdk-slim, 7-jdk8-openjdk-slim]

遇见的问题反思

报404错误

tomcat的server.xml配置中标签下需要配置context。其中path是配置所有url的前缀路径。如果不配置的话,不清楚默认是什么。之前没有配置这项导致经常404。

 <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path="" docBase="yezhubao"/>

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

      </Host>

容器中tomcat未启动

镜像创建完成,容器也启动了。发现容器中的tomcat未启动。

简单来说要么是tomcat启动后自动关闭,要么spring项目启动后自动关闭。

在容器中执行tomcat的startup.sh是可以启动tomcat的。但是在Dockerfile中执行此脚本,tomcat启动后spring项目立即自己结束。甚至容器也处于退出状态

可能与tomcat的启动方式有关

以下是从网上找到的可能原因

https://www.cnblogs.com/yechen2019/p/12100616.html

CMD ["/usr/local/tomcat/bin/catalina.sh","run"],直接运行tomcat的catalina.sh脚本,曾经尝试过在这里运行startup.sh,
但是那个脚本执行完毕后会自动进入后台模式,而docker容器必须有前台运行的应用,否则容器会直接挂掉,所以采用这种方式。

参考上述内容,通过在Dockerfile中使用CMD ["catalina.sh", "run"]解决了tomcat并部署war文件的目的

CMD ["catalina.sh", "run"]

Dockfile

FROM tomcat:8.5.46-jdk8-openjdk-slim
COPY ecs-console.war /usr/local/tomcat/webapps/
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS -server -Xmx4736M -Xms4736M -Xmn1728M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
RUN ln -snf /usr/share/zoneinfo/$TZ  /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]

基础的部分就不说了,这里只指明需要注意的地方

  1. 选取8.5.46-jdk8-openjdk-slim作为基镜像,减小镜像的大小
  2. 设置环境变量JAVA_OPTS,控制jvm的内存大小,不然jdk8默认情况下jvm会根据宿主机的内存分配自己的内存.据说jdk10以后会根据容器的大小分配内存
  3. CMD ["/usr/local/tomcat/bin/catalina.sh","run"],直接运行tomcat的catalina.sh脚本,曾经尝试过在这里运行startup.sh,
    但是那个脚本执行完毕后会自动进入后台模式,而docker容器必须有前台运行的应用,否则容器会直接挂掉,所以采用这种方式。
  4. 采用COPY命令加入war包,因为tomcat运行时会自动解压,而Docker的ADD命令的效率低于COPY,所以使用COPY命令

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK