跟我學SpringCloud | 第十八篇:微服務 Docker 化之基礎環境


1. 容器化

Docker 的橫空出世,給了容器技術帶來了質的飛躍,Docker 標准化了服務的基礎設施,統一了應用的打包分發,部署以及操作系統相關類庫等,解決了測試生產部署時環境差異的問題。對於運維來講,由於鏡像的不可變性,更容易進行服務部署和回滾操作。利用各種第三方容器管理平台,實現一鍵部署、動態伸縮等操作變的輕而易舉。

2. 基礎鏡像選擇

在操作系統的選擇上,可選擇傳統的 CentOS 、 Ubuntu 或者更為輕量化的 Alpine 。比如 CentOS 或者 Ubuntu 的鏡像都在 100MB 以上,壓縮后也都有大幾十 MB ,而輕量化的 Alpine 3.10 版本鏡像大小約為 5.58MB ,而它壓縮后更是僅有 2MB 大小左右。

Alpine 操作系統是一個面向安全的輕型 Linux 發行版。它不同於通常 Linux 發行版,Alpine 采用了 musl libc 和 busybox 以減小系統的體積和運行時資源消耗,但功能上比 busybox 又完善的多,因此得到開源社區越來越多的青睞。在保持瘦身的同時,Alpine 還提供了自己的包管理工具 apk 。

關於基礎鏡像的選擇,一個是考慮鏡像的大小,另一個是只提供最小的依賴包。關於第二點,不同的服務所需要的依賴包是不同的,這里不再展開討論,如果僅從第一點考慮的話, Alpine 肯定是首選,鏡像越小,遠程推拉越快,消耗的資源也越小,更為的方便,我們這里采用 Alpine 作為基礎鏡像。

3. Dockerfile 編寫

選擇 Alpine 有一個比較麻煩的地方是 Alpine 采用的是 musl libc 的 C 的標准庫,而 Oracle 或者 OpenJDK 提供的版本主要是已 glibc 為主。所以我們考慮為 Alpine 加上 glibc ,然后添加 glibc 的 JDK 編譯版本作為基礎鏡像。

3.1 Alpine + glibc

這里選擇的版本是目前最新版 Alpine 3.10 版本,glibc 采用的是 Sgerrand 開源的 glibc 安裝包(https://github.com/sgerrand/alpine-pkg-glibc/ ),版本為 2.30-r0 。具體代碼如下:

代碼清單:chapter17/dockerfiles/alpine-glibc/Dockerfile


FROM alpine:3.10
MAINTAINER inwsy@hotmail.com
RUN apk add --no-cache ca-certificates curl openssl binutils xz tzdata \
    && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && GLIBC_VER="2.30-r0" \
    && ALPINE_GLIBC_REPO="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \
    && curl -Ls ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-${GLIBC_VER}.apk > /opt/${GLIBC_VER}.apk \
    && apk add --allow-untrusted /opt/${GLIBC_VER}.apk \
    && curl -Ls https://www.archlinux.org/packages/core/x86_64/gcc-libs/download > /opt/gcc-libs.tar.xz \
    && mkdir /opt/gcc \
    && tar -xf /opt/gcc-libs.tar.xz -C /opt/gcc \
    && mv /opt/gcc/usr/lib/libgcc* /opt/gcc/usr/lib/libstdc++* /usr/glibc-compat/lib \
    && strip /usr/glibc-compat/lib/libgcc_s.so.* /usr/glibc-compat/lib/libstdc++.so* \
    && curl -Ls https://www.archlinux.org/packages/core/x86_64/zlib/download > /opt/libz.tar.xz \
    && mkdir /opt/libz \
    && tar -xf /opt/libz.tar.xz -C /opt/libz \
    && mv /opt/libz/usr/lib/libz.so* /usr/glibc-compat/lib \
    && apk del binutils \
    && rm -rf /opt/${GLIBC_VER}.apk /opt/gcc /opt/gcc-libs.tar.xz /opt/libz /opt/libz.tar.xz /var/cache/apk/*

這里有幾點需要注意的:

  • 由於 Docker 是分層設計,而在 Dockerfile 中,每一條指令都擁有自己的 context ,而執行到下一條指令時,則會將下一層的構建層疊加到上一層,因此在安裝類庫的時候最好將命令寫在同一個 RUN 指令中,減少分層,降低最后鏡像的大小
  • RUN 命令中安裝了類庫或者軟件包,需要在同一個命令中刪除 apk 的 cache ,這樣才能有效刪除 apk ,減小鏡像大小。
  • 基礎鏡像的標簽不要使用 latest ,當鏡像沒有指定標簽時,將默認使用 latest 標簽。當鏡像更新時, latest 標簽會指向不同的鏡像,這時構建鏡像有可能失敗。如果你的確需要使用最新版的基礎鏡像,可以使用 latest 標簽,否則的話,最好指定確定的鏡像標簽。
  • 這里筆者已經創建好了一個版本,上傳到阿里雲的鏡像倉庫上,有需要的讀者可以直接 pull 這個鏡像使用。
docker pull registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:glibc-2.30-r0

3.2 Alpine + glibc + JDK8

對於 JDK 的版本選擇,有 Oracle 的 Hotspot JDK ,也有 OpenJDK 。這里我們在構建 JDK8 的時候采用 Oracle 的 server-jre-8u221 版本。而對於 JDK9 、 JDK10 以及 JDK11 我們采用 OpenJDK 來進行構建。

Oracle 的 JDK8 的鏡像構建的 Dockerfile 如下:

代碼清單:chapter17/dockerfiles/java8/Dockerfile


FROM registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:glibc-2.30-r0
MAINTAINER inwsy@hotmail.com
ADD server-jre-8u221-linux-x64.tar.gz /opt/
RUN chmod +x /opt/jdk1.8.0_221
ENV JAVA_HOME=/opt/jdk1.8.0_221
ENV PATH="$JAVA_HOME/bin:${PATH}"

同樣,此鏡像作者已經上傳阿里雲鏡像倉庫,可以直接使用以下命令拉取:

docker pull registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:8u221-jre

可以進行驗證,命令如下:

docker run --rm -it registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:8u221-jre java -version

執行結果如下:

java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)

