天天看點

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

【編者的話】這是盆盆談微軟兩會(build/iginte)系列之一。文章引用孫建波老師關于linux核心的6大命名空間隔離,看windows docker如何實作類似隔離,同時又有哪些不同。文章素材取自build和ignite大會視訊,但主要展示盆盆自己的分析和研究,還望大家指正為謝。

在咱們微信群裡聽一位兄弟提到,docker能将devops(意即開發和運維)整合在一起,暗合王陽明先生的“知行合一”之教,這真是一種有趣的說法。

這裡需要注意的是:以下的論述,大多是盆盆根據taylor的demo效果所做的推論,并不是taylor本人的陳述,是以并不一定正确。由于能力所限,必然謬誤不少,還望大家能及時指出哈。

<a target="_blank"></a>

拿大家熟悉的linux docker來看,其涉及到linux核心所提供的namespace隔離技術和資源控制的cgroup技術。

孫建波老師提到了一張表格,其中列出了linux核心所支援的6種隔離:主機名、ipc、程序id、網絡、檔案系統、賬号。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

盡管windows核心實作和linux不同,但是兩者還是有不少可比拟處。是以盆盆根據build大會上mark russinovich這位大神以及taylor brown的講座,來條分縷析。試圖按照這幾個namespace隔離的架構來進行闡述。

1.jpg

孫宏亮老師指出,假設我們下拉了ubuntu:14.04映像,并通過指令docker run –it ubuntu:14.04 /bin/bash将其啟動運作。則docker為其建立的rootfs以及容器可讀寫的檔案系統參見下圖。從容器的視角來看,雖然隻有一個邏輯的完整文 件系統,但該檔案系統由“2層”組成,分别為讀寫檔案系統和隻讀檔案系統(按隻讀層還可以再邏輯分層,是以極大地節省磁盤空間)。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

2.jpg

windows docker同樣如此,頂層的沙盒層(sandbox layer)是可讀寫的,隻允許該容器自己占用,而其他層則是隻讀的,可供不同容器共享。在下圖中,底層的基礎os層和中間的應用程式架構層都是隻讀的, 而頂層的沙盒層則可讀寫,在容器的視角看來,它獨占了完整的os。這有點類似于hyper-v的差異磁盤鍊(頂部的子盤才能讀寫,其上方的所有父盤和 base盤都是隻讀的)。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

3.jpg

為了說明檔案系統隔離的魔力,taylor示範了在windows容器裡用del指令删除c盤根目錄下所有檔案,然後再用reg指令删除hklm\software下的所有系統資料庫鍵值,盡管這個容器被毀了,但是并不會影響其他容器,更不會影響主機。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

4.jpg

盆盆猜測,在windows容器的視角裡,如果隻是讀取一個檔案,在最頂端的沙盒層裡隻有該檔案的重解析點(reparse point);隻有在修改該檔案時,才會用copy-on-writer的方法從下方的隻讀層中把檔案内容複制到可讀寫的沙盒層。

視訊裡示範了一個demo。用一段簡單的代碼,在docker client的console裡顯示“this is a pretty cool app”。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

5.jpg

這是用來建構windows docker映像的dockerfile。這個檔案由以下4行指令組成,基本上每一行指令等于疊加1個layer:

第1行:表明該映像基于windowsservercore這個base映像,可以将其了解為rootfs

第2行:表示工作目錄是c盤根目錄

第3行:将應用目錄複制到容器映像裡

第4行:啟動該應用程式

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

6.jpg

用docker build指令将其建構為容器映像,tag是1。從指令結果中可以看到dockerfile裡的每個指令都被執行,并疊加新的image layer。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

7.jpg

docker映像建構完成後,可以運作docker image指令檢視建立的映像,運作docker run指令即可快速啟動該映像,并成功顯示”this is a pretty cool app…”。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

8.jpg

通過使用docker history指令,我們可以檢視容器映像的建構曆史,這甚至可以用來逆向生成dockerfile。例如視訊裡示範了sysinternals這個映像 的建構曆史。從中我們可以看到:首先記錄維護人員是誰;然後指定工作目錄是c盤根目錄;再者是将sysinternals suite這個工具軟體目錄拷貝到容器映像裡;然後設定容器的運作賬戶(本文後面的賬戶隔離一節還會再闡述);最後設定啟動ipconfig以便顯示容器 的ip位址。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

9.jpg

和linux docker容器一樣,windows容器也采用ipc隔離機制。windows容器使用windows自己的session隔離機制。

會話(session)隔離機制,最初是用在windows終端服務和快速使用者切換中,以便這些不同使用者的程序不會互相幹擾,確定安全。從 windows vista開始,也采用這種技術對系統會話進行隔離,windows系統自己的服務和程序會占用原來的控制台會話(會話0),而後續的使用者會依次使用會話 1、會話2等等,這就是我們不能再使用mstsc /console進行控制台登入的原因。

從《windows internals》裡我們可以學習到:不同會話裡的應用,不能夠發送視窗消息(window message),以防止粉碎攻擊。每個會話擁有自己專用的對象命名空間。同樣每個windows容器,也會有自己的獨立會話,有自己專用的 basenamedobjects等對象命名空間,以便隔離事件、互斥信号和記憶體段等對象。這樣不同容器在同一個windows主機上通路同一個命名對 象,就不會導緻沖突。以下的winobj對話框是在盆盆自己的windows 10上截圖的,雖然不是取自windows docker系統,但是道理是一樣的,可以看到不同的會話,擁有自己專用的對象命名空間。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

10.jpg

視訊裡示範了docker容器的會話隔離能力。taylor啟動了兩個容器,都是從同一個windowsservercore映像裡派生出來的。 其中一個容器,可以運作tasklist指令,看到該容器運作在會話14中。而且還能看到兩個系統程序,一個是system程序,代表作業系統本身,另一 個是空閑程序,這兩個程序都運作在會話0裡。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

