生产级别Dockerfile制作过程

Dockerfile生产实践

背景介绍

因公司推进java11版本升级(默认支持容器),故小组制作了操作系统、java8和java11基础镜像。制作过程使用了一系列优化做法,涵盖缩短构建时间、制作更小更安全镜像等问题,旨在提升构建镜像效率和质量,并使其在容器云平台上更好地运行。重点解决了Dockerfile编写过程中,经常遇到的以下四个问题:

  1. 需要准确控制docker镜像内的内容,如语言和时区设置等;
  2. 需要严格控制生产环境中的漏洞,使用clair扫描基础镜像;
  3. 不希望依赖外部代码库,已替换为国内阿里yum或apk源;
  4. 需要在每个镜像中使用相同的基本操作系统,给出了alpine3和centos7基础镜像。

经过镜像大小、安全和性能等多方面测试,小组发布了基础镜像版本v2.0.0:

  1. base-alpine 基础镜像 ContainerRegistry/library/base-alpine:3.11.3
  2. base-centos基础镜像 ContainerRegistry/library/base-centos:7.7.1908
  3. java11-alpine 开发镜像 ContainerRegistry/library/java-alpine:11.0.5-3.11.3
  4. java11-centos 开发镜像 ContainerRegistry/library/java-centos:11.0.6-7.7.1908
  5. java8-alpine 开发镜像 ContainerRegistry/library/java-alpine:1.8.0-3.11.3
  6. java8-centos 开发镜像 ContainerRegistry/library/java-centos:1.8.0-7.7.1908

附件给出了基础镜像制作过程,包含Dockerfile文件和执行的docker客户端命令等。各个产品根据自身的需要,来制作相应的应用镜像。基础镜像使用说明: stage1-os的base-alpine 基础镜像和base-centos基础镜像, 生产可用; stage2-sdk的java11和java8开发镜像, 如果1.8.0/11.0.5/11.0.6能满足业务需求,可以不用修改; stage3和stage4的dockerfile,需要根据业务特点修改。

使用示例

前提条件:

1.安装18.06.1-ce以上版本 docker容器引擎;
2.登录私有镜像仓库 docker login ContainerRegistry;
3.熟悉基本的docker命令和k8s部署流程。

案例情景:

比如研发A按照公司的需求,改用java11制作了jar包,想制作docker镜像,请问怎样使用上述基础镜像?

解决方案:
a.新建一个文件夹,将java11制作的jar包、目录stage4-app中的Dockerfile.noah-java11-alpine和start-11.sh复制到该文件夹;
b.根据实际情况,修改Dockerfile.noah-java11-alpine中的镜像元数据、环境变量和默认命令等信息;
c.制作docker镜像,使用docker build -f Dockerfile.noah-java11-centos -t image-name。其中,image-name镜像命名规则建议使用语义版本控制进行标记;
d.测试镜像,先使用docker run -m 4GB -it image-name /bin/bash进入容器,后./start-11.sh启动应用。

制作过程

stage1-os: 操作系统Dockerfile.base-alpine

  1. Dockerfile.base-alpine
FROM  ContainerRegistry/library/alpine-official:3.11.3

# 镜像元数据
LABEL name="Alpine base image" \
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A Alpine base image to be used in simple-cloud apps"

# 语言环境和时区变量
ENV LANG='zh_CN.UTF-8' LANGUAGE='zh_CN:zh' LC_ALL='zh_CN.UTF-8' TZ='Asia/Shanghai'

# 因Java是基于GUN Standard C library(glibc),而Alpine基于MUSL libc(mini libc),故Alpine需要安装glibc的库
COPY glibc/ /

