• 容器关闭时(docker stop)处理自定义操作


    容器关闭时(docker stop)处理自定义操作
     
     
    前言
    现如今在开发、测试、生产运维等各个软件开发的环节中都少不了docker的部署,本文不再赘述docker相关介绍。
    在项目生产环境中,特别是用k8s结合微服务框架(如tars)来做服务治理、伸缩时,当容器被关闭的时候,需要告知主节点(Master)优雅的关闭该容器上的服务并下线该服务,而不能粗暴的终止程序/进程,这会导致生产环境上出现不可控的风险。
    本文主要目的就是提供一种在执行docker stop命令时,可以在容器内部监听到该命令并执行自定义操作的方法。
     
    工作原理
    1. 发送信号
    docker stop命令实际上是向容器内部发出了终止进程的信号SIGTERM。
    Linux信号这里简单介绍下,有助于理解整个过程。
    Linux系统利用信号与系统中的进程进行通信。Linux的常见信号有:
    信号
    描述
    1
    SIGHP
    挂起进程
    2
    SIGINT
    终止进程
    3
    SIGQUIT
    停止进程
    9
    SIGKILL
    无条件终止进程
    15
    SIGTERM
    尽可能终止进程
    17
    SIGSTOP
    无条件停止进程,但不是终止进程
    18
    SIGTSTP
    停止或暂停进程,但不终止进程
    19
    SIGCONT
    继续运行停止的进程
    我们在linux系统上最常用的命令Ctrl+C,实际就是产生SIGINT信号,强制终止进程。
     
    2. 捕捉信号
    docker stop命令实际是向容器中PID=1的进程发送了SIGTERM信号,告知容器它即将被关闭,我们要做的就是捕捉SIGTERM信号,并执行需要的相关停止服务、下线服务或其他操作。
     
     
    详细流程
    1. 创建PID=1的进程
    制作镜像的dockerfile中,有一个关键词ENTRYPOINT,是当容器启动时第一个执行的程序,并且该进程ID会被设定为1,所以以它执行的shell脚本才可以捕捉到上文提到的SIGTERM信号。
    下面是dockerfile实例:
    FROM tarscloud/tars-env-full 
    COPY entrypoint.sh /sbin/ 
    RUN chmod 755 /sbin/entrypoint.sh 
    ENTRYPOINT [ "/sbin/entrypoint.sh" ]
    

      

    可以看到,我们将entrypoint.sh脚本作为容器启动时PID=1的程序。
    下面我们将编写entrypoint.sh,在脚本中捕捉SIGTERM信号,
    entrypoint.sh 实例
    #!/bin/bash 
    # 在容器关闭前,优雅的关闭服务并下线服务
     function stop_server() {
         if [ -f "/usr/local/tars-auto/stop_tars_server.go" ]; then 
             echo "/usr/local/tars-auto/stop_tars_server.go exist, will run." 
             go run /usr/local/tars-auto/stop_tars_server.go 
             exit 
         else 
             echo "stop file not exist" 
             exit 
         fi 
    } 
    
    # 捕捉docker stop时发送的SIGTERM信号 
    trap 'stop_server' SIGTERM           
    

      

    trap 'stop_server' SIGTERM就是捕捉SIGTERM的代码,trap是shell脚本中专门用来捕捉信号的方法。
    第二个参数“stop_server”是指捕捉到信号后要执行的命令,
    可以看到stop_server函数中执行了一个stop_tars_server.go的脚本,当然可以根据其他需要进行替换。
     
    我们通过上面的dockerfile,启动了一个容器,
    执行
    docker exec -it tars-node bash
     
    进入容器内部,再执行top 1,查看当前所有进程,如下图:

     

    可以看到进程ID=1的程序是enterypoint的执行程序。
     
    2. 停止容器
    接来下我们执行docker stop
    docker stop tars-node
    

      

    执行后,查看容器日志:
    docker logs -f tars-node
    

      

    可以看到,enterypoint.sh脚本中stop_server函数的echo打印正确输出了:

     

    并且还打印输出了go脚本中的执行日志,也就是文章最开头提到的关闭服务、下线服务的内容。
    至此,我们成功做到了在执行docker stop后,让需要的自定义操作在容器关闭前执行。
     
     
     
     

  • 相关阅读:
    vux 局部注册组件
    vux 全局注册组件
    axios请求本地json
    vux报错 this指针问题
    Vue如何引入远程JS文件
    报错 ERROR in static/js/vendor.b3f56e9e0cd56988d890.js from UglifyJs
    封装axios
    js判断手机型号
    js判断是否在微信浏览器打开
    nginx+tomcat实现负载均衡以及session共享(linux centos7环境)
  • 原文地址:https://www.cnblogs.com/yourstars/p/15608764.html
Copyright © 2020-2023  润新知