尝试使用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中确定,所以不清楚是哪一个。