发布于 2026-01-06 5 阅读
0

构建小型容器的艺术 DEV 全球展示与分享挑战赛,由 Mux 呈现:展示你的项目!

小型容器建造艺术

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

在本文中,我们将通过详细了解构建器模式和多阶段构建来学习如何构建小型 Docker 容器,并探讨它们带来的好处。

剧透一下,我们将把 golang 容器的大小从超过 1000 减少850mb到略低于 10 12mb...

我还制作了一个视频,如果您想跟着做的话。视频中的幻灯片可以在这里找到。

问题

Docker 镜像通常比实际需要的要大得多,这最终会影响我们的部署、安全性和开发体验。

优化构建过程可能很复杂,因为很难保持镜像的干净,最终会变得混乱不堪,难以理解。

我们最终还会将一些不必要的资源(例如工具、开发依赖项、运行时或编译器)包含在发布版本中。

假设我们有一个简单的 Go 语言 Hello World 程序,现在我们想把它容器化并部署到 Kubernetes 上。

这是我们非常简单的 Hello World 项目。

├── Dockerfile
└── main.go
Enter fullscreen mode Exit fullscreen mode
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!")
}
Enter fullscreen mode Exit fullscreen mode

以及我们的Dockerfile

FROM golang:1.16.5
WORKDIR /app
COPY main.go .
RUN go build main.go
CMD ./main
Enter fullscreen mode Exit fullscreen mode
$ docker build -t default .
$ docker images

default     latest    afac261974d0   32 seconds ago     868MB
Enter fullscreen mode Exit fullscreen mode

哇,为什么我们的“Hello World”图片超过850MB!

梗图

解决方案

让我们来看看一些减小图像尺寸的可能解决方案。

较小的基础图像

一个简单的解决方案是在构建容器时使用较小的基础镜像。

例子

GO

1.16.5              862MB
1.16.5-alpine       302MB  <---

Node

16                  907MB
16-slim             176MB
16-alpine           112MB  <---
Enter fullscreen mode Exit fullscreen mode

为此,我们可以更新FROM我们声明中的数据。Dockerfile

FROM golang:1.16-alpine
Enter fullscreen mode Exit fullscreen mode

具有多阶段构建的构建器模式

构建器模式

构建器模式简单来说就是将构建 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
Enter fullscreen mode Exit fullscreen mode
$ docker build -t multistage .
$ docker images

multistage     latest    iucs2934758r   18 seconds ago     12.5MB
Enter fullscreen mode Exit fullscreen mode

注:我们还可以使用scratch我最近最喜欢的distrolessGoogle 容器。

TLDR

  • 从包含完整运行时或 SDK 的基础镜像派生而来
  • 复制我们的源代码
  • 安装依赖项
  • 生成构建工件
  • 将构建好的工件复制到更小的发布镜像中。

好处

以下是我们建造小型集装箱的优势。

表现

构建和部署小型 Docker 容器的一些好处包括:

  • 更快地从容器注册表推送和拉取容器
  • 小型优化版本

成本效益高

现在,我们只需原镜像所需成本和空间的一小部分,就能推送新的 Docker 镜像。

以下是我一位客户在 Kubernetes 上运行大约 18 个微服务时的一个有趣示例。

默认

18 microservices x ~800mb x 5 deploys cycles month x 12 months

~864GB/year
Enter fullscreen mode Exit fullscreen mode

优化

18 microservices x ~25mb x 5 deploys cycles month x 12 months

~27GB/year
Enter fullscreen mode Exit fullscreen mode

安全

安全性是任何应用程序的重要组成部分,尤其是在医疗保健、金融等高度监管的行业中更是如此。

更小的图像可以大幅减少漏洞攻击面,以下是来自 AWS ECR 的快速扫描结果。

扫描结果

下一步

现在我们可以快速高效地在 Kubernetes/OpenShift 上部署我们的小型 Docker 容器。

如有任何疑问,欢迎随时在推特上联系我。

文章来源:https://dev.to/karanpratapsingh/art-of-building-small-containers-3g6c