[转帖]Docker镜像最佳实践

docker,镜像,最佳,实践 · 浏览次数 : 0

小编点评

1.仅安装产线需要依赖与软件镜像尽可能最小原则仅复制jar/war使用自定义JRE(Java Runtime Environment) 2. 使用多阶段构建FROM maven:3.6.3-jdk-11-slim AS buildRUN mkdir /projectCOPY . /projectWORKDIR /projectRUN mvn clean package -DskipTests 3. 不要使用root运行应用为了应用的安全,不要使用root账户运行应用 4. 尽可能处理终止信号量推荐使用exec命令ENTRYPOINT [ \"exec\",\"/jre/bin/java\", \"-jar\", \"/app/app.jar\" ] 5. 使用.dockerigore,使用新版jdk使用.dockerignore排除不需要的文件使用Java 8 update 191+ 和jdk10+版本,其他版本无法感知docker内存和cpu限制。

正文

https://www.zhihu.com/people/trumandu-95/posts

 

5条最佳建议

1.仅安装产线需要依赖与软件

镜像尽可能最小原则

  • 仅复制jar/war
  • 使用自定义JRE(Java Runtime Environment)

2.使用多阶段构建

FROM maven:3.6.3-jdk-11-slim AS build
RUN mkdir /project
COPY . /project
WORKDIR /project
RUN mvn clean package -DskipTests
 
 
FROM adoptopenjdk/openjdk11:jre-11.0.9.1_1-alpine
RUN mkdir /app
COPY --from=build /project/target/java-application.jar /app/java-application.jar
WORKDIR /app
CMD "java" "-jar" "java-application.jar"

3.不要使用root运行应用

为了应用的安全,不要使用root账户运行应用

# Add app user
ARG APPLICATION_USER=appuser
RUN adduser --no-create-home -u 1000 -D $APPLICATION_USER

# Configure working directory
RUN mkdir /app && \
    chown -R $APPLICATION_USER /app

USER 1000
COPY --chown=1000:1000 ./app.jar /app/app.jar
WORKDIR /app

EXPOSE 8080
ENTRYPOINT [ "exec","/jre/bin/java", "-jar", "/app/app.jar" ]

4.尽可能处理终止信号量

推荐使用exec命令

ENTRYPOINT [ "exec","/jre/bin/java", "-jar", "/app/app.jar" ]

推荐处理应用终止回调方法

Runtime.getRuntime().addShutdownHook(yourShutdownThread);

5.使用.dockerigore,使用新版jdk

使用.dockerignore排除不需要的文件

使用Java 8 update 191+ jdk10+版本,其他版本无法感知docker内存和cpu限制。

最小镜像实践

在云环境下,精简镜像有极大的资源利用率的提升,节省磁盘和网络带宽,有着极大的收益。

jdk1.8以下推荐使用alpine镜像

docker pull openjdk:8u212-jre-alpine3.9

jdk11+,由于不再提供jre运行时,推进使用alpine+jlink剪裁出最佳运行时。

自定义jre

首先使用jdeps查看依赖的module

$ jdeps --print-module-deps --ignore-missing-deps --recursive --multi-release 17 --module-path="./app/BOOT-INF/lib/*" --class-path ./app/BOOT-INF/lib/* app.jar
java.base,java.compiler,java.desktop,java.instrument,java.management,java.naming,java.prefs,java.scripting

对于spring 应用推荐增加--ignore-missing-deps,可以忽略spring 的一些module缺失,一般情况下我们的jar会包含spring所有依赖,对于这种fat.jar我们可以先解压该包,然后增加--module-path="./app/BOOT-INF/lib/*" --class-path ./app/BOOT-INF/lib/* 参数进行分析。

最后使用jlink输出自定义jre

$ jlink \
         --add-modules java.base,java.compiler,java.desktop,java.instrument,java.management,java.naming,java.prefs,java.scripting \
         --strip-debug \
         --no-man-pages \
         --no-header-files \
         --compress=2 \
         --output ./javaruntime

最佳镜像

以下为最佳实践案例

# base image to build a JRE
FROM amazoncorretto:17.0.3-alpine as corretto-jdk

# required for strip-debug to work
RUN apk add --no-cache binutils

# Build small JRE image
RUN $JAVA_HOME/bin/jlink \
    --verbose \
    --add-modules java.base,java.compiler,java.desktop,java.instrument,java.management,java.naming,java.prefs,java.scripting \
    --strip-debug \
    --no-man-pages \
    --no-header-files \
    --compress=2 \
    --output /customjre

# main app image
FROM alpine:latest
ENV JAVA_HOME=/jre
ENV PATH="${JAVA_HOME}/bin:${PATH}"

# copy JRE from the base image
COPY --from=corretto-jdk /customjre $JAVA_HOME

# Add app user
ARG APPLICATION_USER=appuser
RUN adduser --no-create-home -u 1000 -D $APPLICATION_USER

# Configure working directory
RUN mkdir /app && \
    chown -R $APPLICATION_USER /app

USER 1000

COPY --chown=1000:1000 ./app.jar /app/app.jar
WORKDIR /app

EXPOSE 8080
ENTRYPOINT [ "exec","/jre/bin/java", "-jar", "/app/app.jar" ]

Native Image

使用native image可以极大的减少镜像大小,启动时间,占用内存,因此如果项目可以接入native image,建议优先接入。

具体文档可参考:NativeImage

参考

  1. How to reduce JVM docker image size
  2. 10 best practices to build a Java container with Docker
  3. 使用 jlink 的 Java 运行时

说明

 

如果你对这个系列感兴趣,可以看我在写的一本电子书:《Better Javaer》

与[转帖]Docker镜像最佳实践相似的内容:

[转帖]Docker镜像最佳实践

https://www.zhihu.com/people/trumandu-95/posts 5条最佳建议 1.仅安装产线需要依赖与软件 镜像尽可能最小原则 仅复制jar/war 使用自定义JRE(Java Runtime Environment) 2.使用多阶段构建 FROM maven:3.6.

[转帖]用buildkit和containerd构建镜像

https://zhuanlan.zhihu.com/p/366671300 最近因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://gith

[转帖]用buildkit和containerd构建镜像

https://zhuanlan.zhihu.com/p/366671300 最近因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://gith

[转帖]Docker:Python环境Docker镜像瘦身

https://www.jianshu.com/p/c0ad13e0be85 关键字:Docker,Python 原始镜像 封装一个Python 3.7的环境并且安装Python依赖包实现一个机器学习算法预测任务,Dockerfile如下 FROM python:3.7 MAINTAINER xxx

[转帖]docker 镜像分层原理及容器写时复制

https://xie.infoq.cn/article/19c98e8b15ff9f610a2ee26bd 一、镜像分层与容器层 在进行docker pull 下载镜像的时候,通过下图可以看到镜像是分层下载并解压的。如 nginx:1.20.2 的镜像,其镜像是分为 6 层。 当我们运行一个新的容

[转帖]Docker如何镜像加速

https://www.zhoubotong.site/post/69.html 在使用Docker 下载镜像时,如果不配置镜像加速,下载镜像会比较慢,因为国内从 DockerHub 拉取镜像有时会遇到困难, 此时我们可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例

[转帖]查找 docker 镜像的所有 tag

https://www.jianshu.com/p/f974ec9e7937 建议阅读方式 可前往语雀阅读,体验更好:查找 docker 镜像的所有 tag 环境说明 centos7 阿里云主机一台: docker 相关信息如下: 测试镜像 hello-world 的 tags 情况见官网:dock

[转帖]查找 docker 镜像的所有 tag

查找 docker 镜像的所有 tag https://www.jianshu.com/p/f974ec9e7937 建议阅读方式 可前往语雀阅读,体验更好:查找 docker 镜像的所有 tag 环境说明 centos7 阿里云主机一台: docker 相关信息如下: 测试镜像 hello-wor

[转帖]docker编译speccpu2017

实验步骤: 1.下载docker和speccpu2017 2.docker下载镜像,创建容器 3.将下载的宿主机speccpu2017拷贝到docker创建的容器中(docker cp) 4.在docker容器(docker exec)中编译运行speccpu2017 下载docker yum in

[转帖]Docker 安装部署RabbitMQ

https://www.jianshu.com/p/14ffe0f3db94 15691 15692 这两个端口挺有用的 这里注意获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面。 获查询镜像 docker search rabbitm