当下,使用容器进行应用开发和部署已经是非常普遍的了。

在容器带来许多价值的同时,也带来了一些挑战,比如:

  • 更大的镜像意味着增加构建时间,同时也增加了开销
  • 镜像包含越多的库会增加漏洞扫描工具需要扫描的范围

等等。

这个问题最常见的解决方案是 - 使用更小的 Linux 发行版作为基础镜像

在开发人员中,使用像 Alpine 这样的轻量级发行版是一种非常常见的技术,可以避免使容器镜像过于庞大。但其底层库总是存在开放漏洞的风险。

谷歌通过引入 Distroless 镜像解决了这个问题。

Distroless 镜像只包含你的应用程序及其运行时依赖项。它们不包含包管理器、shell 或你希望在标准 Linux 发行版中找到的任何其他程序。

在阅读 Gaurav Agarwal 的关于 使用 Distroless 让你的容器更加安全 的故事后,我决定对它进行尝试和获得第一手的经验。

在本文中,我将分别使用 DistrolessAlpine 镜像创建一个 Java 应用程序容器,在它们上进行漏洞扫描,并比较构建时间、镜像大小等内容。

那就让我们开始吧。

使用 Distroless 镜像

我为这个实验创建了一个简单的 Hello World 的 Spring Boot 应用程序。

首先,我使用 Distroless 镜像创建了一个 Dockerfile,如下图所示:

FROM maven:3.5-jdk-8 AS build

COPY src /usr/src/app/src

COPY pom.xml /usr/src/app

RUN mvn -f /usr/src/app/pom.xml clean package

FROM gcr.io/distroless/java:8

ARG DEPENDENCY=/usr/src/app/target/dependency

COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib

COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF

COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","DemoApplication.Application"]

构建完成,如下图所示:

distroless-image-build

然后我用 Trivy 扫描了一下镜像,结果如下图所示:

distroless-image-scan-by-trivy

使用 Alpine 镜像

接下来,我使用 Alpine 镜像重复了这个实验。这个实验的 Dockerfile 如下所示:

FROM maven:3.5-jdk-8 AS build

COPY src /usr/src/app/src

COPY pom.xml /usr/src/app

RUN mvn -f /usr/src/app/pom.xml clean package

FROM openjdk:8-jre-alpine

ARG DEPENDENCY=/usr/src/app/target/dependency

COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib

COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF

COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","DemoApplication.Application"]

构建成功完成:

alpine-image-build

然后我对镜像进行了 Trivy 扫描,结果如下图:

alpine-image-scan-by-trivy

直接比较

基于这个实验,这是在我的环境中观察到的:

  • 镜像大小 - 使用 Alpine 作为基础镜像构建出的镜像大小是 93.5 MB,而 disroless 镜像是 139 MB。所以 Alpine 镜像比 disroless 镜像更加轻量。
  • 漏洞数量 - Alpine 镜像共有216个漏洞(未知:0,轻微:106,中等:79,严重:27,危急:4),反观 distroless 镜像共有 50 个漏洞(未知:0,轻微:30,中等:6,严重:9,危急:5)

总结

最后,如果你更关心安全性,那么肯定建议使用 Distroless 镜像。如果你担心镜像大小,那么 Alpine 可能是一个更好的选择。

实验代码

你可以在这里找到这个实验的完整代码:deshpandetanmay/distroless

原文链接

本文翻译自 Which Container Images To Use — Distroless Or Alpine?