顧雯軒,高 原,顧文杰,鄒 慶,董子奇
(1.南瑞集團有限公司(國網(wǎng)電力科學研究院),江蘇 南京 211106;2.國電南瑞科技股份有限公司,江蘇 南京 211106;3.智能電網(wǎng)保護和運行控制國家重點實驗室,江蘇 南京 211106)
近年來,容器化技術成為了云生態(tài)系統(tǒng)中最受關注的技術之一。容器能夠提供資源隔離、資源限制功能,提高了系統(tǒng)的穩(wěn)定性。容器通過鏡像技術對應用運行環(huán)境進行封裝,通過容器云管理平臺可以方便地實現(xiàn)持續(xù)集成和持續(xù)部署,降低了系統(tǒng)運維的工作量。
隨著特高壓電網(wǎng)的大規(guī)模建設,電網(wǎng)調度控制(簡稱調控)系統(tǒng)實時數(shù)據(jù)規(guī)??焖僭黾?,整個調控系統(tǒng)中的應用數(shù)量也大量增加,對系統(tǒng)基礎資源管理能力和運維能力提出了更高要求。以往調控系統(tǒng)應用部署時不能有效限制應用使用的資源[1]。引入容器技術后,可以實現(xiàn)更細粒度的資源分配。通過容器的資源限制和資源隔離功能,將業(yè)務服務限制在分配的資源范圍內運行,在保證了系統(tǒng)資源充分利用的同時實現(xiàn)系統(tǒng)穩(wěn)定運行。
但是,傳統(tǒng)的開源容器[2-4]技術不能完全滿足電網(wǎng)實時調控系統(tǒng)的要求。比如容器網(wǎng)絡不支持廣播,不具備限制網(wǎng)絡帶寬的功能,容器鏡像較大導致應用遷移和啟動耗時長。通過研究現(xiàn)有容器技術的實現(xiàn)原理,該文提出一種輕量級的容器服務技術,通過研究虛擬網(wǎng)橋技術實現(xiàn)了跨物理宿主機的廣播/組播通信;結合Linux流量控制內核技術實現(xiàn)容器網(wǎng)絡帶寬限制,并通過對私有數(shù)據(jù)的封裝降低容器體積,實現(xiàn)輕量化。
容器的實現(xiàn)主要依賴于Linux的內核技術CGroup[5],NameSpace[6-7]和聯(lián)合文件系統(tǒng)[8]。CGroup(Control Group控制組)是Linux內核提供的一種限制進程組使用宿主機物理資源的機制。通過給容器分配資源的控制機制,避免某個異常容器占用過多的宿主機資源,確保同時運行的多個容器對宿主機資源的合理利用。控制組可以提供內存、CPU、磁盤IO等資源的限制和查詢管理,但是net_cls子系統(tǒng)不具備直接限制網(wǎng)絡資源的功能,即不能限制某個容器內應用占用宿主機的帶寬大小。
NameSpace(命名空間)是Linux針對實現(xiàn)容器資源隔離而引入的特性。每個容器都可以擁有自己唯一的命名空間,運行在其中的進程都像是在獨立互不干擾的操作系統(tǒng)中運行一樣,彼此不可見。這個機制保證了容器運行環(huán)境的相互獨立,特別適合一個宿主機運行很多微服務的應用場景,能夠保證每個服務間使用操作系統(tǒng)資源以及服務自身數(shù)據(jù)的互不干擾。
開源容器Docker目前常用的三種網(wǎng)絡插件為Flannel[9]、Weave[10]、Calico[11]。Flannel通過給每臺宿主機分配一個子網(wǎng)的方式為容器提供虛擬網(wǎng)絡,使用UDP/VXLAN封裝IP包來創(chuàng)建overlay網(wǎng)絡,并借助etcd維護網(wǎng)絡的分配情況。Weave創(chuàng)建一個連接多個Docker主機的虛擬網(wǎng)絡,類似于一個以太網(wǎng)交換機,所有的容器都連接到這上面,互相通信。Calico在主機上創(chuàng)建了一堆的虛擬網(wǎng)卡,其中一端在主機上,另一端在容器的網(wǎng)絡命名空間里,然后在容器和主機中分別設置幾條路由,來完成網(wǎng)絡的互聯(lián)。
這三種插件都是通過給容器建立子網(wǎng),給容器分配子網(wǎng)IP的方式,使得容器間可以互通。容器分配的IP與宿主機不是一個網(wǎng)段,跨宿主機的容器間可以進行TCP和UDP通信。在一個宿主機內部,容器之間可以進行組播/廣播通信,但是跨宿主機節(jié)點的容器之間無法進行組播/廣播通信。
聯(lián)合文件系統(tǒng)的引入為構建容器和快速遷移提供了有效機制。
一個典型的Linux系統(tǒng)運行需要兩個文件系統(tǒng):bootfs和rootfs。相同內核版本的不同Linux發(fā)行版本的bootfs都是一致的,并且是用戶不可更改的。另一個rootfs文件系統(tǒng)包含典型的目錄,包括/dev,/proc,/bin等再加上一些需要運行用戶程序的必要文件(配置文件,庫文件,可執(zhí)行文件)。這個文件系統(tǒng)在不同的Linux發(fā)型版本中是不同的,并且是用戶可更改的。
當啟動一個容器的時候,會將鏡像[12-13]的內容加載到容器內部。鏡像中的內容主要是rootfs文件系統(tǒng)以及一些用戶程序依賴文件。從同一個鏡像啟動多個容器時,rootfs文件系統(tǒng)會被加載重復加載多次,當在宿主機上啟動大量容器時,相同rootfs文件的重復加載對內存資源是一種浪費,并且對容器的啟動時間也有一定的影響。
一種最大化內存共享與最小化運行時環(huán)境的超輕量級容器[14]通過去除所有底層操作系統(tǒng)庫文件且單獨指定容器內應用依賴庫的方法構建輕量化容器。這種方法是一種量身定制的方法,但是如果在電力系統(tǒng)中使用,需要每個應用都能準確指定所需要的依賴庫,這對電力系統(tǒng)的研發(fā)人員具有一定挑戰(zhàn)性,且通用性不好,實施難度大。
該文提出一種輕量級容器的實現(xiàn)方法,將容器運行時的存儲空間分為兩部分:公共存儲空間和私有存儲空間。其中,公共存儲空間共享宿主機的文件資源,私有存儲空間存儲容器應用或服務運行需要的相關文件資源。各個容器之間的私有存儲空間相互隔離,互不干擾,并且容器之間共享宿主機的文件資源;在容器內部,可以同時看到宿主機文件資源和自身的文件資源。
每個輕量級容器擁有獨立的工作目錄,工作目錄作為私有存儲空間是相互獨立的,容器只能訪問自己的工作目錄。各個輕量級容器在自身容器內部觀察到的工作目錄的路徑和命名是一致的,這樣保證了電力上層應用程序的通用性,即容器對應用程序是透明的。通過Linux NameSpace中的mnt[15]掛載命名空間實現(xiàn)數(shù)據(jù)隔離,這樣對某個輕量級容器的私有工作目錄進行操作不會影響到宿主機或其他輕量級容器的相同目錄。各個輕量級容器的工作目錄在宿主機上基于不同的路徑和目錄進行管理,目錄命名與容器命名相關聯(lián),輕量級容器進行遷移打包的時候,只需要打包各自的工作目錄即可,因此容器鏡像的體積更小,整個鏡像封裝更加輕便。
輕量級容器結構如圖1所示。
圖1 輕量級容器結構
操作系統(tǒng)rootfs:宿主機文件系統(tǒng)包含bootfs和rootfs。其中bootfs和Linux內核相關,所有容器共享。rootfs包括常見的/dev,/proc,/etc,/usr等,所有容器也共享rootfs,在容器中看到就是宿主機的rootfs。
輕量級容器:從存儲空間來說包含兩部分:容器中運行的可執(zhí)行程序以及需要的依賴庫,配置文件。這些都是存放在容器的私有工作目錄中的,各個容器之間相互看不見;共享宿主機rootfs文件系統(tǒng),這個為公共存儲空間。
Linux操作系統(tǒng)內核:宿主機的操作系統(tǒng)內核,所有運行在該宿主機上的容器都共享Linux操作系統(tǒng)內核。容器的資源限制,資源隔離以及流量控制功能都需要操作系統(tǒng)內核的支持。
輕量級容器引擎:負責管理容器的整個生命周期,包括創(chuàng)建,啟動,停止,銷毀,主要功能的實現(xiàn)都是依賴Linux內核技術,包括控制組和命名空間。
以上通用技術實現(xiàn)的容器還不能直接滿足電力實時調控系統(tǒng)的需求,原因是電力調控系統(tǒng)對可靠性和實時性要求非常高,所以整個系統(tǒng)底層建立了提供高可用管理和高速通信功能的基礎平臺,這個平臺的高可用和通信模塊需要使用廣播和組播進行通信。并且使用容器后,在一個物理機上不能發(fā)生某一個容器搶占了這個物理機所有帶寬的情況,否則實時系統(tǒng)的部分功能模塊可能就會失去作用。同時因為系統(tǒng)實時性要求高,容器啟動的時效性就要很高的要求,啟動時間越短越好。因此該文基于以下討論的三種技術實現(xiàn)了一種支持跨物理節(jié)點組播/廣播,并能提供網(wǎng)絡帶寬限制功能的輕量化容器。
網(wǎng)絡帶寬限制技術是通過控制組(Control CGroup)的net_ctl[16]子系統(tǒng)和Linux的流量控制(Traffic Control)[16]共同配合實現(xiàn)的。CGroup子系統(tǒng)net_cls可以給發(fā)送packet打上classid的標簽,用于過濾分類。有了這個標簽,流量控制器(tc)可以對分屬不同的CGroup進程發(fā)送的packet起作用。每個容器擁有獨立的網(wǎng)絡命名空間,且為容器內網(wǎng)卡配置的IP地址與宿主機的IP地址在一個網(wǎng)段上。如圖2所示,為了對該容器的發(fā)送數(shù)據(jù)進行網(wǎng)絡流量限制,需要在容器內的網(wǎng)卡上設置TC規(guī)則,其中eth1是容器內的網(wǎng)卡。然后在該容器的CGroup子系統(tǒng)net_cls下的相應目錄內,將tc class規(guī)則的classid傳給net_cls.classid文件。通過這樣的操作,該容器內所有的輸出網(wǎng)絡流量都會限制在tc class規(guī)則限定的value值內,其中,value為字符串,格式為數(shù)值+單位(kbps/mbps/kbit/mbit)。
圖2 網(wǎng)絡帶寬限制原理
tc qdisc add dev eth1 root handle major:0 htb
tc class replace dev eth1 parent major: classid major: minor htb rate value
tc filter add dev eth1 protocol ip parent major:0 prio 1 handle major: minor cgroup
電網(wǎng)調控系統(tǒng)目前多采用多機主備冗余機制,該機制使用廣播進行通信。調控系統(tǒng)的消息總線使用組播進行通信。因此,若需要輕量級容器運用到電網(wǎng)調控系統(tǒng)中,必須確保各個容器之間能夠進行組播/廣播通信,并且容器和物理節(jié)點之間也能對等地進行組播/廣播通信。文中輕量級容器分配IP的方式結合虛擬網(wǎng)橋和虛擬網(wǎng)卡技術實現(xiàn)。
工作原理如圖3所示。
圖3 虛擬網(wǎng)橋/網(wǎng)卡實現(xiàn)原理
(1)宿主機建立虛擬網(wǎng)橋br0,將物理網(wǎng)卡eth0的ip地址賦予br0,橋接到br0;
(2)創(chuàng)建一對虛擬網(wǎng)卡veth pair,其中一個虛擬網(wǎng)卡加入容器的網(wǎng)絡命名空間中,并更名為eth1,配置IP地址和路由。另一個網(wǎng)卡橋接到br0上。
如圖3所示,每個容器擁有獨立的IP地址,與宿主機配置在同一網(wǎng)段上,容器和容器,容器和宿主機之間都能進行廣播和組播通信。
輕量化主要體現(xiàn)在相比Docker容器的鏡像(如圖4(a)所示)體積更小,層級更少。如圖4(b)所示,輕量級容器內部雖然可以看到整個Linux的文件操作系統(tǒng),但并不表示輕量級容器鏡像包含Linux文件操作系統(tǒng)的整個信息。鏡像中只存放了支持容器運行的一些必備文件,包括依賴庫文件,程序執(zhí)行文件和配置文件。創(chuàng)建容器的時候,會在宿主機上創(chuàng)建一個目錄用于存放容器的私有數(shù)據(jù),并將鏡像中的文件拷貝至容器私有目錄中。然后通過mount的bind操作將這個私有目錄掛載至容器的相應目錄中。對于不同的容器來說,將私有目錄掛載至容器掛載空間的相同目錄中,由于容器擁有獨立的掛載隔離空間,這種操作是獨立的,互不干擾的。不同容器的相同掛載目錄中的內容是不一樣的,在此目錄中做文件修改,文件刪除或文件增加操作都只限于本容器內部,不會對其他容器的掛載目錄產(chǎn)生任何影響,同時對容器外面的宿主機而言也是不可見的。
(a)傳統(tǒng)容器鏡像結構
本節(jié)通過在網(wǎng)絡性能、帶寬限制能力、啟動時間三方面將該文研究的輕量級容器與開源容器進行了對比,說明了輕量級容器在三個方面均優(yōu)于開源容器。
結合控制組的net_cls子系統(tǒng)和Linux流量控制功能,可以實現(xiàn)對容器發(fā)送數(shù)據(jù)的帶寬限制。通過scp跨主機拷貝大容量文本Text進行測試驗證,測試分兩組進行(見圖5):
圖5 帶寬使用對比
第一組在主機docker3上直接通過scp拷貝Text文本至主機節(jié)點docker1,通過iftop檢測網(wǎng)卡,發(fā)送速率約為800 Mb/s。
第二組測試是在輕量級容器中進行。首先啟動容器時通過參數(shù)設置,對該容器的帶寬值限制在20 Mb/s。然后通過scp拷貝和第一組中相同大小的文件Text文本至主機節(jié)點docker1,通過iftop檢測,發(fā)送速率控制在了20 Mb/s以內。
本節(jié)對目前Docker主流的網(wǎng)絡開源組件和文中所述的輕量級容器網(wǎng)絡組件進行性能對比。對比的方面包括帶寬和時延,通過發(fā)送不同KiB大小的數(shù)據(jù)包鏡像檢測。采用測試5次取平均值的方法。
(a)host宿主機帶寬 (b)Flannel帶寬
帶寬性能檢測結果如圖6所示,圖中的橫坐標表示發(fā)送數(shù)據(jù)包的大小,從1到64遞增,單位為KiB;縱坐標為帶寬,單位為MB/sec。從圖中對比可知,F(xiàn)lannel和Weave的帶寬性能較差,Calico和網(wǎng)橋方式與主機性能差不多,其中網(wǎng)橋方式性能最優(yōu)。
時延性能測試結果如圖7所示,圖中的橫坐標表示發(fā)送數(shù)據(jù)包的大小,從1到64遞增,單位為KiB;縱坐標表示時延,單位是μs。從對比中可知,Calico和網(wǎng)橋方式與主機性能差不多,且網(wǎng)橋方式性能最優(yōu),Weave和Flannel會隨著數(shù)據(jù)包越來越大而時延越來越大。
(a)host宿主機時延 (b)Flannel時延
這里從容器中的進程啟動時間來對比分析一下文中的輕量級容器和Docker容器的性能。
測試中使用的rocky_cloud:latest開源docker容器包含了運行電網(wǎng)調控系統(tǒng)所需的最小化國產(chǎn)操作系統(tǒng)模塊,輕量級容器因為與底層宿主機操作系統(tǒng)共享模塊,所以大小要小很多。采用測試5次取平均值的方法,輕量級容器和Docker中只啟動一個測試程序,見表1。測試程序單獨啟動時需要1 022 ms。
表1 鏡像大小對比
通過輕量級容器啟動測試程序需要1 025 ms,Docker啟動該測試程序需要2 133 ms。圖8中,橫坐標標識同時啟動容器的個數(shù),分別測試了同時啟動2個容器,4個容器,8個容器,16個容器,32個容器時。縱坐標標識容器啟動需要花費的時間,單位是μs。從圖8中分析可知,基本上用Docker啟動進程需要花費的時間是輕量級容器的2倍。
圖8 啟動時間性能對比
提出了一種適用于電網(wǎng)調控實時系統(tǒng)的輕量級容器技術實現(xiàn)方法,在網(wǎng)絡帶寬限制,跨物理機通信方式和輕量化方面都進行了相關工作。主要的工作包括:結合Linux內核技術實現(xiàn)容器網(wǎng)絡帶寬的限制功能;結合虛擬網(wǎng)橋網(wǎng)卡技術,為容器分配獨立的IP地址并支持跨主機的組播廣播通信方式;提出了輕量級容器私有工作空間的概念,通過共享Linux文件操作系統(tǒng)的方式實現(xiàn)容器的輕量化。最后通過實驗結果分析,該輕量級容器在支持組播/廣播通信的同時具備帶寬限制的功能,且體積小,遷移快速方便,啟動性能上優(yōu)于傳統(tǒng)容器。