Docker Runc容器生命週期
容器的生命週期涉及到內部的程式實現和面向使用者的命令列介面,runc內部容器狀態轉換操作、runc命令的參數定義的操作、docker client定義的容器操作是不同的,比如對於docker client的create來說,
語義和runc就完全不同,這一篇文章分析runc的容器生命週期的抽象、內部實現以及狀態轉換圖。理解了runc的容器狀態轉換再對比理解docker client提供的容器操作命令的語義會更容易些。
容器生命週期相關介面
- 最基本的required的介面
- Start: 初始化容器環境並啟動一個init進程,或者加入已有容器的namespace並啟動一個setns進程;執行postStart hook; 阻塞在init管道的寫端,使用者發訊號替換執行真正的命令
- Exec: 讀init管道,通知init進程或者setns進程繼續往下執行
- Run: Start + Exec的組合
- Signal: 向容器內init進程發訊號
- Destroy: 殺掉cgroups中的進程,刪除cgroups對應的path,運行postStop的hook
- 其他
- Set: 更新容器的配置資訊,比如修改cgroups resize等
- Config: 擷取容器的配置資訊
- State: 擷取容器的狀態資訊
- Status: 擷取容器的當前運行狀態: created、running、pausing、paused、stopped
- Processes: 返回容器內所有進程的列表
- Stats: 容器內的cgroups統計資訊
- 對於linux容器定義並實現了特有的功能介面
- Pause: free容器中的所有進程
- Resume: thaw容器內的所有進程
- Checkpoint: criu checkpoint
- Restore: criu restore
介面在內部的實現
- 對於Start/Run/Exec的介面是作為不同os環境下的標準介面對開發人員暴露,介面在內部的實現有很多重複的部分可以統一,因此內部的介面實際上更簡潔,這裡以linux容器為例說明
- 對於Start/Run/Exec在內部實現實際上只用到下面兩個函數,通過傳入flag(容器是否處於stopped狀態)區分是建立容器的init進程還是建立進程的init進程
- start: 建立init進程,如果status == stopped,則建立並執行newInitProcess,否則建立並執行newSetnsProcess,等待使用者發送執行訊號(等在管道寫端上),用使用者的命令替換掉
- exec: 讀管道,發送執行訊號
- Start直接使用start
- Run實際先使用start(doInit = true),然後exec
- Exec實際先使用start(doInit = false), 然後exec
對使用者暴露的命令列參數與容器介面的對應關係,以linux容器為例
- create -> Start(doInit = true)
- start -> Exec
- run -> Run(doInit = true)
- exec -> Run(doInit = false)
- kill -> Signal
- delete -> Signal and Destroy
- update -> Set
- state -> State
- events -> Stats
- ps -> Processes
- list
- linux specific
- pause -> Pause
- resume -> Resume
- checkpoint -> Checkpoint
- restore -> Restore
runc命令列的動作序列對容器狀態機器的影響
- 對於一個容器的生命週期來說,穩定點有4個: stopped、created、running、paused
- 注意下面狀態轉換圖中的動作是runc命令列參數動作,不是容器的介面動作,這裡沒考慮checkpoint相關的restore狀態
delete |------| /-------------------------------------------------------------| | | / |----- start ---| | | V / | | | |---------| ----------- create ----------> |---------|<---------/ | | stopped | | created |------------| | |---------| <-------- delete(with kill)--- |---------| | | ^ ^ | | | | | | | run | |--------------- delete(-f with kill) ---| exec | | delete(-f with kill) | | | | | | | | | | resume | V | | |---------| -----------------------------> |----------| | | | paused | | running |<----------|-------| |---------| <---------------------------- |----------| | ^ pause ^ | | | | | | | |--exec--| | | | |--------------------------- pause ---------------------------|
感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!