一、为什么要关注镜像大小

基础镜像体积:

[root@db01 ~]# docker images
REPOSITORY                                                   TAG       IMAGE ID       CREATED       SIZE
registry.cn-hangzhou.aliyuncs.com/github_images1024/centos   latest    5d0da3dc9764   3 years ago   231MB

编写Dockerfile

[root@db01 ~]# vim Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/github_images1024/centos:latest
MAINTAINER dot
RUN useradd dot

构建镜像

[root@db01 ~]# docker build --no-cache -t centos:latest .
Sending build context to Docker daemon  16.38kB
Step 1/3 : FROM registry.cn-hangzhou.aliyuncs.com/github_images1024/centos:latest
 ---> 5d0da3dc9764
Step 2/3 : MAINTAINER dot
 ---> Running in c7ae9ffb2800
Removing intermediate container c7ae9ffb2800
 ---> 6050b70e2860
Step 3/3 : RUN useradd dot
 ---> Running in 7607c5348e6a
Removing intermediate container 7607c5348e6a
 ---> cf87d75d03f2
Successfully built cf87d75d03f2
Successfully tagged centos:latest

使用docker history查看每一层的大小

[root@db01 ~]# docker history cf87d75d03f2
IMAGE          CREATED              CREATED BY                                      SIZE      COMMENT
cf87d75d03f2   About a minute ago   /bin/sh -c useradd dot                          297kB
6050b70e2860   About a minute ago   /bin/sh -c #(nop)  MAINTAINER dot               0B
5d0da3dc9764   3 years ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      3 years ago          /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>      3 years ago          /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0…   231MB

再次查看镜像大小

[root@db01 ~]# docker images | grep latest
centos                                                       latest    cf87d75d03f2   2 minutes ago   232MB

二、使用 Alpine 作为基础镜像

将之前创建用户的 Dockerfile 改为 Alpine 镜像

FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/alpine:3.12
MAINTAINER dot
RUN adduser -D dot

说明:Alpine 镜像创建用户的命令为 adduser,-D 表示不设置密码

执行构建并查看镜像大小:

docker build -t alpine:user .

查看镜像大小

[root@db01 ~]# docker images | grep user
alpine                                                       user      52ffd78307e0   33 seconds ago   5.59MB

三、多阶段构建

创建 Go 语言 Hello World 程序

vim hw.go

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

单阶段构建

# 编写Dockerfile文件
vim Dockerfile

FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/golang:1.14.4-alpine
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go
CMD "./hw"

# 构建
docker build -t hw:one .

# 查看单阶段构建的镜像大小,这里显示372MB
[root@db01 ~]# docker images | grep hw
hw                                                           one             d41c3f5686b4   About a minute ago   372MB

# 进入容器查看./hw大小
[root@db01 ~]# docker run --rm hw:one du -sh ./hw
2.0M    ./hw

多阶段 Dockerfile 构建

# 编写Dockerfile文件
vim Dockerfile

FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/golang:1.14.4-alpine
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go
FROM scratch
COPY --from=builder /opt/hw .

# 再次构建镜像
docker build -t hw:multi .

# 查看镜像大小,大小变为2M多
docker images |grep multi

# 启动容器
docker run --rm hw:multi
Hello World!