深入解析阿里 PouchContainer 如何實現容器原地升級
作者:仔仁 文章來源:雲棲社群
原文連結:https://yq.aliyun.com/articles/615113?spm=a2c4e.11153940.bloghomeflow.256.603b291aakVqfZ
PouchContainer 是阿里巴巴集團開源的高效、輕量級企業級富容器引擎技術,擁有隔離性強、可移植性高、資源佔用少等特性。可以幫助企業快速實現存量業務容器化,同時提高超大規模下資料中心的物理資源利用率。已助力阿里巴巴集團實現線上業務 100% 容器化,雙 11 容器規模達到百萬級。
背景
阿里巴巴集團內部,容器使用方式有很大一部分是富容器模式,像這種基於傳統虛擬機器運維模式下的富容器,其中也有一定數量容器仍然是有狀態的。有狀態服務的更新和升級是企業內部頻率很高的一個日常操作,對於以映象為交付的容器技術來說,服務的更新和升級,對應的容器操作實際上是兩步:舊映象容器的刪除,以及新映象容器的建立。而有狀態服務的升級,則要求保證新容器必須繼承舊容器所有的資源,比如網路、儲存等資訊。下面給出兩個實際的業務案例來直觀闡述富容器業務釋出場景需求:
-
客戶案例一:某資料庫業務,在第一次建立容器服務時,會將遠端的資料下載到本地,作為資料庫的初始資料。因為資料庫初始化過程會比較長,所以在之後可能存在的服務升級過程中,新容器需要繼承舊容器的儲存資料,來降低業務釋出的時間;
-
客戶案例二:某中介軟體服務,業務採取服務註冊的模式,即所有新擴容的容器 IP 必須首先註冊到伺服器列表中,否則新擴容業務容器不可用。在業務容器每次升級釋出時,需要保證新容器繼承舊容器 IP,否則會導致新發布的服務不可用。
現在很多企業都是使用 Moby 作為容器引擎,但 Moby 的所有 API 中並沒有一個介面來對標容器升級這一操作。而組合 API 的方式,必然會增加很多 API 請求次數,比如需要請求容器的增刪 API,需要請求 IP 保留的 API 等等,還可能增加升級操作失敗的風險。
基於以上背景,PouchContainer 在容器引擎層面提供了一個
upgrade
介面,用於實現容器的原地升級功能。將容器升級功能下沉到容器引擎這一層來做,對於操作容器相關資源更加方便,並且減少很多 API 請求,讓容器升級操作變得更加高效。
Upgrade 功能具體實現
容器底層儲存介紹
PouchContainer 底層對接的是 Containerd v1.0.3 ,對比 Moby,在容器儲存架構上有很大的差別,所以在介紹 PouchContainer 如何實現容器原地升級功能之前,有必要先簡單介紹一下在 PouchContainer 中一個容器的儲存架構:
對比 Moby 中容器儲存架構,PouchContainer 主要不一樣的地方:
-
PouchContainer 中沒有了 GraphDriver 和 Layer 的概念,新的儲存架構裡引入了 Snapshotter 和 Snapshot,從而更加擁抱 CNCF 專案 containerd 的架構設計。Snapshotter 可以理解為儲存驅動,比如 overlay、devicemapper、btrfs 等。Snapshot 為映象快照,分為兩種:一種只讀的,即容器映象的每一層只讀資料;一種為可讀寫的,即容器可讀寫層,所有容器增量資料都會儲存在可讀寫 Snapshot 中;
-
Containerd 中容器和映象後設資料都儲存在 boltdb 中,這樣的好處是每次服務重啟不需要透過讀取宿主機檔案目錄資訊來初始化容器和映象資料,而是隻需要初始化 boltdb。
Upgrade 功能需求
每一個系統和功能設計之初,都需要詳細調研該系統或功能需要為使用者解決什麼疼點。經過調研阿里內部使用容器原地升級功能的具體業務場景,我們對
upgrade
功能設計總結了三點要求:
-
資料一致性
-
靈活性
-
魯棒性
資料一致性指
upgrade
前後需要保證一些資料不變:
-
網路:升級前後,容器網路配置要保持不變;
-
儲存:新容器需要繼承舊容器的所有 volume ;
-
Config:新容器需要繼承舊容器的某一些配置資訊,比如 Env, Labels 等資訊;
靈活性指
upgrade
操作在舊容器的基礎上,允許引入新的配置:
-
允許修改新容器的 cpu、memory 等資訊;
-
對新的映象,即要支援指定新的
Entrypoint
,也要允許繼承舊容器的Entrypoint
; -
支援給容器增加新的 volume,新的映象中可能會包含新的 volume 資訊,在新建容器時,需要對這部分 volume 資訊進行解析,並建立新的 volume。
魯棒性是指在進行容器原地升級操作期間,需要對可能出現的異常情況進行處理,支援回滾策略,升級失敗可以回滾到舊容器。
Upgrade 功能具體實現
Upgrade API 定義
首先說明一下
upgrade
API 入口層定義,用於定義升級操作可以對容器的哪些引數進行修改。如下
ContainerUpgradeConfig
的定義,容器升級操作可以對容器
ContainerConfig
和
HostConfig
都可以進行操作,如果在 PouchContainer github 程式碼倉庫的
apis/types
目錄下參看這兩個引數的定義,可以發現實際上,
upgrade
操作可以修改舊容器的__所有__相關配置。
// ContainerUpgradeConfig ContainerUpgradeConfig is used for API "POST /containers/upgrade".// It wraps all kinds of config used in container upgrade.// It can be used to encode client params in client and unmarshal request body in daemon side.//// swagger:model ContainerUpgradeConfig
type ContainerUpgradeConfig struct {
ContainerConfig // host config
HostConfig *HostConfig `json:"HostConfig,omitempty"`
}
Upgrade 詳細操作流程
容器
upgrade
操作,實際上是在保證網路配置和原始 volume 配置不變的前提下,進行舊容器的刪除操作,以及使用新映象建立新容器的過程,如下給出了
upgrade
操作流程的詳細說明:
-
首先需要備份原有容器的所有操作,用於升級失敗之後,進行回滾操作;
-
更新容器配置引數,將請求引數中新的配置引數合併到舊的容器引數中,使新配置生效;
-
映象
Entrypoint
引數特殊處理:如果新的引數中指定了Entrypoint
引數,則使用新的引數;否則檢視舊容器的Entrypoint
,如果該引數是透過配置引數指定,而不是舊映象中自帶的,則使用舊容器的Entrypoint
作為新容器的Entrypoint
;如果都不是,最後使用新映象中的Entrypoint
最為新建立容器的Entrypoint
。對新容器Entrypoint
這樣處理的原因是為了保持容器服務入口引數的連續性。 -
判斷容器的狀態,如果是 running 狀態的容器,首先 stop 容器;之後基於新的映象建立一個新的 Snapshot 作為新容器讀寫層;
-
新的 Snapshot 建立成功之後,再次判斷舊容器升級之前的狀態,如果是 running 狀態,則需要啟動新的容器,否則不需要做任何操作;
-
最後進行容器升級清理工作,刪掉舊的 Snapshot,並將最新配置進行存檔。
Upgrade 操作回滾
upgrade
操作可能會出現一些異常情況,現在的升級策略是在出現異常情況時,會進行回滾操作,恢復到原來舊容器的狀態,在這裡我們需要首先定義一下
升級失敗情況
:
-
給新容器建立新的資源時失敗,需要執行回滾操作:當給新容器建立新的 Snapshot,Volumes 等資源時,會執行回滾操作;
-
啟動新容器出現系統錯誤時,需要執行回滾操作:即在呼叫 containerd API 建立新的容器時如果失敗則會執行回滾操作。如果 API 返回正常,但容器內的程式執行異常導致容器退出的情況,不會執行回滾操作。
如下給出了回滾操作的一個基本操作:
defer func() { if !needRollback { return
} // rollback to old container.
c.meta = &backupContainerMeta // create a new containerd container.
if err := mgr.createContainerdContainer(ctx, c); err != nil {
logrus.Errorf("failed to rollback upgrade action: %s", err.Error()) if err := mgr.markStoppedAndRelease(c, nil); err != nil {
logrus.Errorf("failed to mark container %s stop status: %s", c.ID(), err.Error())
}
}
}()
在升級過程中,如果出現異常情況,會將新建立的 Snapshot 等相關資源進行清理操作,在回滾階段,只需要恢復舊容器的配置,然後用恢復後的配置檔案啟動一個新容器既可。
Upgrade 功能演示
-
使用
ubuntu
映象建立一個新容器:
$ pouch run --name test -d -t registry.hub.docker.com/library/ubuntu:14.04 top
43b75002b9a20264907441e0fe7d66030fb9acedaa9aa0fef839ccab1f9b7a8f
$ pouch ps
Name ID Status Created Image Runtimetest 43b750 Up 3 seconds 3 seconds ago registry.hub.docker.com/library/ubuntu:14.04 runc
-
將
test
容器的映象升級為busybox
:
$ pouch upgrade --name test registry.hub.docker.com/library/busybox:latest toptest$ pouch ps
Name ID Status Created Image Runtimetest 43b750 Up 3 seconds 34 seconds ago registry.hub.docker.com/library/busybox:latest runc
如上功能演示,透過
upgrade
介面,直接將容器的映象替換為新的映象,而其他配置都沒有變化。
總結
在企業生產環境中,容器
upgrade
操作和容器擴容、縮容操作一樣也是的一個高頻操作,但是,不管是在現在的 Moby 社群,還是 Containerd 社群都沒有一個與該操作對標的 API,PouchContainer 率先實現了這個功能,解決了容器技術在企業環境中有狀態服務更新發布的一個痛點問題。PouchContainer 現在也在嘗試與其下游依賴元件服務如 Containerd 保持緊密的聯絡,所以後續也會將
upgrade
功能回饋給 Containerd 社群,增加 Containerd 的功能豐富度。
PouchContainer開源地址
PouchContainer 容器技術開源 GitHub 地址為:
PouchContainer 團隊誠邀廣大技術愛好者參與開源貢獻,打造國內第一容器品牌。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31473948/viewspace-2158720/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PouchContainer 容器技術演進助力阿里雲原生升級AI阿里
- 揭秘:如何為 Kubernetes 實現原地升級
- 技術解析系列 | PouchContainer 支援 LXCFS 實現高可靠容器隔離AI
- PouchContainer支援LXCFS實現高可靠容器隔離AI
- 如何實現OpenHarmony的OTA升級
- 邏輯升級,深度解析如何實現業務中的且或元件元件
- nginx實現平滑升級Nginx
- PouchContainer CRI的設計與實現方法AI
- 新基建棋局下,智慧交通如何實現產業升級?產業
- 深入原始碼解析 tapable 實現原理原始碼
- JAVA 實現《超級瑪麗升級版》遊戲Java遊戲
- 實戰訓練營:傳統分散式架構如何進行容器化升級分散式架構
- PHP實現一個輕量級容器PHP
- 如何看阿里和SAP戰略合作的“再升級”?阿里
- java實現“資料平滑升級”Java
- 阿里雲容器服務全線升級,ACK Pro開啟公測、邊緣容器商業化阿里
- 面試題深入解析:Synchronized底層實現面試題synchronized
- 深入解析 Go 中 Slice 底層實現Go
- Javascript閉包深入解析及實現方法JavaScript
- 雲解析DNS如何實現智慧解析?DNS
- OpenKruise :SidecarSet 助力 Mesh 容器熱升級UIIDE
- 踩過的坑(一)——web容器升級Web
- 如何升級 pip
- 深入Java原始碼解析容器類List、Set、MapJava原始碼
- Unity TA總監王靖:Unity如何實現美術畫質升級?Unity
- docker 容器中單獨升級某個模組Docker
- 使用SQL Apply實現滾動升級SQLAPP
- 安全啟動和安全升級的實現
- 阿里雲伺服器怎麼升級配置?升級有哪些限制?阿里伺服器
- 批發分銷行業如何實現數字化轉型升級?行業
- 家居企業如何通過網際網路實現營銷升級?
- Android不使用第三方升級庫實現應用升級Android
- jQuery 1.9/2.0關鍵升級解析jQuery
- 使用阿里 Druid 實現應用級waf阿里UI
- 微信LazyMan筆試題的深入解析和實現筆試
- 動態載入css方法實現和深入解析CSS
- Nginx如何升級OpensslNginx
- 阿里雲伺服器升級gcc阿里伺服器GC