3.3 Alpine + glibc + OpenJDK9

OpenJDK9 的鏡像構建的 Dockerfile 如下:

代碼清單:chapter17/dockerfiles/java9/Dockerfile


FROM registry.cn-shanghai.aliyuncs.com/weishiyao/alpine-3.10:glibc-2.30-r0
MAINTAINER inwsy@hotmail.com

RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main\n\
https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community" > /etc/apk/repositories

RUN apk --update add curl bash openjdk9-jre && \
      rm -rf /var/cache/apk/*

ENV JAVA_HOME /usr/lib/jvm/default-jvm
ENV PATH ${PATH}:${JAVA_HOME}/bin

OpenJDK 的 jre 這里筆者使用清華大學鏡像站的鏡像進行安裝。

同樣,此鏡像作者已經上傳阿里雲鏡像倉庫,可以直接使用以下命令拉取:

docker pull registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk9-jre-9.0.4

驗證命令如下:

docker run --rm -it registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk9-jre-9.0.4 java -version

執行結果如下:

openjdk version "9.0.4"
OpenJDK Runtime Environment (build 9.0.4+12-alpine-r1)
OpenJDK 64-Bit Server VM (build 9.0.4+12-alpine-r1, mixed mode)

3.4 Alpine + glibc + OpenJDK10

OpenJDK10 的鏡像構建的 Dockerfile 如下:

代碼清單:chapter17/dockerfiles/java10/Dockerfile


FROM registry.cn-shanghai.aliyuncs.com/weishiyao/alpine-3.10:glibc-2.30-r0

RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main\n\
https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community" > /etc/apk/repositories

RUN apk --update add curl bash openjdk10-jre && \
      rm -rf /var/cache/apk/*

ENV JAVA_HOME /usr/lib/jvm/default-jvm
ENV PATH ${PATH}:${JAVA_HOME}/bin

同樣,此鏡像作者已經上傳阿里雲鏡像倉庫,可以直接使用以下命令拉取:

docker pull registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk10-jre-10.0.2

驗證命令如下:

docker run --rm -it registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk10-jre-10.0.2 java -version

執行結果如下:

openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-alpine-r0)
OpenJDK 64-Bit Server VM (build 10.0.2+13-alpine-r0, mixed mode)

3.5 Alpine + glibc + OpenJDK11

OpenJDK11 的鏡像構建的 Dockerfile 如下:

代碼清單:chapter17/dockerfiles/java11/Dockerfile


FROM registry.cn-shanghai.aliyuncs.com/weishiyao/alpine-3.10:glibc-2.30-r0
MAINTAINER inwsy@hotmail.com
RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main\n\
https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community" > /etc/apk/repositories

RUN apk --update add curl bash openjdk11-jre && \
      rm -rf /var/cache/apk/*

ENV JAVA_HOME /usr/lib/jvm/default-jvm
ENV PATH ${PATH}:${JAVA_HOME}/bin

同樣,此鏡像作者已經上傳阿里雲鏡像倉庫,可以直接使用以下命令拉取:

docker pull registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk11-jre-11.0.2

驗證命令如下:

docker run --rm -it registry.cn-shanghai.aliyuncs.com/springcloud-book/alpine3.10:openjdk11-jre-11.0.2 java -version

執行結果如下:

openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+4-alpine-r1)
OpenJDK 64-Bit Server VM (build 11.0.4+4-alpine-r1, mixed mode)

4. 實例代碼

示例代碼-Github

示例代碼-Gitee


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM