.NET 和 Docker結合使用

許多與我交流的開發者要麼在積極地使用 Docker,要麼計劃在他們的環境中採用容器技術。容器是我們這個行業的一個重要趨勢,.NET 是其中的一部分。 Microsoft 和 Docker 一直在合作,以便在開發 .NET 應用時,使用 Docker 可以有一個良好的體驗。


Docker生態系統始於 Linux 技術。你可以在 Linux 和 .NET Core 上使用同其他開發平臺一樣的 Docker 工作流。.NET 團隊經常會在 Docker Hub 的 microsoft/dotnet 倉庫中更新 Debian 鏡像。


Windows 團隊最近發佈了 Windows Server 2016,並更新了 Windows 10,而且在 Windows 上支持了容器。現在 .NET Core和 .NET Framework 都可以與 Windows 容器結合使用。


上述支持在使用 Docker 構建和打包 .NET 應用的方式上提供了很多選擇。這篇文章介紹了其中的一些選擇,並提供了入門信息,即使你是個 Docker 新手也沒關係。


爲什麼選擇容器?

下面列出了開發人員遷移到容器的關鍵原因:


  • 一致性:容器包括應用程序及其所有依賴項。不管是在計算機、本地環境或是雲端,應用程序都執行相同的代碼。

  • 輕量級:通過使用基於主機操作系統的最小量級抽象,並在容器之間共享公共資源,容器可以快速啓動並使用最少量的 RAM。

  • 共享性:容器鏡像可以通過 Docker Hub、Docker Store 和私有 Docker 倉庫(如 Azure 鏡像倉庫)輕鬆實現分享。

  • 簡單而強大:DockerFile 格式(容器鏡像的 recipe)是一種可以實現強大場景的簡單格式:優雅地將操作系統和容器的特定命令結合,並且還可以創建 Docker 鏡像層。


想象一下,五年前如果有人在面試中告訴你,他們非常關心一致性,所以需要經常與應用一起部署操作系統。當時你可能不會僱傭他們。然而,這正是目前 Docker 的典型應用場景!


例如,如果需要爲 .NET 團隊添加容器的測試用例。我們會將基礎設施的重要部分轉移到容器上,以便從容器的優勢中受益,而不是簡單地“在 Docker 容器中測試 .NET”。這種方法爲我們提供了雙重優勢:在容器中運行 .NET 的高度信心以及更加高效的整體流程和更低的成本。 在這個案例中,我們每年爲基礎設施實驗室節省了一個人力的時間成本和每年10萬美元的雲服務機器成本。我很高興我們能夠節省這些費用。


Docker 在 .NET 應用中的使用場景

使用 Docker 和 .NET 應用程序的最典型場景是用於生產環境部署和託管。 事實證明,生產環境部署只是一種場景,而針對其他場景 Docker 同樣有用。 這些場景雖然不是 .NET 特有的,但應同樣適用於大多數開發平臺。


  • 低摩擦安裝——在機器上無需安裝任何東西,只需下載一個預裝 .NET 的 Docker 鏡像,你就可以嘗試使用 .NET。

  • 在容器中開發——你可以在一致的環境中開發,開發環境和生產環境非常相似(這樣可以避免一些諸如開發機中的全局狀態等此類的問題)。Visual Studio Tools for Docker 甚至可以直接從 Visual Studio 中啓動容器。

  • 在容器中測試——你可以在容器中進行測試,減少由於環境配置錯誤或上次測試遺留的其他更改導致的失敗。

  • 在容器中構建——你可以在容器中構建代碼,無需爲多個環境正確配置共享的構建機器,而是轉爲 “BYOC”(自帶容器)的方法。

  • 在測試環境、staging 環境、生產環境以及其他環境中部署——你可以在所有環境部中部署同一個鏡像,減少由於配置不同導致的失敗。通常只通過外部配置(例如,注入的環境變量)來更改鏡像的行爲。


