这是我参与「第五届青训营 」笔记创作活动的第11天,今天我学习了如何使用Docker部署服务。
为什么需要Docker
我们试想一个场景,应该也是大家非常熟悉的场景,作为一个开发人员,我们有一台Windows机器,然后我们需要将程序部署在Linux服务器上,服务器并不由我们开发人员维护,而是有专门的运维人员进行维护。我们开发的程序用了Java11,然而服务器上的Java版本是8,为了最大化利用服务器性能,这两个依赖不同java版本的服务可能需要部署在一台服务器上,这个问题也许我们可以通过指定jre来运行,那么依赖不同的gcc或者其他的系统组件的程序呢?解决成本一下子就高了,这也是为什么我们需要Docker。
Docker与虚拟机的区别
我觉得大部分同学第一次接触Docker的时候都有一个顾虑,都觉得Docker与VM这么类似,是不是也像VM一样臃肿,浪费服务器性能呢?其实Docker直接利用宿主机的系统内核,避免了虚拟机启动时所需要的系统引导时间和操作系统运行的资源消耗,可以说是非常的轻量级。但是,虚拟机的安全性比容器好一些,docker与宿主机共享内核、文件系统等资源,更有可能对其他容器、宿主机造成影响。
如何使用Docker部署Go服务
这里介绍两种
Golang镜像 + 源代码
FROM golang:alpine
WORKDIR $GOPATH/src/gin_docker
ADD . ./
ENV GO111MODULE=on
ENV GOPROXY="https://goproxy.io"
RUN go build -o gin .
EXPOSE 8080
ENTRYPOINT ["./gin"]
这是从Golang官方拉下来一个镜像,然后将源码文件复制进容器中进行编译并执行,属于最简单易用的,使用这种方式既可以作为Golang程序的开发,也能作为Golang程序的部署,但是缺点也非常明显,Golang具备交叉编译的能力,编译后生成的字节码也完全不依赖编译器,所以没有必要用带编译器的镜像作为base,徒增镜像大小。
交叉编译 + Linux系统镜像
# 设置 操作系统的类型
SET GOOS=linux
# 设置 cpu 架构
SET GOARCH=amd64
go build
首先编译好go程序,要指定好操作系统和架构,防止运行不成功。 然后再用基础的Linux镜像将程序复制进去执行就好了,这里有几点需要注意,由于目前的Go程序可能出现cgo交叉编译的情况,部分alpine系统可能无法运行,需要采用比较完整的系统包。