关于docker容器优雅退出的问题详解

 更新时间:2017年09月25日 11:20:05   作者:ionic  
在Docker大火的今天,我们能够非常方便的使用容器打包我们的应用程序,并且将它在我们的服务器上部署并运行起来。而下面这篇文章主要给大家介绍了关于docker容器如何优雅退出的问题,需要的朋友可以参考下。

前言

最近因为工作的原因,谈到了关于如何正确的退出运行中的docker容器,这是一个非常值得讨论的话题了。本文将给出详细的介绍,下面来一起看看吧。

容器信号使用

我们跑在容器中的程序通常想在容器退出之前做一些清理操作,比较常用的方式是监听一个信号,延迟关闭容器。

docker提供了这样的功能:

╰─➤ docker stop --help

Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop one or more running containers

Options:
 --help Print usage
 -t, --time int Seconds to wait for stop before killing it (default 10)

docker 1.13以上版本在创建容器时可直接指定STOP_TIMEOUT 和STOP_SIGNAL参数:

$ docker run --help
...
--stop-signal string   Signal to stop a container, SIGTERM by default (default "SIGTERM")
--stop-timeout int   Timeout (in seconds) to stop a container
...

但是。。。

我们测试一个:

package main

import (
 "fmt"
 "os"
 "os/signal"
 "syscall"
 "time"
)

func main() {
 fmt.Println("signal test")
 go func() {
 for {
  c := make(chan os.Signal, 1)
  signal.Notify(c, syscall.SIGTERM)
  s := <-c
  fmt.Println("Got signal:", s)
 }
 }()
 time.Sleep(time.Second * 100)
}

Dockerfile:

FROM golang:1.8.0
COPY main.go .
RUN go build -o signal && cp signal $GOPATH/bin
CMD signal 

构建:

docker build -t signal:latest .

运行:

docker run --name signal signal:latest

再开一终端,运行:

docker stop -t 10 signal

发现并没有打印出Got signal:... 监听信号失败。

问题再于:我们docker inspect signal看一下

可以看到

Path:/bin/sh
Args:[
 -c,
 signal
]

或者docker exec signal ps 看一下可以看到pid为1的进程并不是signal, 而是shell.

所以原因找到了,是因为docker engine只给pid为1的进程发送信号,sh收到了信号而我们想要的signal进程没有收到信号

解决办法:

FROM golang:1.8.0
COPY main.go .
RUN go build -o signal && cp signal $GOPATH/bin
CMD ["signal"] # 不能写成 CMD signal, 这会直接exec,否则会以shell的方式派生子进程。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • CentOS7使用docker部署Apollo配置中心的实现

    CentOS7使用docker部署Apollo配置中心的实现

    这篇文章主要介绍了CentOS7使用docker部署Apollo配置中心的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • docker容器化部署及使用方式

    docker容器化部署及使用方式

    这篇文章主要介绍了docker容器化部署及使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • docker-compose up -d和docker-compose up --build的区别

    docker-compose up -d和docker-compose up -

    本文主要介绍了docker-compose up -d和docker-compose up --build的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • docker-compose安装部署NebulaGraph图数据库的详细过程

    docker-compose安装部署NebulaGraph图数据库的详细过程

    NebulaGraph Studio是一款可以通过Web访问的开源图数据库可视化工具,搭配NebulaGraph内核使用,提供构图、数据导入、编写nGQL查询等一站式服务,这篇文章主要介绍了docker-compose安装部署NebulaGraph图数据库的详细过程,感兴趣的朋友一起看看吧
    2023-12-12
  • docker entrypoint入口文件详解

    docker entrypoint入口文件详解

    这篇文章主要介绍了docker entrypoint入口文件详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Docker ZooKeeper3.4.10集群安装配置过程

    Docker ZooKeeper3.4.10集群安装配置过程

    这篇文章主要介绍了ZooKeeper3.4.10集群安装配置-Docker,集群部署配置步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • 使用dockerfile构建nginx镜像的方法示例

    使用dockerfile构建nginx镜像的方法示例

    这篇文章主要介绍了使用dockerfile构建nginx镜像的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 一文教会你如何高效地搭建Docker私有仓库

    一文教会你如何高效地搭建Docker私有仓库

    Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署我们私有环境内的Registry也是非常必要的,这篇文章主要介绍了如何高效地搭建Docker私有仓库的相关资料,需要的朋友可以参考下
    2022-08-08
  • Docker运行hello-world镜像失败或超时的问题

    Docker运行hello-world镜像失败或超时的问题

    在安装Docker并尝试运行hello-world时,可能会遇到超时问题,这通常是由于默认的镜像源访问速度慢造成的,解决这个问题的办法是更换镜像源,虽然许多人推荐使用阿里云的镜像源,对Docker hello-world超时问题感兴趣的朋友一起看看吧
    2024-09-09
  • 详细记一次Docker部署服务的爬坑历程

    详细记一次Docker部署服务的爬坑历程

    这篇文章主要介绍了详细记一次Docker部署服务的爬坑历程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03

最新评论