如何入門


現在可以在 Windows、MacOS 或 Linux 上使用 .NET 容器。 首先,你需要一個 Docker 客戶端,最佳獲取途徑是 Docker.com。 如果是在 Windows 平臺上,請下載 Docker for Windows(穩定版本)。 Docker 同時支持 Windows 和 Linux 容器。 如果你是 Azure 用戶,可以查看 Docker Edition for Azure(https://docs.docker.com/docker-for-azure/)。


如果你是 Docker 新手,建議你在 Docker 文檔中查看 Docker 入門(https://docs.docker.com/get-started/)部分,我也是從那入門的。該說明使用 Linux 容器,但如果你不是 Linux 用戶,也不用擔心,你可以找到與你使用的操作系統對應的 Docker 客戶端使用說明,以及針對通用 Docker 概念和機制的指南。


接下來,可以嘗試使用我們提供的 .NET 與 Docker 結合使用的示例。 這些示例應該可以幫助你開始使用 .NET 和 Docker。 我們創建了兩組樣本,因爲 .NET Core 和 .NET Framework 之間的關鍵不同在於需要不同 Dockerfile 和其他組件。


  • .NET Core + Docker 示例(https://github.com/dotnet/dotnet-docker-samples)

  • .NET Framework + Docker 示例(https://github.com/microsoft/dotnet-framework-docker-samples)


我們 push 了一些鏡像到 Docker hub,以便大家可以更加容易地使用它們:


  • .NET Core 示例鏡像(https://hub.docker.com/r/microsoft/dotnet-samples/)

  • .NET Framework 示例鏡像(https://hub.docker.com/r/microsoft/dotnet-framework-samples/)


通過使用示例鏡像,你可以在機器上嘗試 .NET,而無需安裝任何東西( Docker 除外)。也就是說,我認爲在本地環境中嘗試示例仍然是充分體驗和評估 .NET 與 Docker 的最佳實踐。


例如,針對 .NET Core,可以嘗試以下 Linux 鏡像(如果使用Docker for Windows,請務必切換到 Linux 容器):


docker run microsoft/dotnet-samples


Docker Hub 中的 .NET


使用 .NET 與 Docker 的一個重要方面是要依賴 .NET 團隊提供的 .NET 基礎鏡像。 爲什麼使用 .NET 基礎鏡像是一個好主意呢?至少有以下四個原因:


  • .NET 團隊提供了基礎鏡像,所以你不必再造輪子。

  • .NET 團隊會定期更新鏡像,其中包括一些針對安全性的更新。

  • 當多個應用程序在同一臺機器上使用相同鏡像時,Docker 共享這些鏡像的內存。鏡像必須相同才能共享。

  • Docker 會掃描鏡像來發現安全漏洞,可以提供有關環境的更多信息。


我們將 Docker 鏡像發佈在 Docker Hub 上幾個不同的倉庫中。 鏡像分割很重要,這樣可以在 Docker Hub 以及 docker search 命令中更容易找到它們。


  • microsoft/dotnet——適用於 Linux 和 Nano Server 的 .NET Core 運行時 和 SDK 鏡像。

  • microsoft/aspnetcore — 適用於 Linux 和 Nano Server 的ASP.NET Core 鏡像。

  • microsoft/aspnetcore-build——適用於 Linux 和 Nano Server 的 ASP.NET Core 鏡像,用於構建應用程序。

  • microsoft/dotnet-framework——適用於 Windows Server Core 的 .NET Framework 3.5 和 4.6.2 鏡像。

  • microsoft/aspnet——適用於 Windows Server Core 的 .NET Framework 3.5 和 4.6.2 ASP.NET 鏡像。


我們也在 Docker Hub 上發佈了示例,以便大家可以更加容易地使用。


  • microsoft/dotnet-samples——.NET Core 示例。

  • microsoft/dotnet-framework-samples——.NET Framework 示例。


基礎鏡像的使用說明及示例可以參照上述提供的 Docker Hub 鏈接。 如果你剛剛接觸 Docker 分層概念,我們建議你閱讀 Docker 關於理解鏡像、容器和存儲驅動(http://t.cn/RWZvwe4)的文檔。


定義 Docker 鏡像


Docker 鏡像(包括 .NET 鏡像)由一個相對簡單的 Dockerfile 格式文件定義。你可以在上述提供的 Docker Hub 倉庫中找到每個鏡像的 Dockerfile 文件的鏈接。


這些文件定義鏡像內容和其他特徵。在多數情況下,我們會研究其他平臺對鏡像的處理,並嘗試遵循行業規範。也有一些情況下,我們會選擇做一些最適用 .NET 應用程序的工作,這些工作可能會也可能不會適用於其他平臺。 通常情況下,Docker 員工爲其他平臺創建初始化鏡像,所以我們在 Docker Hub 上看到的自由“複製”模式實際上只是在追隨 Docker。隨着 Docker 規範的變化,我們將盡最大努力地將這些變化應用在 .NET 鏡像上。


Dockerfile 源文件存儲在 GitHub 上。 你可以關注我們關於鏡像的進展。如果你願意的話,也可以看看我們製作鏡像的原因並參與討論。


Docker 鏡像標籤化


Docker 鏡像具有隱藏 ID(例如,d99acb94e777),用於默認識別。 因爲 ID 對用戶來說並不是很有用,所以我們可以給 Docker 鏡像打標籤。標籤通常是描述鏡像用途的的友好名稱,例如 “hello-world-app”。該機型在本地運行良好。


在 Docker Hub 上,倉庫名稱爲鏡像的名稱,標籤通過版本號或其他標誌來消除倉庫中鏡像的歧義。


.NET Core 標籤

對於 .NET Core,標籤用於描述以下三個維度的鏡像差異:


  • .NET Core 版本——.NET Core 1.0, 1.1 and 2.0(撰寫本文時)。

  • .NET Core 分佈——.NET Core 運行時,.NET Core SDK, .NET Core dependencies 依賴項。

  • 操作系統基礎鏡像——Windows 和 Linux。


dotnet 倉庫的一個重要選項是打上 latest 標籤。我們決定 latest 標籤總是指向最新的 .NET Core SDK 版本。例如,作爲RTM時,latest 將更新指向 .NET Core SDK 2.0。


替代方案是將 latest 映射到 .NET Core 運行時。我們認爲,SDK是你起步的最佳鏡像,一旦你體驗了較大的 SDK,就可以更容易地做出優化的選擇。我們最近做出了一些改變 .NET Core Docker 鏡像使用連拱 (multi-arch) 標籤。 此改變可以讓你減少對上述第三個維度的考量。這意味着你的 Dockerfile 文件不再需要定義要使用的操作系統。


.NET Framework 標籤


對於.NET Framework,標籤僅在一個維度上描述鏡像差異:


  • .NET Framework 版本 — 3.5, 4.6.2


latest 標籤對應最新版本的 .NET Framework。當鏡像可用時,latest 將會更新並指向 4.7 版本。


倉庫分割

關於如何構建倉庫沒有現成的硬性規定。下面這條是個不錯的參考:


從倉庫中執行 docker pull 拉取到的鏡像,應當是一個意義明確的鏡像,倉庫中的其他鏡像應當緊緊圍繞與默認鏡像相關的附加概念而存在。


倉庫中的標籤越多,其中某些鏡像應當屬於其他倉庫的可能性越大。 這是我們正在討論的東西,與 Docker 方面也在討論這個問題。我們希望將 .NET Core 倉庫分爲兩個或三個,這樣便於用戶使用。不幸的是,目前沒有比較好的機制來找到其他相關聯的庫。我們希望這個問題可以得以解決,這樣我們可以更加自由的分割倉庫。


更新鏡像

.NET 鏡像經常更新,有時是安全性更新。可以通過執行 docker pull 下載這些更新,docker build 不會從服務器請求更新。


對於 Windows 鏡像, 在 .NET 的 Dockerfile 定義中依賴了一個特定的基礎鏡像,具體可以參考microsoft/dotnet:1.0-runtime-nanoserver Dockerfile 中的第一行,如下:


FROM microsoft/nanoserver:10.0.14393.1198


在“補丁週二”(每個月的第二個星期二),Windows團隊通常會發布補丁並更新其基礎圖像,.NET 鏡像也會更新。


對於 Linux 鏡像,.NET Dockerfile 中定義依賴了一個更通用的基礎鏡像,該鏡會隨時間發生變化。目前,.NET Core 選用 Debian Jessie,並向 Jessie 發佈更新(例如8.6 到 8.7)。你可以在 microsoft / dotnet:1.0-runtime-deps Dockerfile Dockerfile 定義的第一行看到,如下所示:


FROM debian:jessie


Debian 倉庫包括 Debian Stretch(Debian 9)的鏡像,這是Debian Jessie(Debian 8)之後的一個版本。我們不會將使用 Debian Jessie 的 .NET Core 標籤自動前滾到 Debian Stretch,但會像其他平臺一樣,爲其創建一個新標籤。


遷移 .NET Framework 應用到容器


如果有工具可以將 VHD 轉換爲容器,豈不是讓人很興奮?


在 DockerCon 2017 上,一款名爲 Image2Docker 的工具着實令人興奮,它可以將 Windows VM 遷移到容器。該工具由 Docker 在 GitHub 上維護。


Image2Docker 的 PowerShell 模塊可與 VHD,VHDX 或 WIM 鏡像文件一起使用,並生成可構建 Docker 鏡像的高保真 Dockerfile。該工具可以幫助你構建一個與 VHD 相同的 Docker 鏡像,同時還能發揮 Docker 的優勢。Image2Docker 雖然不會構建出最漂亮的 Dockerfile,但對於希望將 .NET Framework 應用遷移到容器的用戶來說,這是一個不錯的開始!


更多信息可參考 DockerCon 演講之 Image2Docker(https://www.youtube.com/watch?v=YVfiK72Il5A),或者閱讀 Docker 官方文章:使用 Image2Docker 將 ASP.NET 服務轉換爲 Docker(https://blog.docker.com/2016/12/convert-asp-net-web-servers-docker-image2docker/)。


: 運行 Image2Docker 需要安裝 Windows版本的 Docker。


結語

作爲一個團隊,我們至今已持續大約兩年的時間專注於 .NET 與 Docker 的結合。期間,我們針對 Docker 的方案發生了很大變化,很大程度上是爲了適應了 Docker 生態系統的快速變化。我們本身也大量使用 Docker。 我們將繼續調整步伐來確保 .NET 是容器化應用程序的最佳平臺之一。


在此,我想爲在 Docker 工作的同事點贊。我們一直在與他們其中的很多同事合作,致力於 .NET 和 Docker 更好地結合。當我們提出可以讓 .NET 開發人員更友好的改進時,Docker 的同事也很樂意接受建議。連拱標籤和多級構建是我們早期參與而獲益的一個良好示例。


原文鏈接:https://blogs.msdn.microsoft.com/dotnet/2017/05/25/using-net-and-docker-together/


本文轉自(微信訂閱號),僅作爲收藏,如有侵犯請聯繫:

http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=2649695480&idx=1&sn=cce270660e7286f8ff15c7f45c073036&chksm=88931b9bbfe4928d3bfa6dbb04dfc74f55a33b1425cff1c571d17fdab128ecb997eca00699ec&mpshare=1&scene=23&srcid=1031MAi0W1XIAvR0GGEn9ml6#rd


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章