Windows Docker Container 介紹

Container 容器技術是新一代的虛擬化技術,是企業邁向微服務架構的必經之路,本篇將針對 Windows 環境下的應用程式虛擬化,介紹其應作的原理,以利呼應我另外一篇 SQL Server Container的文章。
Container 容器技術早在 Unix時代就已經存在了,隨著市場上在Infrastructure對於虛擬化技術的廣大需求,以及應用情境的普及。虛擬化以技術的層次,已經發展出硬體、指令集、作業系統、函式庫、應用程式…等五大類別。以應用情境來看,虛擬化可歸納成Hypervisor型、主機型、容器化…等三大類型。
 

隨著公有雲的普及,巨量的商務需求,也帶動著底層的虛擬化有著顯著地技術突破,所以本文會依序介紹1、容器技術商業化之前的虛擬化技術發展。2、何謂 Docker Container與其技術原理?3、容器化技術的效益與比較。4、Windows Docker Container 介紹。5、Windows Docker Container 的應用。6、Windows Docker Container 的 HA…等議題

1、容器技術商業化之前的虛擬化技術發展
虛擬化技術的五大類別(依據抽象化的程度):硬體(Intel VT-d, AMD-vi)、指令集(x86, alpha, sparc)、作業系統(Windows, Linux)、函式庫、應用程式…等。
虛擬化的歷史最早是在封閉式大主機的年代,當初為了將這些稀缺且珍貴的運算資源,能有更好的分享機制(一旦馬拉松等級的人口普查大任務要開始運算時,就要開始煩惱半天的股票交易要怎麼排進去,結束金融交易後又要擔心人口普查恢運算時資料不能有誤)以及降低系統導入或是升級的風險,將CPU, RAM, Disk等系統資源分割給獨立的邏輯/動態邏輯分區,來提供運作彈性、便利性以及使用率…
以下圖 Wikipedoa 的圖例來看,以往由硬體向上堆疊的虛擬化,可分為二個 type。如果不是裸機的 type2 虛擬化的應用,就是在Host機器上,虛擬出Guest機器又稱為VM(Virtual Machine)。其次再藉由共用的虛擬化硬體資源同時運行著各種工作負載,又維持其間的隔離性,讓基礎架構之間的移轉作業更加輕鬆,甚至還能根據需求彈性擴充。有了作業系統之後,可以再繼續堆疊 Windows Subsystem for Linux 之類的函式庫,最後就是Java, Dotnet 之類的應用程式來實現我們日常的應用。若要細分在 Windows 中還可以再區分以機碼為核心技術的第六個應用程式虛擬化的類別分支。(將來有機會再談)

出處 Wikipedia

虛擬化應用情境的三大類型:Hypervisor型虛擬化、主機型虛擬化、容器虛擬化。第一種又稱為裸機(不需要作業系統)虛擬化,主流的工具為 VMware ESXi, Microsoft Hyper-v, KVM;第二種又稱為寄居虛擬化,主流的工具為 VMware workstation player;第三種又稱為作業系統虛擬化,主流的工具有 Docker + 叢集管理平台(Orchestration) K8S。
在實務上,如果你想在Win10 上面安裝SQL2019企業版,安裝程式會出現需要Windows server才能安裝的錯誤訊息。透過虛擬化你可以輕易地運行一個Windows 2019 server的VM,讓你來裝好安裝開發測試所需的SQL2019 企業版。
舉個通俗的例子,假設我們想得到一個金髮碧眼輪廓深遂的女娃兒,我們來比較一下這三種虛擬化的差別。在沒有虛擬化時,會遭遇到的困難是,你需要娶一個外國老婆幫你生孩子但又不能保証一定生出女孩。在Hypervisor型虛擬化方面,它像是30歲身強體壯的代理孕母,你需要準備事先做過基因工程的試管嬰兒受精卵,然後就是靜候懷胎十個月的結果;在主機型虛擬化方面,就像是16歲尚未完成身體發育的年輕代理孕母,相同的是剛才的步驟,不同的是大家會預期孕母會需要更多的營養補充或是休息;在容器虛擬化方便,則是像在無菌的實驗室中直接Clone出女娃兒複製人,若能採用K8S則會像是駭客任務中母體Matrix,只需要將一個外國小孩身體連上裝置,就能高速地Clone分身並且傳送到另一個世界。

2、何謂 Docker Container與其技術原理?
首先 Docker是一家近代以 Container容器化為主力的軟體公司,它官網中是這樣定義容器化技術的 Package software into standardized units for development, shipment and deployment。其次,它獨霸一方的 Linux 環境上的容器化市佔,以及 Swarm 服務亮眼的銷售成績,甚至讓微軟決定要委託它開發 Windows Docker Container。

至於它的技術原理,接續剛才提及的傳統 Type1&2虛擬化,在下圖的最右邊加入了容器化的架構說明,Container 它以更高度共用的底層(N個 image 都會共用同樣的作業系統底層),以及更輕量的映象檔(例如 web server, database server…),再加上K8S 無所不在的母體來進行資源的調度。
汽車商有需要重新造輪子才能賣車嗎?請各位再仔細看一下這張圖,不管是 Type 1還是2,VM 中都會有 Guest OS的存在,雖然比較笨重,但是隨時可以決定Windows與Linux。相對而言右手邊的 Container 不能決定OS但是非常輕快,GB起跳的VM V.S. MB起跳的Container,至少就差了1024倍(從MB到GB)。

如果真的要細究 Container 能夠這麼輕量的最主要原因,就是他們採用了aufs (源自於 Linux)檔案系統來設計一個可以層層堆疊的 Container映像檔,將Container內的所有程式(包括應用程式、相關函式庫、設定檔),全都打包進 Docker映像檔,並且提供了一個 Dockerfile設定檔來記錄建立 Container過程的每一個步驟包括參數。只要在任何支援 Docker平台的環境中,就可以從這個映像檔來建立出一個一模一樣的 Container來執行同一個應用程式。如此一來,應用程式等於是可以透過 Docker映像檔,或甚至只需要 Dockerfile,就能將程式執行環境帶著走,移動到任何支援 Docker的環境中。Docker公司也釋出API,可以用來控制所有的 Container相關指令,任何人只要使用同一套 Docker,就等於有了同一套管理和建立 Container的方法,也就等同於將Container 運用標準化了。
下圖,就是一個唯讀的映像檔在作業系統上運行多個 Ubuntu Container的示意圖,不用安裝開機選單來切換多個 Linux,也不用跟IT要多個VM,一切就是這麼輕量且便利的使用資源。

3、容器化技術的效益與比較
容器化技術最大的舞台是在 DevOps(公司中寫程式、測試、Infra佈署是由不同人所負責的),藉由這個新技術的導入,企業因為可以在佈署的工作上,有效降低管理的複雜度、縮減佈署的時間、節省在環境面除錯的時間,進而能更專注在開發,達成 time to market 的目標。硬體虛擬化雖然是舊的技術,但它適用的應用情境比較廣。容器化技術雖然是最夯的新技術,但它僅能用在無UI的應用程式(可能是網站服務、貨幣匯率轉換服務、其他後台服務)。也因為它能將應用程式所需的程式碼、函式庫、環境配置檔…進行封裝,以利快速佈署至其他地方,將能為企業帶來更高效、更彈性、更自動化…等優勢。

容器化技術的優勢:

  • 隔離性好:它有二種模式,Process mode啟動快但隔離性較差(從Task manager工作管理員可以看到其他Container的Process,雖然看不到裡面的資料,但是有可能會被 Kill Process的誤刪風險);Hyper-V mode啟動較慢(一分鐘內)但隔離性較好(從Task manager中看不到,要從Hyper-V管理介面來看)
  • 可攜性好:在Kernel版本是對的,只需下載映像檔,就能順利運行,且不需考慮函式庫/程式安裝路徑…等問題)
  • 輕量且高速回應:啟動與關閉只要數秒鐘,最多不會超過一分鐘。在下圖中有15.04版本的ubuntu映像檔,包含了188MB的 Base基底,與不同的服務 web server, node.js …等,然後被執行為 N個 instance。
    不曉得各位有沒有同時在作業系統中執行多個應用程式的經驗?例如我們開2個 Word 來比較論文修改的前後。對作業系統來說,就是運行2個獨立的Process。(本來想舉開2個 IE或 Edge瀏覽器來做線上購物的比較情境,但是這個產品一直都被客戶用放大鏡檢視,他們很早就被改成 Multiple thread) 所以 Container就是把沒有UI的應用程式變得這麼簡單,例如在2個1分鐘,執行2個獨立的 Instance SQL Server。若你沒有這個技術,你光是安裝設定第一個 default instance就可能花了快一個小時,然後再花第二個小時安裝與設定另一個 name instance,2分鐘 v.s. 120分鐘,科技就是在幫助我們改善生活,有感覺到嗎?
  • 擴充性高:映像檔可隨時擴充與更新
  • 優化DevOps流程:以往常會聽 Programmer(PG)說,我的程式邏輯都對啊!在我自己的電腦測都可以!但是發佈到Server端就有問題,搞不好是後台的問題?現在這個問題將再也聽不到,因為PG在自己的電腦中運行Docker Container後,將會與Server端的環境是一致的
  • 增進企業內的 DevOps:由於 Docker是透過 Dockerfile來記錄建立Container映像檔的每一個步驟,所以可以將建立應用程式執行環境的過程和配置參數,完整地記錄下來。將來開發人員和維運人員之間可以利用 Dockerfile來溝通對執行環境的討論。甚至結合版本控制服務(例如GitHub),進而讓 Dockerfile具備版本控制功能,達成基礎架構程式化(Infrastructure as code)的崇高理念
  • 優化應用程式的生命週期:安裝Docker Server你將具有一個Docker daemon的服務,來回應Docker Client的請求。這二個角色可以裝在同一個電腦,沒有問題!當你安裝機這二個角色之後,你就可以將任一個唯讀的映像檔,運行成N個執行個體(Container);當然你可以隨時把Container修改後再Build成新的映像檔。至於Registry就是映像檔庫,它可以在地端找機器擔任或是採用雲端的服務(例如微軟的Azure Container Registry ACR,這個服務上傳/下載不收費,只收Storage儲存空間的錢)。舉例來說,我要架網站,我去微軟所提供的映像檔mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019 下載最乾淨且無毒的環境,但是下載後 wwwroot (放網站內容的資料夾)是空的,所以我可以把我的網站內容放進去,然後停止這個Container,接著把它 build成新的映像檔並且Tag為 1.0.0.1,成為我網站A的分支,將來好升級與改版。接下來我為了Load balance我就把這個映像檔,分別 Run成 name= Web01與Web02的 Container,所以這二網站裡面的內容是一模一樣,一但遇上江蕙的演唱會,我可以在數秒中 Run起N個網站來應付。將來要升級或改版很快!只要幾個指令就完成,當然你要自動化,還有Docker Compose來批次處理多個容器的大型環境的管理
  • 透過微服務來創新:根據 Docker 公司的說法,採用這種新一代的 Microservices(微服務)軟體架構,將能受惠良多。將組成一個應用系統的每一個Stack,拆解成許多小型服務,例如Apache服務、MySQL服務、Node.js服務、Ruby服務,每一個服務都只是包在Container裡的一支程式,這麼做的好處是可以建立一個鬆散耦合的彈性應用程式架構,也能輕易地抽換其中一個 Container,例如要升級MySQL,只需要重新載入新版MySQL的 Container映像檔,就可以完成資料庫升級,不用將整套應用系統停機。。如此一來,既容易橫向擴充,每支程式也容易升級;不會很大一包且除錯困難。這個架構將能成為企業創新所需的養份…

4、Windows Docker Container 介紹
接續一開始 Container 歷史的簡要介紹,早在硬體貴桑桑的1982年代Unix系統,就為了解決如何在高投資金額的的大型主機上評估新系統?推出了Chroot 讓新系統可以在舊主機上測試,不必先搬一台新的大主機(不管是誰出錢都是很大的投資!),接著Linux興起,在1998年代方興未艾 FreeBSD也推出了 jails,另外微軟也在 2004年推出了 Windows系統中的 Sandboxie(胎死腹中的產品),以上這些都屬於在作業系統內建立孤立虛擬執行環境的作法,都算在Container 的發展歷程中。一直到了 2013年的近代,dotCloud這家公司推出了Container 的 PaaS服務,名叫 Docker 受到市場熱烈的廻響(超過一億次的下載),乾脆重新用這個名字來開一家新公司,致力於開源 Container的推廣,以及發展其商務化的加值服務,包括 Swarm(Docker Enterpise)細節可以參考官網的說明。
故,在Windows 環境上運行 Container的解決方案的「Windows Docker Container」專案,就是微軟於2015年向 Docker 公司,為了趕上世界的潮流以及增加 Windows Server 2016的賣點,所提出了開發的委託。
其具體的作法,中間會有一個 Computing pool,它透過 Docker daemon 的常駐服務,允許使用者在 client端不管在本機或是遠端,隨時可以下達指令,讓唯讀的 Image 開始運行。右邊則是有一個標準化的映像檔庫來集中管理,所需的 Images。

再講深一點,在CI/CD持續整合/發佈的情境中,當程式邏輯, DB, Web…有新的改版時,是可以透過Yaml file 來程式化環境的參數版本,動態地組合出所需的運行環境。

另一個重點是使用 Windows Docker 有沒有額外的授權費用?稍早我們在圖例中有看到 Docker Server/Client 這二個角色,所以原廠的授權費用是有區分EE企業版與免費的CE社群版(只能提供給 Trial用途)。由於當我們購買 Windows Server CAL(Client access license 也就是常聽到的 1+5低消,一個伺服器節點與五個使用者節點)時,微軟已經吸收或者說包含了。換言之,如果在非 Windows的環境下(例如 Linux, MacOS) 上面使用 Docker 則是需要付費的,但是在Windows 上(包含在上面使用 Linux container)是沒有額外的費用,完全可以放心地使用。

5、Windows Docker Container 的應用
由於 Windows Server 2016以上 與 Windows 10(Desktop)是採用相同的程式碼基底 code base,所以Windows Docker Container,使用者可以享受到使用相同的 Image在這二個環境上運作。例如在Win10上開發,佈署至Windows Server 2016(或以上的版本)是常見的情境。
<網站>
比如說要開發一個江蕙演唱會的購票網站,PG開發時的環境跟將來Production的環境的一模一樣,他只需要專注在商業邏輯,買十張以上的折扣不能算錯。其次是,為了伺服器的硬體資源利用率,常常會在一台Web Server上面,以不同的檔案夾,同時去運行其他網站內容,例如太陽馬戲團或是其他活動的售票活動。可能會有衍生的 Connection pool、硬碟滿了、記憶體未能正常釋放與回收(程式寫不好)…資源排擠的風險,在Container上都能避免掉。
<DotNet應用系統>
比如說要開發一個貨幣匯率的換算服務,來支援外國人(含大陸同胞)購買江蕙演唱會,所以這個服務就可以支援數個商業演出的購票活動,需要時再找機器運行,一個Container撐不住,再起另一個只需要數秒鐘。
<SQL Server>
請注意資料庫運行在 Container僅適合開發測試環境,原因是資料庫的正式環境是多人存取比較複雜,而且還會有高 iops 寫入/讀取、多顆 CPU平行運算的硬體需求。不像網站較單純只會有CPU的資源瓶頸。當PG要開發一個系統,我們可以給他一個Container,裡面就有測試資料供他寫程式與驗證邏輯,但不適合寫入新資料。因為只要Container停止後,即使再啟動資料都不見了;若是PG要對DB寫入新資料,就要在 Run的啟動指令中,在參數中指定資料庫 mdf與 ldf檔案的位置給它,就能寫在Container之外把資料成功地保存下來,也不是難事!但隨著 AKS與 ACI的技術的成熟,慢慢有客戶開始把資料庫運行到 Production環境。
<映像檔管理>
ACR是一個全球化的服務,可以協助企業不必管理映像檔庫,將它佈署到雲端,並透過 Azure AD的高安全性驗證,IT高枕無憂。

6、Windows Docker Container 的 HA
挑戰一:由於Docker for Windows 的設計是在單一伺服器,能夠運行多個Container。但是當你生意愈做愈大,需要多台伺服器時來建置高可靠度的專業環境時,其實並不需要採用舊時的Cluster叢集技術。在舊技術中需要把一套應用系統的多個單元(例如Web Server, Midware Server, DB Server),在每個伺服器全部都佈署一遍,除了勞民傷財,也無法提供足夠的彈性在應付前端的商務變化。
為了比較,下圖是某個企業將其 Infra搬至 Azure的 Iaas環境,有錢的作法就是創建多個VM各司其職,沒錢就是Web/Logic unit/DB灌在同一個VM,然後以類似 Clone到另一個 VM來組成 Cluster的概念做 HA,並不是微服務。

多層式架構 (N-Tier) 的實體圖

挑戰二:在下圖中列出至少8種需求,包含了排程(明星商品在明天開賣,不需要讓工程師在凌晨12:00用微微出汗的手指頭戰戰兢兢地按下Enter進行切換上線,而是應該讓工程師吃著點心從容的,用Monitor界面來監控系統的上線)、資源排擠與任務編組(例如你有一組Web + DB,但是這個伺服器剛好只能放的下一個Container)、系統健康狀況檢視、容錯移轉、依業務的擴充來調度資源、網路資源的調度、服務狀況分析、升級與改版…
Orchestration)三雄,分別是 Google推出的Kubernetes(市佔率超過九成),以及目前比較式微的 Docker Swarm與 Apache Mesos。順應市場的發展,微軟也於2019年將支援協奏三雄的策略調整為以支援 Kubernetes 為主的AKS 與ACI 服務。

容器映像的 Azure Container Registry 異地複寫

細部的部署架構

地理路由與 Azure 流量管理員

7、其他:客戶曾經問過我,Windows Docker 是否支援 GUI或是 RDP?在官網上是說不行。但是我知道微軟的總部有在開發,類似Windows Server 2016 Hyper-V 中的巢式虛擬化(Nested Virtualization)功能,可以在Windows 10中再開出一個視窗裡面就是一套 Windows 10。等它有更進一步的消息我再更新給大家。或是先參考部落格的資料。同理在Linux 就是KVM的 Virtio

Windows Sandbox Screenshot - open.jpg

後續我將幫大家介紹:如何安裝Windowd docker?以及微軟在Azure推出的 Serverless Container服務…
Docker為微軟使用者寫的 Docker for Windows
微軟官網中的 Win10快速入門
微軟官網中 Windows Server快速入門

**2021更新,接著隨後市場的變化很快,在2015成立的 CNCF(Cloud Native Computing Foundation) 接手了容器化後續的發展,從下圖看來生態系是相當的豐富且完整。

這個連結可查看最新變化 https://github.com/cncf/landscape

李秉錡 Christian Lee
Once worked at Microsoft Taiwan