上期的文章:Kubernetes入门实践--部署运行Go项目发布后,有网友留言说我文章里演示的镜像是把项目文件和Go都打包到了镜像里,这样镜像的占用空间会比较大。linux
Go
开发的程序在编译成二进制文件后是能够在没有安装Go
环境的系统里执行的,若是只把编译完的二进制文件直接放到镜像里就能节省不少镜像空间了。我给的回复是文章的侧重点是Kubernetes
的实践因此镜像方面就没有占太多篇幅。golang
确实真实线上项目的应用镜像通常都不像以前文章里讲那样构建,由于生产项目各方面要求更严格些。镜像构建的过程通常都是先用Docker
容器把项目编译成二进制文件,而后把编译好的文件拷贝到一个新的容器镜像里,新镜像里通常只包含Linux
系统运行须要的最基本的文件,不须要有Go
环境,所以能减小不少占用空间。整个这个过程都发生在镜像构建的过程当中,这样就能保证多环境的一致性,上面这个构建Docker
镜像的方式叫作多阶段构建(multi stage build
)。docker
多阶段构建是17.05
版本才有的功能,因此使用前要先肯定下使用的Docker Engine
的版本。bash
下面就来介绍一下怎么使用Docker
的多阶段构建制做Go
应用的镜像。app
以前文章里镜像的Dockerfile
长这样:工具
FROM golang:1.14-alpine
RUN mkdir /app COPY . /app WORKDIR /app RUN go build -o main . CMD ["/app/main"] 复制代码
咱们使用用多阶段构建的方式构建镜像后,Dockerfile
会变成相似下面这样:ui
FROM golang:alpine AS build
RUN mkdir /app COPY . /app WORKDIR /app RUN CGO_ENABLED=0 GOOS=linux go build -o myapp
###
FROM scratch as final
COPY --from=build /app/myapp . CMD ["/myapp"] 复制代码
Go
项目应用的Dockerfile
一般大概相似这样,可是每一个项目的细节可能有所不一样。FROM golang:alpine
指定了开始阶段的基础映像(其中包含Go工具和库,用于构建程序),AS build
是给这个阶段取名为build
。spa
golang:alpine
指定了Go
基础映像的alpine
版本, alpine
是专门为容器设计的小型Linux
发行版。这个Dockerfile
中使用了两次FROM
指令,第二条FROM scratch
行,它告诉Docker
从一个全新的,彻底空的容器镜像从新开始,而后将上个阶段编译好的程序复制到其中。这个才是咱们随后将用于运行的Go
应用程序的容器镜像。设计
scratch
镜像是Docker
项目预约义的最小的镜像。 Docker
用于Go
程序的多阶段构建很常见,使用scratch
镜像能够节省大量空间,由于咱们实际上不须要Go
工具或其余任何东西来运行咱们的编译好的程序,这可能也是Go
在容器时代的一个优点吧。code
使用scratch
镜像制做的Go
应用镜像在运行时会有一个不识别时区的问题,这个也是咱们最近项目往Kubernetes
上迁移时遇到的第一个问题,不过还好通过Google
和查看Go
加载时区的源码找到了解决方法,具体怎么解决的下期的文章再告诉你们。