尝试使用distroless镜像创建一个运行时的Docker镜像

distroless是什么?

这是由Google公开提供的、用于运行时的Docker镜像。

为什么要使用它?

Docker 现在也被引入到生产环境中。

在生产环境中,需要进行漏洞修复等安全性处理。
通过限制部署的Docker镜像仅限于应用程序运行所需的内容,可以减少此类间接性操作。

distroless镜像是一种特化于应用程序运行时的Docker镜像,它满足了您提出的需求。

如果使用gcr.io/distroless/base,实际上是在内部映像中。

    • glibc

 

    • libssl

 

    • openssl

 

    • ca-certificates

 

    • A /etc/passwd entry for a root user

 

    A /tmp directory

只需要一种选项。

上述的 nodejs 图像中似乎包含了每个运行时所需的二进制文件等内容的附加项。

试一试

使用distroless镜像创建一个运行时镜像。

我用Node.js尝试了一下这个示例,参考自https://github.com/GoogleContainerTools/distroless。

存储着如下所示的 Dockerfile。

FROM node:8.9.1 AS build-env
ADD . /app
WORKDIR /app

FROM gcr.io/distroless/nodejs
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.js"]

这段代码被分成了两个阶段:构建阶段(前三行)和将输出拷贝到distroless镜像的阶段(后四行)。

※这个描述是关于多阶段构建,而不是Distroless镜像的讨论,我的理解是,“不将只在应用程序构建时所需的依赖包包含在最终镜像中”。

用这个Dockerfile,尝试构建一个基于distroless镜像的Docker镜像。

$ docker build . -t nodejs_distroless                                                                                  水  7/18 22:09:30 2018
Sending build context to Docker daemon  7.168kB
Step 1/7 : FROM node:8.9.1 AS build-env
8.9.1: Pulling from library/node
85b1f47fba49: Pull complete
ba6bd283713a: Pull complete
817c8cd48a09: Pull complete
47cc0ed96dc3: Pull complete
8888adcbd08b: Pull complete
6f2de60646b9: Pull complete
51fa8867e10f: Pull complete
3de546fb9d8f: Pull complete
Digest: sha256:552348163f074034ae75643c01e0ba301af936a898d778bb4fc16062917d0430
Status: Downloaded newer image for node:8.9.1
 ---> 1934b0b038d1
Step 2/7 : ADD . /app
 ---> edaf827024d3
Step 3/7 : WORKDIR /app
Removing intermediate container 1712ca1226a1
 ---> 26d537ccf985
Step 4/7 : FROM gcr.io/distroless/nodejs
latest: Pulling from distroless/nodejs
57752e7f9593: Pull complete
ba7c544469e5: Pull complete
fe1a8dd285c0: Pull complete
Digest: sha256:ed997b713028c133799c41c2401e5d77ba1973876e92c55d1d67b6a0b68e9c29
Status: Downloaded newer image for gcr.io/distroless/nodejs:latest
 ---> a853ae078c7b
Step 5/7 : COPY --from=build-env /app /app
 ---> b3c68eb49cc5
Step 6/7 : WORKDIR /app
Removing intermediate container 79aa5baa396d
 ---> b6f4f9fd66d3
Step 7/7 : CMD ["hello.js"]
 ---> Running in 4dfbc310729f
Removing intermediate container 4dfbc310729f
 ---> ccb158736e44
Successfully built ccb158736e44
Successfully tagged nodejs_distroless:latest

实际情况怎样?

图像尺寸

使用Docker映像节点进行构建的结果进行比较。

ベースのイメージイメージサイズnode:8.9.1676MBnode:8.9.1-alpine67.7MBgcr.io/distroless/nodejs:latest75.1MB

总的来说,尽管alpine的容量较少,但差别并不大,几乎达到了相同的水平。

我试图登录

$ docker run --rm -it --entrypoint /bin/bash nodejs_distroless 
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown.
$ docker run --rm -it --entrypoint /bin/sh nodejs_distroless 
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.

做不到了。

总结

开始时我打算将标题命名为“最小的运行时”,
但是 nodejs 的大小比 alpine 要大笑了
(应该试试用 Golang)

目前的状况已经公开了以下的图像。

    • gcr.io/distroless/base (Golangなどバイナリでコンパイルされたものの実行環境)

 

    • gcr.io/distroless/java (openjdk8ベース)

 

    • gcr.io/distroless/cc (Rust, D言語用)

 

    • gcr.io/distroless/python2.7

 

    • gcr.io/distroless/python3

 

    • gcr.io/distroless/nodejs

 

    • gcr.io/distroless/java/jetty

 

    gcr.io/distroless/dotnet

其中除了base之外,其他的还似乎是处于生产就绪状态。
※至于Java和CC方面的情况,因为无法从Git仓库的Readme中确定,所以不清楚是哪一个。

广告
将在 10 秒后关闭
bannerAds