原文:https://blogs.msdn.microsoft.com/dotnet/2018/06/18/staying-up-to-date-with-net-container-images/node
這篇文章描述了咱們爲你提供的生產和更新的容器鏡像,你能夠在 Docker ,Kubernetes 和其餘系統中使用。當你一塊兒用 .NET 和 Docker 鏡像的時候,你可能正在使用微軟官方的 .NET 容器鏡像。過去一年咱們對 .NET 鏡像作了不少改進來使你更容易封裝 .NET 應用。git
在上週的 DockerCon 2018 期間,我發部了關於同時使用 .NET 和 Docker 的更新。它展現瞭如何使用 Docker 和 .NET 進行生產、開發和測試。這些場景都是基於 Docker Hub 上的 .NET 容器鏡像。github
更快的軟件交付docker
Docker 是獲取和使用 .NET 更新的遊戲轉換器。回想幾年前。你能夠下載最新的 .NET Framework 做爲 Windows MSI 安裝包,直到咱們運行下一版本都不須要從新下載。快進到今天。咱們一個月推送屢次更新的容器鏡像到 Docker Hub。每次你拉取 .NET 鏡像,你就得到了更新的軟件,一個 .NET 和/或底層操做系統的更新,不管是 Windows 仍是 Linux。ubuntu
這種新的軟件交付模式更快而且在軟件生產者和消費者之間創建了更強的聯繫。它也給你更多的控制,但在如何經過 Docker 獲取軟件上須要多一點的知識。重要的是要了解軟件供應商的 Docker 倉庫(repos)和標記(tags)——這個例子的 Microsoft——這樣你就能夠獲得你想要的確切版本和更新。這篇文章旨在提供你須要的信息以便選擇你須要的 .NET 鏡像的最佳版本。windows
來自 Docker 的官方鏡像安全
Docker 維護操做系統和應用平臺的官方鏡像。這些鏡像是由 Docker 、熟練的社區開發者和指定技術(像 Alpine)的操做系統或應用平臺維護人員一塊兒來維護的。ionic
官方鏡像:學習
.NET 鏡像是使用官方鏡像構建的。咱們在 Alpine,Debian 和 Ubuntu 的 x64 和 ARM 的官方鏡像上構建。經過使用官方鏡像,咱們將按期更新操做系統基礎鏡像和包(例如 OpenSSL)的成本和複雜性留給最接近這些技術的開發人員。相反,咱們的構建系統配置了自動構建、測試和推送 .NET 鏡像,不管在咱們使用和更新官方鏡像。使用這種方法,咱們能以低成本在多個 Linux 發行版上提供 .NET Core 並在幾小時內發部更新。還能夠節省內存。.NET ,Java 和 Node.js 應用程序的組合在最同一臺主機上,例如最新的官方 Debian 鏡像,將在內存中共享 Debian 基礎鏡像。測試
來自 Microsoft 的 .NET 鏡像
.NET 鏡像不是 Docker 官方鏡像的一部分,由於他們僅由 Microsoft 維護。咱們也在上面構建 Windows Server 鏡像是相同的,相似於 Docker 官方鏡像,咱們有一個熟練於 .NET 和 Docker 的 .NET 鏡像。這樣的結果就是於上面描述的 Docker 官方鏡像相同的好處。
咱們用下列模型維護 .NET 鏡像:
咱們依靠 Docker 官方維護者及時地生成高質量的鏡像以便咱們的鏡像重視最新的。咱們知道你依賴咱們爲 .NET 作一樣的事情。咱們也知道當新的 .NET 鏡像可用時,許多人會自動重構建鏡像和包含的應用程序。很是重要的是這個過程運行良好,使你的應用程序老是運行在最新的 .NET 補丁版本和你選擇使用的軟件棧的其他部分上。這是咱們一塊兒工做的一部分以確保 .NET 應用程序在生產中安全可靠的。
.NET Docker Hub 倉庫
Docker Hub 是一個偉大的服務,存儲世界上的公共容器鏡像。當咱們第一次推送鏡像到 Docker Hub時,咱們建立了細粒度的存儲庫。許多細粒度的回購都有它的優勢,但可發現性不是其中之一。咱們聽到了很難找到 .NET 鏡像的反饋。爲了幫助這一點,咱們減小了咱們使用的倉庫數量。當前的 .NET Docker Hub 倉庫以下:
.NET Core 倉庫:
.NET Framework 倉庫:
廢棄倉庫:
.NET 鏡像標籤
在 Dockerfile 文件中使用的鏡像標記可能時各類 Docker-relaterd 資產中最重要的工件。標籤訂義了在運行 docker 構建預期要使用的底層軟件和應用程序將在生產中運行的。標籤讓你對你拉取的鏡像有不少控制,可是若是你使用的標籤不符合你的須要,它也多是痛苦的來源。
標籤有四種主要的選擇,從通常到最具體:
標籤是你想要的 .NET 版本上的一個合同。每次咱們運行時都盡力知足合同。咱們作兩個主要的事情來產生有質量的容器鏡像:CI 驗證和代碼審查。CI 驗證在幾個操做系統上運行,每次拉取請都請求到 .NET 倉庫。這一級別的預先驗證爲咱們提供了對推送到 Docker Hub 的 Docker 鏡像的質量。
對於每一個主要和次要 .NET 版本,咱們能夠採用一個新的主要操做系統版本依賴。正如前面提到的,咱們採用 Debian 9 做爲 .NET Core 2.0 的基礎鏡像。咱們爲 .NET Core 2.1 停留在 Debian 9。由於 Debian 10(又名 "Buster")尚未發部。Debian 9 仍然是 .NET Core 2.1 的默認基礎鏡像用於 .NET Core 2.1 的生命週期。一旦咱們採用了底層操做系統的主要版本,咱們就不會爲給定的 .NET 版本的生命週期而改變它。
每一個發行版都有本身的補丁模型。對於 .NET 補丁,咱們將採用較小的 Debian 版本,例如(Debian 9.3-9.4)。若是你查看 .NET Core Dockerfiles,你能夠看到各類 Linux 操做系統的依賴,如 Debian 和 Ubuntu。咱們在咱們支持的 Windows 和 Linux 操做系統的上下文和使用它們的社區中作出了有意義的決策。
Docker 的 Windows 版本控制與 Linux 不一樣,就像 multi-arch 標籤的工做方式同樣。簡單的說,當你在 Windows 上拉取一個 .NET Core 或者 .NET Framework 鏡像時,若是你使用 multi-arch 標籤,咱們將獲得一個與主機 Windows 版本匹配的鏡像(稍後會有更多關於這個的介紹)。若是須要不一樣的版本,則須要使用 Windows 版本的特定標籤。一些 Azure 服務,像 Azure Container Instances(ACI) 只支持 Windows Server 2016(在編寫時)。若是你的目標是 ACI,則須要使用 Windows Server 2016 標籤,例如 4.7.2-runtime-windowsservercore-ltsc2016 或者 2.1-aspnetcore-runtime-nanoserver-sac2016,分別是爲了 .NET Framework 和 ASP.NET Core。
.NET Core 標籤方案
在 microsoft/dotnet 倉庫中有多種鏡像:
咱們爲下面操做系統作了 Docker 鏡像:
.NET Core 支持多個芯片:
注意:ARM64v8 鏡像將在稍後時間提供,可能隨着 .NET Core 3.0。
.NET Core 標籤遵循一個方案,它描述了 .NET Core 支持的各類鏡像,操做系統和芯片的不一樣組合。
[version]-[kind]-[os]-[chip]
注意:這個方案是伴隨 .NET Core 2.1 的新方案,早期版本使用相似但稍有不一樣的方案。
下面 .NET Core 2.1 標籤是這個方案的例子:
注意:你可能注意到這些標籤中有一些使用了奇怪的名字。「bionic」 和 「stretch」 分別是 Ubuntu 18.04 和 Debian 9 的版本名稱。它們分別是 ubuntu 和 debian 倉庫的標籤名稱。「stretch-slim」 是 「stretch」 的小變種。當他們可用時咱們使用更小的鏡像。「nanoser-1803」 表明了 Windows Nano Server 的 Spring 2018 更新。「arm32v7」 描述了一個 32 位的 ARM 基礎鏡像。ARMv7 是由 ARM 控股公司定義的 32 位指令集。
它們也是 .NET Core 標籤的短格式。短格式有兩種不一樣的方式。他們使用兩部分版本號並跳過操做系統。在大多數狀況下,短格式標籤是你想要使用的標籤,由於他們更簡單、更容易維護而且是 multi-arch 的,所以能夠跨操做系統移植。
咱們建議你在 Dockerfile 中使用如下 .NET Core 的短格式標籤:
如上所述,一些 Azure 服務只支持 Windows Server 2016(而不是 Windows Server 1709 以上版本)。若是你使用其中之一,你可能沒法使用短標籤,除非剛好在 Windows Server 2016 上構建鏡像。
.NET Framework 標籤方案
在 microsoft/dotnet-framework 倉庫中有多種鏡像:
咱們爲下面 Windows Server 版本作了 Docker 鏡像:
.NET Framework 標籤遵循一種方案,它描述了各類鏡像的不一樣組合以及 .NET Framework 支持的 Windows Server 版本:
[version]-[kind]-[timestamp]-[os]
.NET Framework 版本號不使用 主版本.次版本.補丁版本 方案。版本號的第三部分不表明補丁版本。所以,咱們在標籤中添加了一個時間戳來建立惟一的標籤名。
下面 .NET Framework 標籤是這個方案的例子:
它們也有 .NET Framework 標籤的短格式。短格式有兩種不一樣的方式。它們省略時間戳和省略 Windows Server 版本。在大多數狀況下,這些都是你但願使用的標籤,由於它們更簡單、易維護而且是 multi-arch 的。所以能夠跨 Windows 版本移植。
咱們建議你在 Dockerfile 裏使用如下短格式的標記,例如 .NET Framework 4.7.2 和 3.5:
正如上面所討論的,一些 Azure 服務只支持 Windows Server 2016(不是 Windows Server 1709 以上版本)。若是使用其中之一,則可能沒法使用短標記,除非你碰巧只在 Windows Server 2016 上構建鏡像。
microsoft/aspnet 和 microsoft/wcf 使用這種標籤方案的變種,而且未來可能會移到這個方案。
安全更新和漏洞掃描
因爲你可能已經瞭解到這一點,因此咱們按期更新 .NET 鏡像,以便你可使用最新的 .NET 和操做系統補丁。對於 Windows,咱們的鏡像更新本質上相似於 Windows 團隊在 Windows 更新上提供的常規「星期二補丁」版本。事實上,咱們經過最新的 Windows 補丁更新咱們的 Windows 基礎鏡像在每一個星期二補丁。你不能在容器中運行 Windows 更新。你能夠經過 Docker Hub 上的最新的容器鏡像從新構建。
在 Linux 上的更新體驗更加微妙。咱們支持多個 Linux 發行版本,能夠隨時更新。沒有具體的時間表。此外,一般有一組發部的漏洞(AKA CVEs)是未修補的,其中沒有可用的修復。這種狀況並不特別適用在容器中使用 Linux,但一般使用 Linux。
有客戶問咱們爲何 .NET Core Debian 的基礎鏡像沒法進行漏洞掃描。我使用 anchore.io 進行掃描,並驗證了客戶與咱們共享的一樣的掃描。漏洞來自咱們使用的基礎鏡像。
你能夠查看我查看的相同掃描:
個人一個觀察結果是,Debian 和 Ubuntu 的掃描結果隨着時間的推移而顯著改變。對於 Alpine,它們保持穩定,報告的漏洞不多。
咱們採用三種方法來部分緩解挑戰:
這三種方法給了你不少選擇。咱們建議你使用 .NET Core 鏡像,使用你選擇的 Linux 發行版的最新版本。若是你更關心 Linux 上的漏洞,請使用 .NET Core 2.1 Alpine 鏡像的最新補丁版本。若是你仍然不滿意這種狀況,那麼考慮使用咱們的 Nano Server 鏡像。
使用預發行鏡像
咱們保持一個預發佈 Docker Hub 倉庫,dotnet-nightly。在 .NET Core 2.1 發佈以前夜間構建的 .NET Core 2.1 鏡像在那個倉庫中可用。目前該倉庫中有夜間構建的 .NET Core 1.x 和 2.x 服務分支。不久以後,你將看到能夠測試夜間構建的 .NET Core 2.2 和 3.0。
咱們也提供 .NET Core 和 Linux distros 的預發佈版本。在它發佈前咱們提供 Ubuntu 18.04(又名 「bionic」)。咱們目前提供 .NET Core 鏡像與 Debian 10(又名 「buster」)的預發佈版本和 Alpine edge 分支。
結束語
咱們但願使你可以輕鬆直觀的使用咱們爲 Windows 和 Linux 生成的官方 .NET 鏡像。Docker 提供了一個偉大的軟件交付系統使它很容易保持最新。咱們但願你如今擁有了配置 Dockerfile 和構建系統所需的信息,以便使用爲你的環境提供服務特性和鏡像一致性的標籤樣式。
當咱們收到反饋和 Docker 特性發生改變時,咱們將繼續對 .NET 容器鏡像進行更改。咱們在 dotnet/announcements 按期更新。「watch」 這個倉庫以跟上最新的更新。
若是你是個 Docker 新手,請使用 .NET 和 Docker 一塊兒檢查。它解釋瞭如何使用 Docker 在各類場景中使用 .NET。咱們也爲 .NET Core 和 .NET Framework 提供了義域使用和學習的示例。
在評論中告訴咱們你如何一塊兒使用 .NET 和 Docker。咱們很想知道你使用 .NET 和容器的方式以及你但願看到的改進。