11.jpg

在同一個映像所建立的另一個容器裡,我們可以看到該容器運作在會話15中,同樣可以看到system程序和空閑程序。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

12.jpg

taylor的解釋是由于容器是共享windows kernel的,是以容易可以看到system程序的pid是一樣的,都是4。其實system程序并不是使用者模式程序,而是用來代表所有作業系統和驅動 程式的核心模式線程,在所有的windows主機上,system程序的pid都是4,空閑程序也是同樣的道理。

和linux容器一樣,windows容器也可以有自己的獨立網絡配置。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

13.jpg

此外,由于最新的windows server 2016具備sdn功能,不但包含先前windows 2012對于nvgre的支援,同時也支援vxlan。理論上來說,window内置的網絡支援能力如果能夠和windows docker有機的整合,可以更好地支援windows docker功能。

由于傳統的windows應用大多是有gui的,是以這些應用可能需要通過圖形化方式進行遠端操控。

視訊裡taylor舉了一個sysinternals容器的例子。有趣的是,這個demo本來是mark russsinovich的保留曲目,可惜build大會keynote的時間十分寶貴,mark沒有足夠的時間去示範,而由taylor代勞。

taylor示範直接在docker client上下文裡啟動sysinternals suite裡的經典工具process explorer,由于該工具帶gui,是以雖然程序已經在容器裡啟動,但是在docker client裡無法直接遠端顯示。

如何才能正常顯示呢?taylor用了一個cc指令,直接連接配接到該容器的ip位址(192.168.0.23)。從demo裡我們可以看出,實際 上這個cc指令連接配接到容器的rdp服務上,這樣就相當于直接通過終端服務連接配接到容器裡的會話裡,哈哈,有點類似remoteapp(或者citrix xenapp)的效果!

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

14.jpg

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

15.jpg

在linux容器裡,容器裡的pid有自己的獨立命名空間。從示範的情況來看,windows容器的pid隔離方法看上去略有不同。

在前面ipc隔離一節,我們可以通過tasklist指令确認不同的容器,其csrss、lsass、svchost等重要程序的pid有所不同,使用者程序的pid也不一樣,可見彼此之間是完全隔離的。

那麼從主控端的角度來看呢?

我們可以用process explorer的例子來确認,這需要觀看ignite大會上由taylor所主講的視訊,由于process explorer是在終端會話裡打開的,是以我們可以在容器的任務管理器裡看到有兩個會話:

會話14是docker用戶端通路生成

會話15則是通過rdp通路生成

可以看到process explorer的程序有兩個版本。顯然,會話14是taylor在docker用戶端裡運作的結果(但是我們無法看到圖形化界面),而會話15則是rdp通路的結果。

兩者的運作賬戶不一樣,rdp登入的運作身份為administrator(應該和docker history一緻),而會話14則是system賬戶。

以下是從容器視角所看到的任務管理器。這個任務管理器是從容器的角度來看的,我們可以記下其中的若幹svchost程序的pid。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

接下來我們打開主控端的任務管理器,從全局的角度來檢視。可以發現,從主控端的角度來看,能看到每個容器裡的程序,其pid和容器裡面的版本是一樣的。

16.jpg

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

17.jpg

linux核心擁有賬戶隔離能力,可以讓容器裡的程序以root身份運作,而在主控端上,該賬戶實際上是普通使用者權限,這樣可以極大地改進安全性。

在taylor的這個示範中,我們也能“察覺”到一些蛛絲馬迹。在pid隔離一節的兩個任務管理器截圖裡,從容器的視角來看,可以看到 process explorer的運作賬戶為administrator,但是從主控端上檢視,對應程序的運作賬戶為空。是以windows容器可能也實作了類似的賬戶 隔離技術(抱歉這隻是推測,我們現在還拿不到windows docker的測試版本)。

windows容器擁有自己的計算機名和域名隔離能力,這樣在網絡上,windows容器看上去類似于一台獨立的虛拟機。

不過由于共享核心,是以windows容器目前應該不支援活動目錄,畢竟同一台主控端上所有容器應該都具有同一個sid,這樣就無法加域(無法驗證計算機賬戶)。

盆盆推測,到了windows容器時代,類似于活動目錄這類比較笨重的驗證協定可能會逐漸退出曆史舞台。畢竟活動目錄需要開放那麼多端口,需要借助adfs等手段才能穿透internet。

不過windows容器的驗證并不會存在問題,azure ad和證書等都是很合适的辦法。

容器非常适合開發的快速疊代、快速復原。taylor做了一個簡單的示範,對前面所述的代碼進行修改,調用私有的msvcr120.dll檔案裡的_snwprintf函數,以顯示”now it’s really cool”。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

18.jpg

但是在docker build的時候,taylor沒有修改dockerfile,沒有像mark之前的demo那樣把私有的msvcr120.dll拷貝到容器映像中,以便生成新的layer。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

19.jpg

結果由于容器的目标主控端上沒有安裝visual studio,是以新build的容器運作失敗,提醒缺少msvcr120.dll檔案,而無法顯示”now it’s really cool”。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

20.jpg

解決這個問題很簡單,可以根據先前的映像快速生成新的容器,這大概隻需要幾秒鐘時間。這樣就可以有充足的時間去調試修改了。

在build大會的keynote上,mark russinovich示範了用visual studio把同一個電商網站的代碼簽入到windows容器和linux容器裡,并且可以用visual studio來調試linux容器裡的代碼。

Windows Docker第一時間揭秘Windows Docker第一時間揭秘

21.jpg

原文釋出時間:2015-05-14

本文來自雲栖合作夥伴“linux中國”

繼續閱讀