构建一个JDK镜像,有三方面需求:

  • 足够精简
  • 功能强大
  • 完善的排错工具

足够精简

如果需要足够精简,那么最好满足以下几种条件:

  • 尽量少的分层,避免上一个分层引入的文件在下一个分层删除,这也整体的大小是很大的
  • 尽量使用最小的基础镜像,比如Alpine
  • 安装软件,不要留下缓存

功能强大

需要的功能不能缺失:

  • 比如安装openjdk8-jre那么就不能忘记安装nss,不然AES256加密会出错
  • 在不知道确切需要多少的时候,尽量不要精简opnejdk8

完善的排错工具

排错是重要的一环,也是运维的精髓:

  • 网络排错工具:ss telnet curl 不能缺
  • JAVA排错工具:jmap 等包含在JDK内,从实际工作中来看,不能精简,且服务不能以PID1启动,不然无法排错,这时候就需要tini来做PID1

Dockerfile

114M,直接上内容:

FROM alpine:3.11.2

ENV JAVA_VERSION=8 \
    JAVA_UPDATE=242 \
    JAVA_HOME="/usr/lib/jvm/default-jvm" \
    PATH="$PATH:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin"

RUN sed -i 's/dl-cdn.alpinelinux.org/mirror.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    # install tzdata
    apk add --no-cache --virtual=.build-dependencies tzdata && \
    # install ops tools
    apk add --no-cache busybox-extras iproute2 jq curl bash freetype tini && \
    # install jdk
    apk add --no-cache openjdk8 && \
    # set timezone
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone && \
    # clean
    apk del .build-dependencies

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["bash"]

用的时候的一些问题

1. ENTRYPOINT与CMD的关系

entrypoint是容器的主入口,cmd是入口的参数,以这样方式书写,最终的进程是/sbin/tini -- bash,如果使用这个镜像进行构建的时候,直接覆盖CMD即可,而不要选择覆盖entrypoint

2. Kubernetes中启动如何设定命令

上一步中,在使用此镜像进行构建时,覆盖了cmd命令,同样在Kubernetes是如下对应:

dockerKubernetes
entrypointcommand
cmdargs

所以在启动镜像时,如果没有设置command,则会沿用docker镜像内的entrypoint,然后使用args覆盖默认的cmd

3. 假如我只想要JRE的

不要忘记了nssjava-cacerts,这俩安装JDK会带,但JRE没有。

92M:

FROM alpine:3.11.2

ENV JAVA_VERSION=8 \
    JAVA_UPDATE=242 \
    JAVA_HOME="/usr/lib/jvm/default-jvm" \
    PATH="$PATH:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin"

RUN sed -i 's/dl-cdn.alpinelinux.org/mirror.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    # install tzdata
    apk add --no-cache --virtual=.build-dependencies tzdata && \
    # install ops tools
    apk add --no-cache nss busybox-extras iproute2 jq curl bash tini && \
    # install jre
    apk add --no-cache openjdk8-jre && \
    # install java base
    apk add --no-cache java-cacerts freetype && \
    # set timezone
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone && \
    # clean
    apk del .build-dependencies

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["sh"]
Last modification:March 9th, 2020 at 07:27 pm