小容器挑战:将一个HTTP服务器Dcoker从943M压缩到6k! | devopsdirective


本文展示如何将Node.js的Image大小从最初的943MB缩小到6.34kB Assembly Image的过程,并了解了一些可用于将来缩小容器镜像的技术。
Docker具有称为多阶段构建的功能,可轻松在具有所有必要依赖项的环境中构建代码,然后将生成的可执行文件复制到其他Image中。出于多种原因,这很有用,但是最明显的原因之一是Image大小!通过如下方式重构dockerfile:

### build stage ###
FROM golang:1.14-alpine AS builder
COPY . .
RUN go build -o server .

### run stage ###
FROM alpine:3.12
COPY --from=builder /go/server ./server
COPY index.html index.html
CMD ["./server"]

Image结果就是13.2MB!
 
静态编译+Scratch image
13 MB还算不错,但是我们仍然可以使用一些技巧来使它变得更小。
有一个称为scratch的基本Image,其内容为空且大小为零。因为scratch里面没有任何内容,所以使用它构建的任何Image都必须带有所有必需的依赖项。
为了使基于go的服务器能够做到这一点,我们需要在编译步骤中添加一些标志,以确保将必要的库静态链接到可执行文件中:

### build stage ###
FROM golang:1.14 as builder
COPY . .
RUN go build \
  -ldflags "-linkmode external -extldflags -static" \
  -a server.go

### run stage ###
FROM scratch
COPY --from=builder /go/server ./server
COPY index.html index.html
CMD [
"./server"]

具体来说,我们将链接模式设置为external,并将-static标志传递给外部链接器。
这两个更改使Image大小达到8.65MB
 
ASM赢!
用Go之类的语言编写的小于10MB的图像几乎在任何情况下都足够小...但是我们可以缩小尺寸!Github用户nemasu在github上以汇编形式编写的全功能http服务器,名为assmttpd
对其进行容器化所需要做的就是在运行提供的make release配方之前将一些构建依赖项安装到ubuntu基础Image中:

### build stage ###
FROM ubuntu:18.04 as builder
RUN apt update
RUN apt install -y make yasm as31 nasm binutils 
COPY . .
RUN make release

### run stage ###
FROM scratch
COPY --from=builder /asmttpd /asmttpd
COPY /web_root/index.html /web_root/index.html
CMD ["/asmttpd", "/web_root", "8080"

asmttpd然后将生成的可执行文件复制到 scratch image中,并使用调用CMD。这样产生的图像大小仅为6.34kB!
点击标题