Java的普及和容器技术的兴起使得JDK和JRE镜像在应用部署中扮演着关键的角色。本文将为您提供一份全面而实用的指南,覆盖了JDK和JRE镜像的通常选择、制作流程、不同场景下的应用、安全性最佳实践以及镜像优化策略。

1. 选择合适的基础镜像

Docker基础镜像的尺寸

linux版本

镜像名称

拉取命令

尺寸

Alpine

alpine:latest

docker pull alpine:latest

5.27MB

Ubuntu

ubuntu:latest

docker pull ubuntu:latest

69.2MB

Debian

debian:latest

docker pull debian:latest

118MB

Amazon Linux 

public.ecr.aws/amazonlinux/amazonlinux:minimal

docker pull public.ecr.aws/amazonlinux/amazonlinux:minimal

docker pull public.ecr.aws/amazonlinux/amazonlinux:2023-minimal

116MB

Amazon Linux 2

amazonlinux:latest

docker pull amazonlinux:latest

194MB

Alma Linux

almalinux:latest

docker pull almalinux:latest

210MB

Debian

python:3.8

docker pull python:3.8

861MB

Debian

python:3.8-slim

docker pull python:3.8-slim

117MB

Alpine

python:3.8-alpine

docker pull python:3.8-alpine

46.1MB

Debian

java:8-jre

docker pull java:8-jre

311MB

Debian

java:8-jdk

docker pull java:8-jdk

643MB

Debian

openjdk:8-jre

docker pull openjdk:8-jre

266MB

Debian

openjdk:8-jdk

docker pull openjdk:8-jdk

520MB

Debian

openjdk:8-jre-slim

docker pull openjdk:8-jre-slim

187MB

Debian

openjdk:8-jdk-slim

docker pull openjdk:8-jdk-slim

292MB

Alpine

openjdk:8-jre-alpine

docker pull openjdk:8-jre-alpine

83.4MB

Alpine

openjdk:8-jdk-alpine

docker pull openjdk:8-jdk-alpine

292MB

Debian

openjdk:11-jre

docker pull openjdk:11-jre

294MB

Debian

openjdk:11-jdk

docker pull openjdk:11-jdk

645MB

Alpine

tomcat:8.5-alpine

docker pull tomcat:8.5-alpine

106MB

Alpine

node:12-alpine

docker pull node:12-alpine

89.4MB

Debian

node:12

docker pull node:12

864MB

Alpine

node:16-alpine

docker pull node:16-alpine

114MB

Debian

node:16

docker pull node:16

856MB

 minimal-container

1.1 官方镜像

OpenJDK官方维护的镜像是首选,保证了最新的版本和官方支持。

FROM openjdk:11-jre-slim
  • 1.

1.2 Alpine Linux

为了减小镜像体积,可以选择基于Alpine Linux的OpenJDK镜像。

FROM adoptopenjdk:11-jre-hotspot-alpine
  • 1.

1.3 定制镜像

根据特定需求,创建定制的JDK或JRE镜像,添加必要的依赖和配置。

FROM ubuntu:20.04

# 自定义安装和配置JDK
  • 1.
  • 2.
  • 3.

2. 制作JDK和JRE镜像的最佳实践

通过Dockerfile定义镜像制作过程,并使用多阶段构建来降低最终镜像的大小。

# 第一阶段:构建和配置JDK
FROM debian:bullseye-slim AS builder

# ... (详细见前文的Dockerfile)

# 第二阶段:最终镜像
FROM debian:bullseye-slim

COPY --from=builder /usr/java /usr/java

ENV JAVA_HOME=/usr/java/default \
    PATH=/usr/java/default/bin:$PATH
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

定制jdk 11基础镜像

FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal

# 安装OpenJDK 11
RUN dnf install -y java-11-amazon-corretto-devel \ 
    && dnf clean all \
    && echo "networkaddress.cache.ttl = 60" >> $JAVA_HOME/conf/security/java.security
    && rm -rf /var/cache/dnf /usr/share/doc /usr/share/man

# 设置JAVA_HOME环境变量
ENV JAVA_HOME /usr/lib/jvm/java-11-amazon-corretto

# 验证Java安装
RUN java -version

# 设置工作目录
WORKDIR /app

# 指定容器启动时执行的命令
CMD ["/bin/bash"]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

定制jdk 17例子

# 第一阶段:基于Debian安装和配置JDK
FROM debian:bullseye-slim AS builder

# 定义环境变量
ENV JAVA_PKG=jdk-17_linux-x64_bin.tar.gz \
    JAVA_HOME=/usr/java/default

# 安装必要的工具
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# 复制JDK安装包到镜像中
COPY ${JAVA_PKG} /usr/java/

# 解压JDK安装包并设置软链接
RUN tar -xvf /usr/java/${JAVA_PKG} -C /usr/java && \
    ln -s /usr/java/jdk-17.0.9 /usr/java/default && \
    rm /usr/java/${JAVA_PKG}

# 设置TTL
RUN echo "networkaddress.cache.ttl = 60" >> $JAVA_HOME/conf/security/java.security

# 第二阶段:基于Debian创建最终镜像
FROM debian:bullseye-slim

