docker容器如何优雅的终止详解

2020-06-17 06:38:03易采站长站整理

//Do something...
}
fmt.Println("Exiting...")
}

接下来使用交叉编译的方式来编译程序,让程序可以在Linux下运行:


CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o graceful

编译好之后,我们还需要打包程序到容器中运行。于是,我们还得有个Dockerfile。在这里,我们选择使用体积小又轻盈的alpine镜像作为基础镜像,打包这个Go程序:


from alpine:latest
MAINTAINER Timothy
ADD graceful /graceful
CMD ["/graceful"]

这里需要避开的一个坑,是Dockerfile中CMD命令的用法。

CMD命令有两种方式:


CMD /graceful

使用

CMD command param1 param2 
这种方式,其实是以shell的方式运行程序。最终程序被执行时,类似于/bin/sh -c的方式运行了我们的程序,这样会导致/bin/sh以PID为1的进程运行,而我们的程序只不过是它fork/execs出来的子进程而已。前面我们提到过docker stop的SIGTERM信号只是发送给容器中PID为1的进程,而这样,我们的程序就没法接收和处理到信号了。


CMD [“/graceful”]

使用

CMD [“executable”,”param1”,”param2”] 
这种方式启动程序,才是我们想要的,这种方式执行和启动时,我们的程序会被直接启动执行,而不是以shell的方式,这样我们的程序就能以
PID=1
的方式开始执行了。

话题转回来,我们开始执行容器构建操作,打包程序:


docker build -t registry.xiaozhou.net/graceful:latest .

打包过后的镜像,才6MB左右:


λ Timothy [workspace/src/graceful] → docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.xiaozhou.net/graceful latest b2210a85ca55 20 hours ago 6.484 MB

启动并运行容器:


λ Timothy [workspace/src/graceful] → docker run -d --name graceful b2210a85

查看容器运行状态:


λ Timothy [workspace/src/graceful] → docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd18eedafd16 b221 "/graceful" 3 seconds ago Up 2 seconds graceful

查看容器输出,能看到程序已经正常启动:


λ Timothy [workspace/src/graceful] → docker logs graceful
Started...

接着我们要使用

docker stop