小型容器建造艺术
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
在本文中,我们将通过详细了解构建器模式和多阶段构建来学习如何构建小型 Docker 容器,并探讨它们带来的好处。
剧透一下,我们将把 golang 容器的大小从超过 1000 减少850mb到略低于 10 12mb...
我还制作了一个视频,如果您想跟着做的话。视频中的幻灯片可以在这里找到。
问题
Docker 镜像通常比实际需要的要大得多,这最终会影响我们的部署、安全性和开发体验。
优化构建过程可能很复杂,因为很难保持镜像的干净,最终会变得混乱不堪,难以理解。
我们最终还会将一些不必要的资源(例如工具、开发依赖项、运行时或编译器)包含在发布版本中。
假设我们有一个简单的 Go 语言 Hello World 程序,现在我们想把它容器化并部署到 Kubernetes 上。
这是我们非常简单的 Hello World 项目。
├── Dockerfile
└── main.go
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", helloHandler)
http.ListenAndServe(":8080", nil)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
以及我们的Dockerfile
FROM golang:1.16.5
WORKDIR /app
COPY main.go .
RUN go build main.go
CMD ./main
$ docker build -t default .
$ docker images
default latest afac261974d0 32 seconds ago 868MB
哇,为什么我们的“Hello World”图片超过850MB!
解决方案
让我们来看看一些减小图像尺寸的可能解决方案。
较小的基础图像
一个简单的解决方案是在构建容器时使用较小的基础镜像。
例子
GO
1.16.5 862MB
1.16.5-alpine 302MB <---
Node
16 907MB
16-slim 176MB
16-alpine 112MB <---
为此,我们可以更新FROM我们声明中的数据。Dockerfile
FROM golang:1.16-alpine
具有多阶段构建的构建器模式
构建器模式简单来说就是将构建 Docker 容器的过程拆分成两个或多个阶段,以减少生产镜像中任何不必要的资源。
第一张图是构建器图像,它利用所有必要的构建工具来构建我们的代码。
第二张图片是我们的运行时或发布镜像,我们将把构建好的二进制文件复制到其中并进行部署,因此体积减小了!
多阶段构建允许我们在单个 Dockerfile 中定义所有阶段,而无需像以前那样将其拆分成多个 Dockerfile。
它在我们的生活中是如何体现的呢?Dockerfile
FROM golang:1.16.5 as builder
WORKDIR /app
COPY main.go .
RUN go build main.go
FROM alpine as production
COPY --from=builder /app/main .
EXPOSE 8080
CMD ./main
$ docker build -t multistage .
$ docker images
multistage latest iucs2934758r 18 seconds ago 12.5MB
注:我们还可以使用scratch我最近最喜欢的distrolessGoogle 容器。
TLDR
- 从包含完整运行时或 SDK 的基础镜像派生而来
- 复制我们的源代码
- 安装依赖项
- 生成构建工件
- 将构建好的工件复制到更小的发布镜像中。
好处
以下是我们建造小型集装箱的优势。
表现
构建和部署小型 Docker 容器的一些好处包括:
- 更快地从容器注册表推送和拉取容器
- 小型优化版本
成本效益高
现在,我们只需原镜像所需成本和空间的一小部分,就能推送新的 Docker 镜像。
以下是我一位客户在 Kubernetes 上运行大约 18 个微服务时的一个有趣示例。
默认
18 microservices x ~800mb x 5 deploys cycles month x 12 months
~864GB/year
优化
18 microservices x ~25mb x 5 deploys cycles month x 12 months
~27GB/year
安全
安全性是任何应用程序的重要组成部分,尤其是在医疗保健、金融等高度监管的行业中更是如此。
更小的图像可以大幅减少漏洞攻击面,以下是来自 AWS ECR 的快速扫描结果。
下一步
现在我们可以快速高效地在 Kubernetes/OpenShift 上部署我们的小型 Docker 容器。
如有任何疑问,欢迎随时在推特上联系我。
文章来源:https://dev.to/karanpratapsingh/art-of-building-small-containers-3g6c


