雲計算

Docker 構建Java 應用程序包

作者: 張首富
時間: 2021-02-01
微信: y18163201

前言

目前我們公司使用的基本上都是java開發的後端,本文詳細的介紹了公司java程序docker 包構建的演變過程,這裡面不對java包本身的構建做過多的贅述。

docker 鏡像的演變過程

最初的時候我們只想著給java包怎麼放到docker 鏡像中,我們使用瞭如下的Dockerfile

FROM openjdk:8u212-jre-alpine
ENV TZ="Asia/Shanghai"
ENV JVM="-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Xms1024m -Xmx2048m -Xmn512m -Xss512k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC"

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime ; \
    echo $TZ > /etc/timezone  ; \
    mkdir -p /var/upload_tmp ;\
    mkdir -p /home/guiyu-v2/config ; \
    mkdir -p /home/guiyu-v2/jar ;  \
    mkdir -p /home/guiyu-v2/jar/logxml ;\
    mkdir -p /home/temp_download/oss


CMD ["sh","-c","java `echo $JVM` -Djava.io.tmpdir=/var/upload_tmp -Dfile.encoding=utf-8 -Dspring.config.location=/home/guiyu-v2/config/oss.yml -Dlogging.config=/home/guiyu-v2/jar/logxml/log-oss.xml -jar /home/guiyu-v2/jar/guiyu-oss-web-2.0-SNAPSHOT.jar"]

COPY ./guiyu-oss-web/src/main/resources/application.yml /home/guiyu-v2/config/oss.yml
COPY ./guiyu-oss-web/target/guiyu-oss-web-2.0-SNAPSHOT.jar /home/guiyu-v2/jar/
COPY ./guiyu-oss-web/src/main/resources/logback.xml /home/guiyu-v2/jar/logxml/log-oss.xml

使用上面的Dockerfile 顯著運維人員太沒有技術水平了,然後吧啟動參數變成可變的變量,於是乎演變成下面

FROM openjdk:8u212-jre-alpine
ENV TZ="Asia/Shanghai"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime ; \
    echo $TZ > /etc/timezone  ; \
      mkdir -p /var/upload_tmp ;\
    mkdir -p /home/work/ ; \
    mkdir -p /home/work/ ;  \
    mkdir -p //home/work/ ;\
    mkdir -p /home/temp_download/oss ;\
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
    
ENV JVM_OPTS -server -Xms1g -Xmx1g -XX:+UseG1GC
ENV JAVA_OPTS -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/urandom  -Dspring.profiles.active=prod -Dlogging.config=/home/work/logback-spring.xml
ENV JAVA_AGENT=
ENV APP_NAME=guiyu-oss-web-2.0-SNAPSHOT.jar

CMD  java ${JVM_OPTS} ${JAVA_OPTS} ${JAVA_AGENT} -jar ${APP_NAME}

COPY ./guiyu-oss-web/src/main/resources/application.yml /home/work/application.yml
COPY ./guiyu-oss-web/target/guiyu-oss-web-2.0-SNAPSHOT.jar /home/work/
COPY ./guiyu-oss-web/src/main/resources/logback.xml /home/work/logback-spring.xml

發展到這個地步的時候我們啟動就只需要改 JVM_OPTSJAVA_OPTS 參數即可,稍微有點人性化了,但是好景不長,線上出了一點問題,需要通過jvm分析工具來看看那個地方出問題了,我們採用上面這種方式構建的docker鏡像無法使用jvm分析工具。

因為上面這種方式構建的Docker鏡像裡面所有的java進程都是 PID 為1,jvm分析PId 為1 的有點問題,而且好多服務並不能處理系統發送的kill 指令,這所是我不能容忍的,所以就進化成了如下樣子,(docker 不能優雅的stop 請查看我這篇文章https://www.cnblogs.com/shoufu/p/12978843.html)

然後給Docker 添加一個init 進程放在主進程

FROM openjdk:8u212-jre-alpine
ENV TZ="Asia/Shanghai"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime ; \
    echo $TZ > /etc/timezone  ; \
      mkdir -p /var/upload_tmp ;\
    mkdir -p /home/work/ ; \
    mkdir -p /home/work/ ;  \
    mkdir -p //home/work/ ;\
    mkdir -p /home/temp_download/oss ;\
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories ;\
    RUN apk add --no-cache tini

    
ENV JVM_OPTS -server -Xms1g -Xmx1g -XX:+UseG1GC
ENV JAVA_OPTS -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/urandom  -Dspring.profiles.active=prod -Dlogging.config=/home/work/logback-spring.xml
ENV JAVA_AGENT=
ENV APP_NAME=guiyu-oss-web-2.0-SNAPSHOT.jar

ENTRYPOINT ["/sbin/tini", "--"]
CMD  java ${JVM_OPTS} ${JAVA_OPTS} ${JAVA_AGENT} -jar ${APP_NAME}

COPY ./guiyu-oss-web/src/main/resources/application.yml /home/work/application.yml
COPY ./guiyu-oss-web/target/guiyu-oss-web-2.0-SNAPSHOT.jar /home/work/
COPY ./guiyu-oss-web/src/main/resources/logback.xml /home/work/logback-spring.xml

到這個時候為止,大部分問題都已經解決,但是進去到docker 容器裡面發現沒有 jmap等指令,需要通過如下命令去安裝即可

apk add openjdk8 

本著docker 鏡像最小原則,就沒有把它安裝到所有的docker鏡像中去。

到此公司的java包docker 鏡像構建完畢

Leave a Reply

Your email address will not be published. Required fields are marked *