# 从builder阶段复制JDK到最终镜像中
COPY --from=builder /usr/java /usr/java

# 设置环境变量
ENV JAVA_HOME=/usr/java/default \
    PATH=/usr/java/default/bin:$PATH
  • 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.

3. 场景应用与性能优化

3.1 容器化部署

选择轻量级基础镜像,使用多阶段构建来减小镜像体积,适应容器环境。

3.2 版本管理

定期更新JDK和JRE镜像,确保应用程序能够运行在最新、安全的Java版本上。

3.3 定制化

根据应用程序的需要,定制JDK或JRE镜像,包括设置JVM参数、调整垃圾回收策略等。

3.4 监控和调优

利用监控工具,如Java Mission Control、VisualVM等,对Java应用程序进行性能监控和调优。

3.5 安全优化

避免在容器中使用root用户,定期审查安全漏洞,使用最小权限原则。

4. 安全性最佳实践

4.1 更新策略

定期应用JDK和JRE的安全更新,确保您的应用程序始终运行在最新、安全的Java版本上。

4.2 基础镜像审查

审查基础镜像,确保它来自可信任的源,避免使用未经验证的镜像。

4.3 镜像签名

使用Docker镜像签名确保您的镜像的完整性和来源可信。

4.4 访问控制

在容器中运行应用程序时,确保容器内的用户权限被适当限制,不要使用root用户。

4.5 敏感信息管理

定期审查应用程序镜像,确保不包含敏感信息,例如硬编码的密码、密钥等。

5. 镜像优化策略

5.1 多阶段构建

通过多阶段构建,只保留最终运行时所需的组件,减小镜像大小。

wget https://curl.se/download/curl-7.79.1.tar.gz
wget http://www.lcdf.org/gifsicle/gifsicle-1.95.tar.gz
  • 1.
  • 2.
# 第一阶段:构建 JDK 11
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS jdk_builder

# 设置 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/lib/jvm/java-11-amazon-corretto

# 安装 OpenJDK 11
RUN dnf install -y java-11-amazon-corretto-devel \
    && dnf clean all \
    && echo "networkaddress.cache.ttl = 60" >> $JAVA_HOME/conf/security/java.security \
    && rm -rf /var/cache/dnf /usr/share/doc /usr/share/man

# 验证 Java 安装
RUN java -version

# 设置工作目录
WORKDIR /app

# 指定容器启动时执行的命令
CMD ["/bin/bash"]

# 第二阶段:构建 gifsicle 最终镜像
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS gifsicle_builder

# 添加 gifsicle 源码
ADD gifsicle-1.95.tar.gz /tmp

# 安装 make 和 gcc,编译安装 gifsicle
RUN dnf install -y make gcc \
    && cd /tmp/gifsicle-1.95 \
    && ./configure \
    && make \
    && make install \
    && dnf clean all \
    && rm -rf /var/cache/dnf /usr/share/doc /usr/share/man /tmp/gifsicle-1.95

# 设置 gifsicle 环境变量
ENV PATH="/usr/local/gifsicle/bin:${PATH}"

# 验证 gifsicle 安装
RUN gifsicle --version

# 第三阶段:安装 curl
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS curl_builder

# 添加 curl 源码
ADD curl-7.79.1.tar.gz /tmp

# 下载并安装 curl
RUN dnf install -y make gcc openssl-devel \
    && cd /tmp/curl-7.79.1 \
    && ./configure --with-openssl \
    && make \
    && make install \
    && dnf clean all \
    && rm -rf /var/cache/dnf /usr/share/doc /usr/share/man /tmp/curl-7.79.1

# 最终镜像
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal

# 从 JDK 11 阶段复制 JAVA_HOME 环境变量和安装结果
COPY --from=jdk_builder $JAVA_HOME $JAVA_HOME
COPY --from=jdk_builder /usr/bin/java /usr/bin/java

# 从 gifsicle 阶段复制 gifsicle 安装结果和环境变量
COPY --from=gifsicle_builder /usr/local/bin/gifsicle /usr/local/bin/gifsicle

# 从 curl 阶段复制 curl 安装结果
COPY --from=curl_builder /usr/local/bin/curl /usr/local/bin/curl
  • 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.

5.2 懒加载依赖

延迟加载应用程序的依赖项,根据需要在运行时下载。

# 第一阶段:构建基础镜像
FROM alpine as base

# 安装运行时需要的基本工具
RUN apk add --no-cache curl

# 第二阶段:懒加载依赖
FROM base as lazy_deps

# 在运行时下载依赖项
RUN curl -o /usr/local/bin/dependency https://example.com/dependency

# 第三阶段:应用程序镜像
FROM base

# 从懒加载阶段复制所需的依赖项
COPY --from=lazy_deps /usr/local/bin/dependency /usr/local/bin/dependency

# 设置容器启动时执行的命令
CMD ["dependency"]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

5.3 资源清理

在构建过程中清理不必要的文件和依赖,减小镜像体积。

6. 结语

通过本文提供的全方位指南,您将能够更好地选择、制作和优化JDK和JRE镜像,确保它们在各种场景下都能够发挥最佳性能和安全性。在不断演进的容器化世界中,保持对新技术和最佳实践的关注,将使您的Java应用程序始终保持竞争力。