# 安装Alphine库依赖
RUN set -eux \
    && echo "https://mirrors.aliyun.com/alpine/v3.11/main" > /etc/apk/repositories \
    && echo "https://mirrors.aliyun.com/alpine/v3.11/community" >> /etc/apk/repositories \
    && echo "https://mirrors.aliyun.com/alpine/edge/testing" >> /etc/apk/repositories \
    && apk update \
    && apk add --no-cache bash tzdata \
    && mv /sgerrand.rsa.pub /etc/apk/keys/ \
    #wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
    #wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk && \
    #wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-bin-2.30-r0.apk && \
    #wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-i18n-2.30-r0.apk && \
    && apk add glibc-2.30-r0.apk glibc-bin-2.30-r0.apk glibc-i18n-2.30-r0.apk \
    && rm -f /*.apk \
    && rm -rf /var/cache/apk/* \
    && rm -rf /glibc-* 

# 设置语言和时区
RUN set -eux \
    && echo -e "en_US\nzh_CN"  | xargs -i /usr/glibc-compat/bin/localedef -i {} -f UTF-8 {}.UTF-8 \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "${TZ}" > /etc/timezone \
    && echo "LANG=${LANG}" >> /etc/profile \
    && echo "LANGUAGE=${LANGUAGE}" >> /etc/profile \
    && echo "LC_ALL=${LC_ALL}" >> /etc/profile \
    && source /etc/profile \
    && rm -rf /tmp/*

# 创建devops用户, 默认为root用户(id=0)
RUN set -eux \
    #wget -O /usr/local/bin/tini https://github.com/krallin/tini/releases/download/v0.18.0/tini && \
    && mv /tini /usr/local/bin/ \
    && addgroup -g 10001 -S devops \
    && adduser devops -u 10001 -D -S -s /bin/bash -G devops \
    && chmod -R +x /usr/local/bin \
    && chgrp -R 0 /usr/local/bin/ \        
    && chmod -R g=u /usr/local/bin /opt \
    && sed -i '/^root/c\root:x:0:0:root:/root:/bin/bash' /etc/passwd \
    && sed -i '/^root/c\root:$6$mphzPBXa$3tePoCmOUiRIzOoujeFwjjznQ94LBa6j2k5CHcPiiL2ywVwJ/c8QiqtbKAU2ntbHB2yPcDK2ZDr49GGT1HXkI/:18307:0:99999:7:::' /etc/shadow \
    && sed -i '/^devops/c\devops:$6$n5wOC3GI$Go4jmLorMs9PcJidDtBmH.D4KUoAgg9TTuGRD25/mwztpje0I9jjaENU9xFepnONW/UmAyUX9Fxv52DsKRq5O.:18307:0:99999:7:::' /etc/shadow

# 切换到非root用户 
# USER 10001

# 可传递参数来覆盖默认命令
CMD ["bash"]

  1. Dockerfile.base-centos
# 镜像元数据
LABEL name="X.L.Xia CentOS base image" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A CentOS base image to be used in simple-cloud apps" 

# 语言环境变量
ENV LANG='zh_CN.UTF-8' LANGUAGE='zh_CN:zh' LC_ALL='zh_CN.UTF-8' TZ='Asia/Shanghai'

# 安装centos7库依赖
RUN set -eux \
    && yum install -y wget \
    && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
    && wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo \
    && wget -O /etc/yum.repos.d/CentOS7-Base-163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo \
    && yum update -y \
    && yum install -y kde-l10n-Chinese \
    && yum -y reinstall glibc-common \
    && yum clean all \
    && rm -rf /tmp/* \
    && rm -rf /var/cache/yum/*

# 设置语言和时区
RUN set -eux \
    && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 \
    && echo "export LANG=${LANG}" >> /etc/locale.conf \
    && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo '${TZ}' > /etc/timezone

# 创建devops用户, 默认为root用户(id=0)
RUN set -ex \
    && wget -O /usr/local/bin/tini https://github.com/krallin/tini/releases/download/v0.18.0/tini \
    && groupadd --gid 10001 devops \
    && useradd --uid 10001 --gid devops --shell /bin/bash --create-home devops \
    && chmod -R +x /usr/local/bin \
    && chgrp -R 0 /usr/local \        
    && chmod -R g=u /usr/local/bin /opt \
    && sed -i '/^root/c\root:$6$mphzPBXa$3tePoCmOUiRIzOoujeFwjjznQ94LBa6j2k5CHcPiiL2ywVwJ/c8QiqtbKAU2ntbHB2yPcDK2ZDr49GGT1HXkI/:18307:0:99999:7:::' /etc/shadow \
    && sed -i '/^devops/c\devops:$6$n5wOC3GI$Go4jmLorMs9PcJidDtBmH.D4KUoAgg9TTuGRD25/mwztpje0I9jjaENU9xFepnONW/UmAyUX9Fxv52DsKRq5O.:18307:0:99999:7:::' /etc/shadow

# 切换到非root用户 
# USER 10001

# 可传递参数来覆盖默认命令
CMD ["bash"]
[root@ecs-7ef181 stage1-os]# ls
Dockerfile.base-alpine  Dockerfile.base-centos  glibc
[root@ecs-7ef181 stage1-os]# cat Dockerfile.base-centos 
FROM hub.tech.21cn.com/addons/centos-official:7.7.1908

# 镜像元数据
LABEL name="X.L.Xia CentOS base image" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A CentOS base image to be used in simple-cloud apps" 

# 语言环境变量
ENV LANG='zh_CN.UTF-8' LANGUAGE='zh_CN:zh' LC_ALL='zh_CN.UTF-8' TZ='Asia/Shanghai'

# 安装centos7库依赖
RUN set -eux \
    && yum install -y wget \
    && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
    && wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo \
    && wget -O /etc/yum.repos.d/CentOS7-Base-163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo \
    && yum update -y \
    && yum install -y kde-l10n-Chinese \
    && yum -y reinstall glibc-common \
    && yum clean all \
    && rm -rf /tmp/* \
    && rm -rf /var/cache/yum/*

# 设置语言和时区
RUN set -eux \
    && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 \
    && echo "export LANG=${LANG}" >> /etc/locale.conf \
    && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo '${TZ}' > /etc/timezone

# 创建devops用户, 默认为root用户(id=0)
RUN set -ex \
    && wget -O /usr/local/bin/tini https://github.com/krallin/tini/releases/download/v0.18.0/tini \
    && groupadd --gid 10001 devops \
    && useradd --uid 10001 --gid devops --shell /bin/bash --create-home devops \
    && chmod -R +x /usr/local/bin \
    && chgrp -R 0 /usr/local \        
    && chmod -R g=u /usr/local/bin /opt \
    && sed -i '/^root/c\root:$6$mphzPBXa$3tePoCmOUiRIzOoujeFwjjznQ94LBa6j2k5CHcPiiL2ywVwJ/c8QiqtbKAU2ntbHB2yPcDK2ZDr49GGT1HXkI/:18307:0:99999:7:::' /etc/shadow \
    && sed -i '/^devops/c\devops:$6$n5wOC3GI$Go4jmLorMs9PcJidDtBmH.D4KUoAgg9TTuGRD25/mwztpje0I9jjaENU9xFepnONW/UmAyUX9Fxv52DsKRq5O.:18307:0:99999:7:::' /etc/shadow

# 切换到非root用户 
# USER 10001

# 可传递参数来覆盖默认命令
CMD ["bash"]

stage2-sdk: 开发环境

  1. Dockerfile.java11-alpine
FROM  ContainerRegistry/library/base-alpine:3.11.3 

# 镜像元数据
LABEL name="Java image on Alpine" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A Java11 image based on Alpine" 

# 环境变量
ENV JAVA_VERSION="11.0.5" \
    JAVA_HOME="/usr/lib/jvm/java-11-openjdk" \
    PATH="/usr/lib/jvm/java-11-openjdk/bin:$PATH"

# 安装openjdk开发环境
RUN set -eux \
    && apk update \
    && apk add --no-cache openjdk11 \
    && rm -rf /var/cache/apk/* \
    && rm -rf /tmp/* \
    && javac -version \
    && java -version

  1. Dockerfile.java11-centos
FROM  ContainerRegistry/library/base-centos:7.7.1908 

# 镜像元数据
LABEL name="Java image on CentOS" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A Java11 image based on CentOS" 

# 环境变量
ENV JAVA_VERSION="11.0.6" \
    JAVA_HOME="/etc/alternatives/java_sdk_11" \
    PATH="/etc/alternatives/java_sdk_11/bin:$PATH"

# 安装openjdk开发环境
RUN yum update -y \
    && yum install -y java-11-openjdk java-11-openjdk-devel \
    && yum clean all \
    && rm -rf /tmp/* \
    && rm -rf /var/cache/yum/* \
    && javac -version \
    && java -version 

stage3-cmd:中间件层

  1. Dockerfile.resin-java11-alpine
FROM  ContainerRegistry/library/java-alpine:11.0.5-3.11.3

# 镜像元数据
LABEL name="Base image with Caucho Resin running on OpenJDK 11" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A Resin image based on OpenJDK 11" 

# 使用ADD解压resin-4.0.64.tar.gz到docker镜像的/opt目录
ADD resin-4.0.64.tar.gz /opt/

# 环境变量
ENV RESIN_HOME=/opt/resin-4.0.64 \
    PATH="/opt/resin/bin:$PATH"

# 安装resin-4.0.64
RUN set -eux \
    && java -jar ${RESIN_HOME}/lib/resin.jar version

  1. Dockerfile.resin-java11-centos
FROM ContainerRegistry/library/java-centos:11.0.6-7.7.1908 

# 镜像元数据
LABEL name="Base image with Caucho Resin running on OpenJDK 11" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1" \
      summary="A Resin image based on OpenJDK 11" 

# 复制文件
#COPY resin-pro-4.0.64-1.x86_64.rpm /tmp/
#COPY mysql-connector-java-5.1.38.zip /var/resin/webapp-jars/
# 使用ADD解压resin-4.0.64.tar.gz到docker镜像的/opt目录
ADD resin-4.0.64.tar.gz /opt/
 
# 环境变量
#ENV RESIN_HOME=/usr/local/share/resin \
#    PATH="/usr/local/share/resin/bin:$PATH"
ENV RESIN_HOME=/opt/resin-4.0.64 \
    PATH="/opt/resin/bin:$PATH"

# 安装resin-4.0.64
#RUN set -eux \
#    && yum localinstall -y /tmp/resin-pro-4.0.64-1.x86_64.rpm \
#    && yum clean all \
#    && rm -f /tmp/resin-pro-4.0.64-1.x86_64.rpm \
#    #因-d64在java10中已经被移除, 故resinctl会报Unrecognized option: -d64异常
#    #&& resinctl version
#    && java -jar ${RESIN_HOME}/lib/resin.jar version
# 安装resin-4.0.64
RUN set -eux \
    && java -jar ${RESIN_HOME}/lib/resin.jar version

#  MySQL JDBC driver Connector/J依赖
#RUN set -eux; \
#    cd /var/resin/webapp-jars; \
#    yum -y install unzip; \
#    yum clean all; \
#    unzip -j mysql-connector-java-5.1.38.zip mysql-connector-java-5.1.38/mysql-connector-java-5.1.38-bin.jar; \
#    rm mysql-connector-java-5.1.38.zip;
    

stage4-app: 应用代码

  1. Dockerfile.noah-java11-alpine
FROM  ContainerRegistry/library/java-alpine:11.0.5-3.11.3

# 镜像元数据
LABEL name="Test image running on OpenJDK 11" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1.0.0" \
      summary="A Noah image based on OpenJDK 11" 

# 环境变量
ENV APP_NAME="noah" \
    APP_HOME="/data/addons/noah" 

# 设置工作目录
WORKDIR ${APP_HOME}/

# 复制文件到工作目录
COPY release/ .

# 入口点使用tini初始系统, 以防止产生僵尸进程
ENTRYPOINT ["tini", "--"] 

# 容器在运行时侦听指定的网络端口
EXPOSE 8000/tcp

# 可传递参数来覆盖默认命令
CMD ["sh","start-11.sh"]

  1. Dockerfile.noah-java11-centos
FROM  ContainerRegistry/library/java-centos:11.0.6-7.7.1908

# 镜像元数据
LABEL name="Test image running on OpenJDK 11" \    
      maintainer="X.L.Xia" \
      vendor="X.L.Xia" \
      release="1.0.0" \
      summary="A Noah image based on OpenJDK 11" 

# 环境变量
ENV APP_NAME="noah" \
    APP_HOME="/data/addons/noah" 

# 设置工作目录
WORKDIR ${APP_HOME}/

# 复制文件到工作目录
COPY release/ .

# 入口点使用tini初始系统, 以防止产生僵尸进程
ENTRYPOINT ["tini", "--"] 

# 容器在运行时侦听指定的网络端口
EXPOSE 8000/tcp

# 可传递参数来覆盖默认命令
CMD ["sh","start-11.sh"]
  1. start-11.sh
#!/bin/bash
set -eux
# pinpoint动态链路跟踪参数配置
: ${NODE:="${HOSTNAME##*.}"}
: ${APP_NAME:="noah"}
: ${APP_VERSION:="v1.0.0"}
: ${APP_HOME:=$(cd `dirname $0`; pwd)}
: ${PROJECT_NAME:="genesis"}
: ${UUID:=$(cat /proc/sys/kernel/random/uuid)}
: ${POD_IP:="127.0.0.1"}
: ${dtraceName:=${NODE}-${PROJECT_NAME}-${APP_NAME}}
: ${agentId:=${POD_IP}}
: ${pingpointPath:=${APP_HOME}/dtrace/dtrace-bootstrap-2.2.0.jar}

# 日志目录
mkdir -p ${APP_HOME}/logs

# dtrace提示
#echo -e "The following was configured on pinpoint: \nagentId=${agentId} \ndtraceName=${dtraceName} \npingpointPath=${pingpointPath}" > ${APP_HOME}/logs/${APP_NAME}-pinpoint-agent.log 

# java11启动参数配置示例(resources.limits.cpu=2,resources.limits.memory=4Gi ) 
# dtrace-bootstrap-2.2.0.jar不支持java11
#java -javaagent:${pingpointPath}\
#     -Ddtrace.applicationName=${dtraceName}\
#     -Ddtrace.agentId=${agentId}\
java -XX:ActiveProcessorCount=2\
     -Xmx2688M\
     -Xms2688M\
     -Xmn960M\
     -XX:MaxMetaspaceSize=256M\
     -XX:MetaspaceSize=256M\
     -XX:ReservedCodeCacheSize=128M\
     -XX:MaxDirectMemorySize=512M\
     -XX:SurvivorRatio=10\
     -XX:ParallelGCThreads=2\
     -Xlog:gc:${APP_HOME}/logs/gc.log:time,level,tags\
     -XX:+HeapDumpOnOutOfMemoryError\
     -XX:HeapDumpPath=${APP_HOME}/logs/java.hprof\
     -XX:+CMSScavengeBeforeRemark\
     -XX:CMSMaxAbortablePrecleanTime=5000\
     -XX:+CMSClassUnloadingEnabled\
     -XX:CMSInitiatingOccupancyFraction=80\
     -XX:+UseCMSInitiatingOccupancyOnly\
     -XX:+ExplicitGCInvokesConcurrent\
     -XX:-UsePerfData\
     -XshowSettings:vm\
     -jar ${APP_HOME}/${APP_NAME}-${APP_VERSION}.jar
  1. start-8.sh
#!/bin/bash
set -eux
# pinpoint动态链路跟踪参数配置
: ${NODE:="${HOSTNAME##*.}"}
: ${APP_NAME:="noah"}
: ${APP_VERSION:="v1.0.0"}
: ${APP_HOME:=$(cd `dirname $0`; pwd)}
: ${PROJECT_NAME:="genesis"}
: ${UUID:=$(cat /proc/sys/kernel/random/uuid)}
: ${POD_IP:="127.0.0.1"}
: ${dtraceName:=${NODE}-${PROJECT_NAME}-${APP_NAME}}
: ${agentId:=${POD_IP}}
: ${pingpointPath:=${APP_HOME}/dtrace/dtrace-bootstrap-2.2.0.jar}

# gc日志目录
mkdir -p ${APP_HOME}/logs

# dtrace提示
echo -e "The following was configured on pinpoint: \nagentId=${agentId} \ndtraceName=${dtraceName} \npingpointPath=${pingpointPath}" > ${APP_HOME}/logs/${APP_NAME}-pinpoint-agent.log 

# java-1.8.0启动参数配置示例(resources.limits.cpu=2,resources.limits.memory=4Gi ) 
java -javaagent:${pingpointPath}\
     -Ddtrace.applicationName=${dtraceName}\
     -Ddtrace.agentId=${agentId}\
     -XX:ActiveProcessorCount=2\
     -Xmx2688M\
     -Xms2688M\
     -Xmn960M\
     -XX:MaxMetaspaceSize=256M\
     -XX:MetaspaceSize=256M\
     -XX:ReservedCodeCacheSize=128M\
     -XX:MaxDirectMemorySize=512M\
     -XX:SurvivorRatio=10\
     -XX:ParallelGCThreads=2\
     -XX:+UnlockExperimentalVMOptions\
     -XX:+UseCGroupMemoryLimitForHeap\
     -XX:+HeapDumpOnOutOfMemoryError\
     -XX:HeapDumpPath=${APP_HOME}/logs/java.hprof\
     -XX:+UseConcMarkSweepGC\
     -XX:+CMSScavengeBeforeRemark\
     -XX:CMSMaxAbortablePrecleanTime=5000\
     -XX:+CMSClassUnloadingEnabled\
     -XX:CMSInitiatingOccupancyFraction=80\
     -XX:+UseCMSInitiatingOccupancyOnly\
     -XX:+ExplicitGCInvokesConcurrent\
     -Xloggc:${APP_HOME}/logs/gc.log\
     -XX:+PrintGCDetails\
     -XX:+PrintGCDateStamps\
     -XX:-UsePerfData\
     -XshowSettings:vm\
     -jar ${APP_HOME}/${APP_NAME}-${APP_VERSION}.jar

执行命令

## stage1-os:操作系统
docker build -f Dockerfile.base-centos -t ContainerRegistry/library/base-centos:7.7.1908 .
docker build -f Dockerfile.base-alpine -t ContainerRegistry/library/base-alpine:3.11.3 .

## stage2-sdk:运行环境
docker build -f Dockerfile.java11-centos -t ContainerRegistry/library/java-centos:11.0.6-7.7.1908 .
docker build -f Dockerfile.java11-alpine -t ContainerRegistry/library/java-alpine:11.0.5-3.11.3 .
docker build -f Dockerfile.java8-centos -t ContainerRegistry/library/java-centos:1.8.0-7.7.1908 .
docker build -f Dockerfile.java8-alpine -t ContainerRegistry/library/java-alpine:1.8.0-3.11.3 .

## stage3-cmw:中间件
docker build -f Dockerfile.resin-java11-centos -t ContainerRegistry/library/resin-java-centos:4.0.64-11.0.6-7.7.1908 .
docker build -f Dockerfile.resin-java11-alpine -t ContainerRegistry/library/resin-java-alpine:4.0.64-11.0.5-3.11.3 .
docker build -f Dockerfile.resin-java8-centos -t ContainerRegistry/library/resin-java-centos:4.0.64-1.8.0-7.7.1908 .
docker build -f Dockerfile.resin-java8-alpine -t ContainerRegistry/library/resin-java-alpine:4.0.64-1.8.0-3.11.3 .

## stage4-app:应用
docker build -f Dockerfile.noah-java11-centos -t ContainerRegistry/trial/noah-java11-centos:v1.0.0 .
docker build -f Dockerfile.noah-java11-alpine -t ContainerRegistry/trial/noah-java11-alpine:v1.0.0 .
docker build -f Dockerfile.noah-java8-centos -t ContainerRegistry/trial/noah-java8-centos:v1.0.0 .
docker build -f Dockerfile.noah-java8-alpine -t ContainerRegistry/trial/noah-java8-alpine:v1.0.0 .

## 测试镜像
- a.docker run方式:先bash进入容器,后./start.sh-11或start-8.sh启动应用
docker run -m 4GB -it ContainerRegistry/trial/noah-java11-centos:v1.0.0 /bin/bash
docker run -m 4GB -it ContainerRegistry/trial/noah-java11-alpine:v1.0.0 /bin/bash
docker run -m 4GB -it ContainerRegistry/trial/noah-java8-centos:v1.0.0  /bin/bash
docker run -m 4GB -it ContainerRegistry/trial/noah-java8-alpine:v1.0.0  /bin/bash

- b.k8s yaml方式:先简云部署服务,后hey压测服务, 同时查看pinpoint链路跟踪和prometheus监控
hey -z 10s -c 50 -cpus 2 -host "noah-java11.alpine.com" http://xxx.xxx.xxx.xxx/healthz
hey -z 10s -c 50 -cpus 2 -host "noah-java11.centos.com" http://xxx.xxx.xxx.xxx/healthz
hey -z 10s -c 50 -cpus 2 -host "noah-java8.alpine.com" http://xxx.xxx.xxx.xxx/healthz
hey -z 10s -c 50 -cpus 2 -host "noah-java8.centos.com" http://xxx.xxx.xxx.xxx/healthz

最佳实践

在这里插入图片描述

常见问题

在这里插入图片描述

测试结果

在这里插入图片描述

参考资料

1. Dockerfile 最佳实践.
2. Dockerfile最佳实践.
3. 如何写Dockerfile,Dockerfile 参考文档.
4. Dockerfile中文参考手册.
5. Best practices for writing Dockerfiles.
6. 操作容器的最佳做法.
7. 构建容器的最佳做法.
8. Best Practices for Designing and Building Containers for Kubernetes.
9. Kubernetes best practices: How and why to build small container images.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值