1. 程式人生 > >跟我學SpringCloud | 第十八篇:微服務 Docker 化之基礎環境

跟我學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 [email protected]
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 [email protected]
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 [email protected]

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 [email protected]
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

示例程式碼-Gi