容器關閉時(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后,讓需要的自定義操作在容器關閉前執行。
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM