天天看點

Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(二)

Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(二)

出品丨Docker公司(ID:docker-cn)

編譯丨小東

每周一、三、五,與您不見不散!

目前,有大量的應用程式以 Docker 容器的形式運作在 Windows Server 2016 上,但 Windows 容器一直與 Linux 容器在性能方面存在着一些細小的差距。但是,在已經到來的 Windows Server 2019 中,它彌補了大部分的性能差距,是以現在的 Windows Docker 容器幾乎與 Linux 容器旗鼓相當。接下來,我将介紹餘下的内容,點選下列标題了解前一部分内容:

使用 VIP 服務發現

接下來将介紹 Docker Swarm 模式的第二個增強功能。Swarm 通過 DNS 提供服務發現,是以容器可以通過服務名稱互相引用,Docker 将其解析為容器的 IP 位址。這是一種使用現有技術連接配接服務的非常簡單的方法,是以它對于在容器中運作的應用程式是透明的。

服務發現有兩種模式:VIP 和 DNSRR 模式。VIP 模式使用的是虛拟 IP 位址,當容器進行 DNS 查詢時,它在響應中獲得單個 IP 位址,該位址是虛拟位址。網絡層實際上是将其路由到運作服務副本的某一個容器中。DNSRR 模式也是 DNS 循環,DNS 響應包含所有容器IP 位址的清單,以随機順序提供負載均衡。

VIP 模式是更好的選擇,因為它不會對緩存 DNS 響應的用戶端(幾乎每個DNS用戶端)造成任何問題。如果在服務中替換容器,則虛拟IP位址保持不變,并且用戶端請求将始終路由到活動的容器。如果用戶端緩存響應,DNSRR 模式可能會出現問題,因為響應是單個容器的 IP 位址,當更換該容器時,用戶端無法通路該服務,直到 DNS 緩存過期并獲得新響應。

DNSRR 有很好的用途,特别是對于使用 DNS 發現叢集中其他節點的叢集技術。在 Docker Swarm 模式中管理負載均衡和擴充叢集也涵蓋了這一點。

Windows Server 2016 僅支援 DNSRR 服務發現,但 Windows Server 2019 不僅支援 DNSRR 服務發現還支援 VIP 服務發現。與入口網絡一起,這意味着您可以在群集模式下運作高度可用、高度可擴充和彈性的服務。

我已經為 Docker 示例投票應用程式添加了 Windows 1809 版本。您可以使用此 Docker 應用棧檔案在 Windows 1809 版本的叢集上運作該應用程式,該檔案使用入口網絡和 VIP 服務發現:

Docker 示例投票應用程代碼: https://github.com/dockersamples/example-voting-app
iwr -useb -outf docker-stack-windows-1809.yml ` 
 https://raw.githubusercontent.com/sixeyed/example-voting-app/master/docker-stack-windows-1809.yml
 
docker stack deploy -c .\docker-stack-windows-1809.yml vote
           

現在,您可以在叢集中的任何節點上浏覽到在 5000 端口上的投票應用程式,并且四個投票應用程式容器中的一個容器将處理該請求:

Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(二)

做出選擇後,應用程式将向運作在容器中的 CNCF-incubating NATS 消息隊列發送消息,然後三個消息處理程式容器中的一個容器将處理消息并将資料存儲在與 mysql 相容的 TiDB 資料庫中 —— 在容器中運作。浏覽到 5001 端口,您将看到來自投票結果應用程式的總數。

這些都是基于 1809 版本的 Windows Nano Server 基礎鏡像建構的小鏡像。

卷挂載具有可用的目錄路徑

Docker 卷(Volume)是您将存儲與容器生命周期分開的方式。您将卷附加到容器,它将作為容器檔案系統中的一個目錄出現。您的應用程式寫入“C: jenkins”(或您安裝的任何路徑)并且資料實際存儲在卷中,該卷可能存儲在 Docker 主機上。就像伺服器上的 RAID 陣列,或資料中心中的單獨存儲單元,或雲存儲服務。

容器内的挂載應該對應用程式透明,但實際上在 Windows Server 2016 中使用的是符号連結目錄,這就導緻了一些問題。

這是一個基本問題,首先運作互動式 Windows Server Core 2016 容器,Docker 卷将本地目錄挂載到容器内的目标 C: mount 中:

docker container run -it --rm ` 
 -v C:\temp:C:\mount `
 microsoft/windowsservercore:ltsc2016
           

檢查容器中的目錄清單,你會看到“C: mount”實際上是 SYMLINKD(符号連結目錄)類型,它映射到一個危險的檔案路徑“ [\?ContainerMappedDirectories…”:

Microsoft Windows [Version 10.0.14393] 
(c) 2016 Microsoft Corporation. All rights reserved.
 
C:\>dir C:\ 
 Volume in drive C has no label.
 Volume Serial Number is 5AC2-AFC5
 
 Directory of C:\
 
11/22/2016 11:45 PM            1,894 License.txt 
10/22/2018 01:01 PM       mount [\\?\ContainerMappedDirectories\C4CCB043-FA0A-49DE-88F0-F408917EC284] 
06/28/2018 07:55 PM   
         PerfLogs 
06/28/2018 08:04 PM   
         Program Files 
07/16/2016 02:18 PM   
         Program Files (x86) 
10/22/2018 01:01 PM   
         Users 
10/22/2018 01:01 PM   
         Windows 
              1 File(s)         1,894 bytes  
              6 Dir(s) 21,218,250,752 bytes free
           

這會導緻底層語言嘗試解析符号連結并使用目标路徑的應用程式出現問題,因為它們會識别雙反斜杠和問号。

這個問題在 Windows Server 2019 中将不再是問題。在運作 Docker 的 1809 版本的機器上運作相同的指令:

docker container run -it --rm ` 
 -v C:\temp:C:\mount `
  mcr.microsoft.com/windows/servercore:1809
           

現在清單顯示“C: mount”作為标準目錄:

Microsoft Windows [Version 10.0.17763.1] 
(c) 2018 Microsoft Corporation. All rights reserved.
 
C:\>dir C:\ 
 Volume in drive C has no label.
 Volume Serial Number is 961D-F4E8
 
 Directory of C:\
 
09/15/2018 10:42 AM            5,510 License.txt 
10/04/2018 11:08 AM   
         mount 
09/15/2018 05:44 PM   
         Program Files 
09/15/2018 10:42 AM   
         Program Files (x86) 
09/15/2018 10:45 AM   
         Users 
10/22/2018 01:05 PM   
         Windows 
              1 File(s)         5,510 bytes
              5 Dir(s) 21,242,155,008 bytes free
           

它仍然是一個使用容器外部存儲的卷,由Docker管理,但現在它對應用程式完全透明。将我的 Windows Server 2019 的 Jenkins Dockerfile 與我的 Windows Server 2016 的 Jenkins Dockerfile 進行比較,你會發現它更容易閱讀。

卷挂載可以覆寫現有目錄

Windows Server 2016 還存在一些其它的關于卷的問題。一個是如果該目錄已經存在于 Docker 鏡像中,則無法使用目标目錄進行卷挂載操作。

許多應用來說都存在這個問題,,因為配置目錄附帶了鏡像中的預設配置檔案。在 Linux 上,您可以運作容器并使用卷的内容覆寫 config 目錄。但在 Windows 2016 上您就不能這樣做了,您必須編寫一個 Dockerfile 來打包你的自定義配置。

或者使用 Web 伺服器,如果您想使用預設鏡像,又想從卷中提供自己的内容,那麼您将從 Windows Server 2016 中收到錯誤提示:

PS> docker container run -d ` 
 -p 8041:80 `
 -v C:\web:C:\nginx\html `
 sixeyed/nginx:windowsservercore-ltsc2016
 
13f9f189ef9b5a73b700b79556aa002fd8fb3ce5f70ced21e364d5b4ac708446
 
C:\Program Files\Docker\docker.exe: Error response from daemon: container 13f9f189ef9b5a73b700b79556aa002fd8fb3ce5f70ced21e364d5b4ac708446 encountered an error during CreateContainer: failure in a Windows system call: The directory is not empty. (0x91) extra info:
           

您得到的錯誤消息 —— 該目錄不是空的。

在 Windows Server 2019 中解決了該問題。現在,您可以在現有目錄上挂載卷并替換其内容,是以容器可以檢視卷的内容而不是鏡像中的内容:

PS> docker container run -d ` 
 -p 8041:80 `
 -v C:\web:C:\nginx\html `
 sixeyed/nginx:windowsservercore-1809
 
42ed3441e2e2cebc37cac6ecac927ece45c65f877d4c072be4f5ff2dcef7ddcf
           

在 Windows Server 2019 中将不再出現該問題的錯誤提示了。 現在,當我浏覽應用程式時,我會看到我的網頁,而不是預設的 Nginx 頁面:

Windows Server 2019 的6處變化,提升您的 Windows 容器體驗(二)