在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何優雅地關閉容器

馬哥Linux運維 ? 來源:opskumu.com ? 2023-02-01 09:21 ? 次閱讀

最近把 Docker 官方的 Docker Reference 文檔又讀了一遍,發現有些細節深究起來,還是有很多可挖的。針對寫 Dockerfile ,大部分時候只要照葫蘆畫瓢,基本也不會有什么大的問題,但是如果再深入理解一下那就更有意思了。

要說如何優雅的關閉容器,那就不得不提到信號(Signal)的理念,以及 Dockerfile 中 ENTRYPOINT 和 CMD 指令了。在具體說優雅關閉之前,先了解一下信號這個 Linux 中的基礎概念。

1 信號

信號是事件發生時對進程的通知機制,有時也稱之為軟件中斷。

信號有不同的類型,Linux 對標準信號的編號為 1~31,可以通過 kill -l 獲取信號名稱:

#kill-l
1)SIGHUP2)SIGINT3)SIGQUIT
4)SIGILL5)SIGTRAP6)SIGABRT
7)SIGBUS8)SIGFPE9)SIGKILL
10)SIGUSR111)SIGSEGV12)SIGUSR2
13)SIGPIPE14)SIGALRM15)SIGTERM
......

實際列出的信號超過了 31 個,有些是其它名稱的同義詞,有些則是定義但未使用的。以下介紹幾個常用的信號:

SIGHUP 當終端斷開(掛機)時,將發送該信號給終端控制進程。SIGHUP 信號還可用于守護進程(比如,init 等)。許多守護進程會在收到 SIGHUP 信號時重新進行初始化并重讀配置文件。

SIGINT 當用戶鍵入終端中斷字符(通常為 Control-C ) 時,終端驅動程序將發送該信號給前臺進程組。該信號的默認行為是終止進程。

SIGQUIT 當用戶在鍵盤上鍵入退出字符(通常為 Control- )時,該信號將發往前臺進程組。默認情況下,該信號終止進程,并生成用于調試的核心轉儲文件。進程如果陷入無限循環,或者不再響應時,使用 SIGQUIT 信號就很合適。

SIGKILL 此信號為 “必殺(sure kill)” 信號,處理器程序無法將其阻塞、忽略或者捕獲,故而 “一擊必殺”,總能終止程序。

SIGTERM 這是用來終止進程的標準信號,也是 kill 、 killall 、 pkill 命令所發送的默認信號。精心設計的應用程序應當為 SIGTERM 信號設置處理器程序,以便其能夠預先清除臨時文件和釋放其它資源,從而全身而退。因此,總是應該先嘗試使用 SIGTERM 信號來終止進程,而把 SIGKILL 作為最后手段,去對付那些不響應 SIGTERM 信號的失控進程。

SIGTSTP 這是作業控制的停止信號,當用戶在鍵盤上輸入掛起字符(通常為 Control-Z )時,將該信號給前臺進程組,使其停止運行。

值得注意的是, Control-D 不會發起信號,它表示 EOF(End-Of-File),關閉標準輸入(stdin)管道(比如可以通過 Control-D 退出當前 shell)。如果程序不讀取當前輸入的話,是不受 Control-D 影響的。

程序可以針對信號捕捉,然后執行相應函數:

7234d2c0-a1b2-11ed-bfe3-dac502259ad0.png

以上知識大部分都來自 《Linux/UNIX 系統編程手冊》,想要了解更多的,可以查看該書上冊的 20、21、22 章節。

2 ENTRYPOINT 、 CMD

可能有人會問,說了半天,那信號和優雅的關閉容器有半毛錢的關系啊?話說,這和錢確實沒關系,但是和如何優雅關閉容器卻關系密切。

接著說 Dockerfile 中的 ENTRYPOINT 和 CMD 指令,它們的主要功能是指定容器啟動時執行的程序。

CMD 有三種格式:

CMD ["executable","param1","param2"] (exec 格式, 推薦使用這種格式)

CMD ["param1","param2"] (作為 ENTRYPOINT 指令參數

CMD command param1 param2 (shell 格式,默認 /bin/sh -c )

ENTRYPOINT 有兩種格式:

ENTRYPOINT ["executable", "param1", "param2"] (exec 格式,推薦優先使用這種格式)

ENTRYPOINT command param1 param2 (shell 格式)

其中,不管你 Dockerfile 用其中哪個指令,兩個指令都推薦使用 exec 格式,而不是 shell 格式。原因就是因為使用 shell 格式之后,程序會以 /bin/sh -c 的子命令啟動,并且 shell 格式下不會傳遞任何信號給程序。這也就導致,在 docker stop 容器的時候,以這種格式運行的程序捕捉不到發送的信號,也就談不上優雅的關閉了。

?~dockerstop--help

Usage:dockerstop[OPTIONS]CONTAINER[CONTAINER...]

Stoponeormorerunningcontainers

Options:
--helpPrintusage
-t,--timeintSecondstowaitforstopbeforekillingit(default10)

docker stop 停掉容器的時候,默認會發送一個 SIGTERM 的信號,默認 10s 后容器沒有停止的話,就 SIGKILL 強制停止容器。通過 -t 選項可以設置等待時間。

?~dockerkill--help

Usage:dockerkill[OPTIONS]CONTAINER[CONTAINER...]

Killoneormorerunningcontainers

Options:
--helpPrintusage
-s,--signalstringSignaltosendtothecontainer(default"KILL")

通過 docker kill的-s選項還可以指定給容器發送的信號。

所以,說了那么多,只要 Dockerfile 中通過 exec 格式執行容器啟動命令就相安無事了?那當然是,沒有那么簡單的了,接下來我們通過實例來看看具體的效果是怎么樣的。

3 實例

通過 Go 寫一個簡單的信號處理器:

?~catsignals.go
packagemain

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

funcmain(){
sigs:=make(chanos.Signal,1)
done:=make(chanbool,1)

signal.Notify(sigs,syscall.SIGINT,syscall.SIGTERM)

gofunc(){
sig:=<-sigs
????????fmt.Println()
????????fmt.Println(sig)
????????done?<-?true
????}()

????fmt.Println("awaiting?signal")
????<-done
????fmt.Println("exiting")
}

3.1 實例 1

?~GOOS=linuxGOARCH=amd64gobuildsignals.go
?~ls
Dockerfilesignalssignals.go
?~catDockerfile
FROMbusybox

COPYsignals/signals

CMD["/signals"]#exec格式執行
?~dockerbuild-tsignals.

通過 tmux 開啟兩個面板,一個運行容器,一個執行 docker stop :

?~dockerrun-it--rm--namesignalssignals
awaitingsignal

terminated
exiting
?~timedockerstopsignals
signals
dockerstopsignals0.01suser0.02ssystem4%cpu0.732total
?~

可以發現,容器停止之前,程序接收到信號并輸出相應信息,并且停止總耗時為 0.732 s,達到了優雅的效果。

修改 Dockerfile 中 CMD 執行格式,執行相同操作:

?~catDockerfile
FROMbusybox

COPYsignals/signals

CMD/signals#shell格式執行
?~dockerbuild-tsignals.
?~dockerrun-it--rm--namesignalssignals
awaitingsignal
?~
?~timedockerstopsignals
signals
dockerstopsignals0.01suser0.01ssystem0%cpu10.719total

通過 shell 格式之后,可以發現容器停止之前,程序并未接收到任何信號,并且停止時間為 10.719s,說明該容器是被強制停止的。

結論很明顯,為了優雅的退出容器,我們應該采用 exec 這種格式。

3.2 實例 2

通過實例 1 我們都會在 Dockerfile 中都會通過 exec 這種格式來執行程序了,那如果執行的程序本身也是一個 shell 腳本呢?

?~ls
Dockerfilesignalssignals.gostart.sh
?~catDockerfile
FROMbusybox

COPYsignals/signals
COPYstart.sh/start.sh#引入shell腳本啟動

CMD["/start.sh"]
?~catstart.sh
#!/bin/sh

/signals
?~

測試依然引用實例 1 中的方法:

?~dockerrun-it--rm--namesignalssignals
awaitingsignal
?~
?~timedockerstopsignals
signals
dockerstopsignals0.01suser0.02ssystem0%cpu10.765total
?~

可以發現,即使 Dockerfile 中的 CMD 指令使用的是 exec 格式,容器中的程序依然沒有接收到信號,最后被強制關閉。因為 shell 腳本中執行的原因,導致信號依然沒有被傳遞,我們需要針對 shell 腳本做一些改造:

?~catstart.sh
#!/bin/sh

exec/signals#加入exec執行
?~dockerbuild-tsignals.
?~dockerrun-it--rm--namesignalssignals
awaitingsignal

terminated
exiting
?~timedockerstopsignals
signals
dockerstopsignals0.02suser0.02ssystem4%cpu0.744total
?~

可以看到,加入 exec 命令之后,程序又可以接收到信號正常退出了。當然,如果你 Dockerfile 中的 CMD 是以 shell 格式運行的,即使啟動腳本中加入 exec 也是無效的。再者,如果你的程序本身不能針對信號做一些處理,也就談不上優雅關閉了。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11326

    瀏覽量

    209961
  • 信號
    +關注

    關注

    11

    文章

    2797

    瀏覽量

    76939
  • 容器
    +關注

    關注

    0

    文章

    498

    瀏覽量

    22086
  • 命令
    +關注

    關注

    5

    文章

    692

    瀏覽量

    22063
  • Docker
    +關注

    關注

    0

    文章

    489

    瀏覽量

    11887

原文標題:如何優雅地關閉容器

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    200.200 尚硅谷 SparkStreaming 優雅關閉 恢復數據

    數據庫
    充八萬
    發布于 :2023年07月18日 09:25:47

    神舟優雅U10R上網本 參考價格:2499元

    推薦產品:神舟優雅U10R上網本  參考價格:2499元神舟 優雅U10R神舟 優雅U10R僅重1.15kg 輕盈生活隨處可得   優雅U10R采用10.1寸超輕薄靚麗LED
    發表于 07-01 22:30

    熱門低價3G上網本推薦 神舟優雅U20Y 參考售價:2399元

    獲得了補貼,含上網自費套餐的3G上網本價格上并不比沒有3G功能的上網本高。因此在有補貼的情況,今年購買還是比較劃算的。下面我們就一起看看具體的情況。  神舟優雅U20Y  參考售價:2399元(不含
    發表于 07-02 09:03

    Spark Streaming的offset管理和關閉策略

    Spark Streaming優雅關閉策略優化
    發表于 04-22 14:59

    如何優雅地完成倒計時定時器自適應顯示呢

    如何實現倒計時的基本功能呢?如何優雅地完成倒計時定時器自適應顯示呢?
    發表于 10-27 07:15

    磁通電容器的資料分享

    更多的絲印藝術。再次感謝 pcb 方式,一塊板已完全組裝,我編寫了代碼讓燈閃爍以模仿通量電容器動畫。該按鈕目前沒有做任何事情,但我打算用它來打開和關閉 LED,或者啟用其他類型的動畫。 LED 在日光下非常明亮,并具有溫暖的黃色/橙色。PCB
    發表于 07-13 07:50

    利用golang優雅的實現單實例分享

    1、利用golang優雅的實現單實例平時編寫代碼過程中,經常會遇到對于全局角度只需運行一次的代碼,比如全局初始化操作,設計模式中的單例模式。針對單例模式,java中又出現了餓漢模式、懶漢模式,再配
    發表于 10-17 16:46

    經驗分享|BI數據可視化報表布局——容器

    設置。2、放大容器點擊右側的【專有】,將看到一個【允許放大容器】的開關。這是一個什么功能?關閉該開關,表示可以放大容器以及容器內的圖表;開啟
    發表于 03-15 17:10

    如何通過ESP模塊打開/關閉樹莓派GPIO電路?

    如何通過ESP模塊打開/關閉樹莓派GPIO電路?樹莓派作為優雅的電源開/關功能。您只需關閉 Pi Pin 5 (BCM 3) GPIO 到 GND。只要您在 Pi OS 中完成了一些軟件配置,這就
    發表于 05-15 06:13

    華為nfc怎么關閉

    華為手機的NFC功能默認的是開啟,如果不喜歡,可以選擇關閉。華為nfc關閉的步驟的如下:
    的頭像 發表于 02-28 14:02 ?6.6w次閱讀

    容器充電和放電的工作原理

    容器剛接入電路(本來不帶電),開關閉合,充電,一會兒后由不帶電量變得帶電。
    發表于 06-22 09:45 ?1.6w次閱讀

    單片機優雅的開發Clion環境搭建

    單片機優雅的開發Clion環境搭建
    發表于 11-13 12:21 ?20次下載
    單片機<b class='flag-5'>優雅</b>的開發Clion環境搭建

    Tokio 模塊的優雅停機機制

    在進行高并發、網絡編程時,優雅停機是一個非常重要的問題。在 Rust 語言中,Tokio 是一個非常流行的異步編程框架,它提供了一些優雅停機的機制,本文將圍繞 Tokio 模塊的優雅停機進行詳細
    的頭像 發表于 09-19 15:26 ?665次閱讀

    linux關閉docker的命令

    在 Linux 系統中,關閉 Docker 的操作可以通過以下多種方式進行。本文將詳細講解每一種方式,并提供示例代碼和命令,以幫助讀者更好地理解和實踐。 使用 docker 命令 最常用的方法
    的頭像 發表于 11-23 09:39 ?2891次閱讀

    優雅停機是什么?SpringBoot+Nacos+k8s實現優雅停機

    優雅停機是什么?網上說的優雅下線、無損下線,都是一個意思。
    的頭像 發表于 02-20 10:00 ?2149次閱讀
    <b class='flag-5'>優雅</b>停機是什么?SpringBoot+Nacos+k8s實現<b class='flag-5'>優雅</b>停機
    主站蜘蛛池模板: 国产精品夜色一区二区三区| 国产激情三级| 黑色丝袜美美女被躁视频| 黄乱色伦短篇小说h| yyy6080韩国三级理论| 欧美极品一区| 亚洲韩国日本欧美一区二区三区| 特黄aa级毛片免费视频播放| 国产汉服被啪福利在线观看| 最近新韩国hd视频| 午夜艹逼| 欧美色图亚洲| 国产在线永久视频| 伊人网址| 九九福利视频| 色多多网址| 日本精品三级| 婷婷综合在线观看丁香| 四虎影永久在线观看网址| 人碰人操| 国产精品久久久亚洲| 天天做天天爱夜夜爽毛片毛片| 狠狠干狠狠插| 亚洲免费在线观看| 亚洲第一精品夜夜躁人人爽| 美女隐私黄www视频| caoporn成人免费公开| 欧美满足你的丝袜高跟ol| 亚洲国产欧美日韩一区二区三区| 日韩高清特级特黄毛片| 色噜噜中文网| 久草视频一区| 天天干天天上| 国产h在线观看| 亚洲人成电影在线小说网色 | 午夜手机看片| 午夜爽| 国产激情久久久久影院小草| 亚洲男人天堂2020| 色香首页| 成 人 免费 网站|