Docker和ASP.NET Core
Docker 正在逐漸成為容器行業的事實標準,受到 Windows 和 Linux 生態系統領域最重要供應商的支援。 (Microsoft 是支援 Docker 的主要雲供應商之一。)現在,Docker 基本上已經在各大雲或本地的任何資料中心普及了。
如何將.NET程式託管到Docker之中,相信這是廣大.NET開發者的一個疑問。事實上,.NET Framework 支援在Docker中執行,但是僅能在windows 容器中執行,這並不符合我們的預期,因此,本篇我們只側重於討論ASP.NET Core和Docker。
在使用之前,筆者還是有必要介紹下ASP.NET Core。如果您對此非常熟悉和了解或者對此節不感興趣,可以跳過本節。
ASP.NET Core簡介
ASP.NET Core是一個跨平臺的高效能開源框架,用於生成基於雲且連線 Internet 的新式應用程式。使用 ASP.NET Core,我們可以:
-
建置 Web 應用程式和服務、IoT 應用和移動後端。
-
能夠在 Windows、macOS 和 Linux 上進行開發和執行。部署到雲或本地。
-
在 .NET Core 或 .NET Framework 上執行。
-
能夠在 IIS、Nginx、Apache、Docker 上進行託管或在自己的程式中進行自託管我們的應用。
效能是.NET Core的一個關鍵特性,這裡有必要介紹下。在這塊,我們摘取了一份社群的測試彙總統計,僅供參考:
具體過程大家可以訪問此連結來檢視詳情:https://www.cnblogs.com/savorboard/archive/2016/10/17/dotnet-benchmarks.html
ASP.NET Core和Docker
剛才說了這麼多,我們回到主題。.NET Core天生就為跨平臺設計,並且和Docker搭配非常友好,而且微軟官方在這塊提供了很多支援。比如說:
- 輕量
- 跨平臺,天生對Linux友好
- 模組化
- 提供了輕量型容器映象高效能(領先於Java servlets、Go 和 node.js)
接下來,我們一起來了解官方映象。ASP.NET Core的官方映象名稱為microsoft/aspnetcore,微軟針對Docker上的 ASP.NET Core 應用進行了優化,因此容器可以更快啟動。為開發人員生成Docker映象時,Microsoft 側重於提供了以下主要方案:
- 用於開發和生成 .NET Core 應用的映象。
- 用於執行 .NET Core 應用的映象。
例如.NET Core 2.1,官方提供的映象:
為什麼是多個映象?因為在開發、生成和執行容器化應用程式時,通常具有不同的優先順序。 通過為這些單獨的任務提供不同的映象,有助於獨立優化開發、生成和部署應用程式的過程。在開發期間,我們側重的是開發更改的速度以及除錯的能力。在生產環境,我們側重的是應用部署和容器啟動的速度和效率。
這裡我們順便提下我們基於.NET Core 2.1開發的免費開源框架——Magicodes.Admin,其demo現在已經完全託管在Docker之中,部署在騰訊雲的容器服務之中,大家可以點選訪問測試下速度和穩定性,啟動速度這點沒得說。推薦訪問Https地址,因域名在備案之中,http域名可能無法訪問。
Magicodes.Admin開源庫地址:https://gitee.com/xl_wenqiang/Magicodes.Admin.Core
Demo地址:https://demoadmin.xin-lai.com
Admin
123456abcD
在本篇Docker教程中,我們會結合Magicodes.Admin的實踐進行講解,同時我們也會盡量提供一些實踐案例分享給大家,比如Magicodes.Admin demo、Magicodes雲服務、小程式商城(即將開源)、愛車APP等Docker完整託管案例,以便大家更易於理解和使用Docker。在Magicodes.Admin框架中,介面服務使用.NET Core 2.1開發,在docker上基於microsoft/dotnet:2.1-aspnetcore-runtime映象使用Kestrel web伺服器,後臺前端使用Angular開發,在docker上基於nginx映象使用nginx伺服器進行託管,並啟用了HTTPS支援和GZIP壓縮。
我們回過來繼續。.NET映象 (microsoft/dotnet) 同樣適用於基於 .NET Core 的控制檯應用。使用 Docker 和 .NET Core非常適用於生產部署和託管,主要有以下幾點:
-
無需本地安裝——可以直接使用 .NET Framework,而無需本地安裝。只下載相關的Docker 映象,其中包含 .NET Framework。
-
在容器中開發——你可以在一致的環境中開發,使開發和生產環境類似(可避免一些問題,例如開發人員計算機上的全域性狀態)。 通過VS的一些擴充套件外掛,我們甚至可以直接從 Visual Studio 啟動容器。
-
容器中測試——可以在容器中測試,減少由於環境配置不當或上次測試遺留的其他更改而導致的故障。
-
在容器中生成——可以在容器中生成程式碼。
-
在所有環境中部署——可以通過你的所有環境部署映象。 這種方法減少了配置差異導致的故障,通常通過外部配置(例如,注入的環境變數)改變映象行為。
注意:
Docker 映象容器可以在 Linux 和 Windows 上本機執行。 但是,Windows 映象僅能在 Windows 主機上執行,Linux 映象可以在 Linux 主機和 Windows 主機上執行(到目前為止,使用 Hyper-V Linux VM),其中主機是指伺服器或 VM。
注意:
.NET Framework也可以使用Docker進行託管,不過僅能託管到windows容器之中。
在具體應用和實踐之前,我們有必要了解以下內容。
Kestrel
Kestrel是一個基於libuv的跨平臺ASP.NET Core web伺服器,libuv是一個跨平臺的非同步I/O庫。ASP.NET Core模板專案使用Kestrel作為預設的web伺服器。
Kestrel支援以下功能:
-
HTTPS
-
用於啟用不透明升級的WebSockets
-
位於Nginx之後的高效能Unix sockets
Kestrel 被.NET Core支援的所有平臺和版本所支援。Kestrel 可以單獨使用,也可以與反向代理伺服器(如 IIS、Nginx 或 Apache)一起使用。 反向代理伺服器接收到來自 Internet 的 HTTP 請求,並在進行一些初步處理後將這些請求轉發到 Kestrel。
在沒有 Kestrel 或自定義伺服器實現的情況下,不能使用 IIS、Nginx 和 Apache。 ASP.NET Core 設計為在其自己的程式中執行,以實現跨平臺統一操作。 IIS、Nginx 和 Apache 規定自己的啟動過程和環境。 若要直接使用這些伺服器技術,ASP.NET Core 必須滿足每個伺服器的需求。 使用 Kestrel 等 Web 伺服器實現時,ASP.NET Core 可以控制託管在不同伺服器技術上的啟動過程和環境。
注意:
Kestrel 可以單獨使用,也可以與反向代理伺服器(如 IIS、Nginx 或 Apache)一起使用。在docker容器中,我們推薦使用Kestrel。
在大部分情況下,我們推薦使用反向代理伺服器。主要是有以下好處:
-
可以限制所承載的應用中的公開的公共外圍應用。
-
可以提供額外的配置和防護層。
-
可以更好地與現有基礎結構整合。
-
可以簡化負載均衡和 SSL 配置。 僅反向代理伺服器需要 SSL 證照,並且該伺服器可使用普通 HTTP 在內部網路上與應用伺服器通訊。
說了這麼多,總歸還是“紙上得來終覺淺,絕知此事要躬行”。我們來一起實踐:
首先我們需要安裝以下包:
Install-Package Microsoft.AspNetCore.Server.Kestrel -Version 2.1.3
然後就可以編寫啟動程式碼:
在上面的程式碼中,我們通過了配置檔案來配置Kestrel,我們也推薦大家使用配置檔案來配置Kestrel。相關配置Demo如下:
當然,我們也可以通過程式碼來配置kestrel:
按環境載入配置
ASP.NET Core 基於使用環境變數的執行時環境配置應用行為。ASP.NET Core 在應用啟動時讀取環境變數ASPNETCORE_ENVIRONMENT,並將該值儲存在 IHostingEnvironment.EnvironmentName 中。 ASPNETCORE_ENVIRONMENT 可設定為任意值,但框架支援三個值:Development、Staging 和 Production。 如果未設定 ASPNETCORE_ENVIRONMENT,則預設為 Production。
注意:
在Docker容器中,我們經常會修改ASPNETCORE_ENVIRONMENT環境變數來模擬開發、測試和生產環境。
因此在程式碼中,我們可以根據環境變數來啟用或關閉相應的功能,其中場景最廣泛的一點是——根據不同的環境載入不同的配置。同時,內建的環境變數配置提供程式(EnvironmentVariablesConfigurationProvider)還可以在執行時從環境變數鍵值對載入配置。具體見以下程式碼:
內建的日誌記錄提供程式
ASP.NET Core 提供以下內建日誌記錄提供程式,在很多情況下,對我們會很有幫助:
-
控制檯日誌提供程式
-
除錯日誌提供程式
-
EventSource日誌提供程式
-
EventLog日誌提供程式
控制檯日誌提供程式
在Docker環境下,為了便於排錯,我們推薦啟用此日誌提供程式。在平常的情況下,我們通過控制檯執行程式(比如通過dotnet run執行)也會輸出控制檯日誌。在使用之前,需要安裝以下包:
Install-Package Microsoft.Extensions.Logging.Console -Version 2.1.1
然後我們可以在程式碼中通過以下程式碼啟用:
logging.AddConsole();
完整程式碼如圖所示:
新增了之後,我們在雲端的容器服務的日誌中,就可以看到控制檯日誌了。下面以騰訊雲容器服務為例。首先開啟騰訊雲【容器服務】的【服務】頁面,如圖所示:
我們可以點選【日誌】操作按鈕的圖示來檢視日誌:
我們也可以點選具體的某個例項來檢視相關日誌,這裡就不多寫了。
注意:
通過控制檯日誌,我們可以輸出一些啟動資訊以用來做啟動診斷,同時我們也可以根據控制檯日誌來檢視請求狀況和執行狀況。
除錯日誌提供程式
和控制檯日誌一樣,也需要安裝相關依賴包:
Install-Package Microsoft.Extensions.Logging.Debug -Version 2.1.1
該包使用 System.Diagnostics.Debug 類(Debug.WriteLine 方法呼叫)來寫入日誌輸出。注意,在 Linux 中,此提供程式將日誌寫入 /var/log/message。
程式碼啟用方式如下所示:
logging.AddDebug();
EventSource日誌提供程式
包依賴關係如下:
Install-Package Microsoft.Extensions.Logging.EventSource -Version 2.1.1
該提供程式可實現事件跟蹤。不過值得注意的是,該提供程式尚無支援 Linux 或 macOS 的事件集合和顯示工具。期待官方提供相關工具。
而在windows server,可以通過開源工具https://github.com/Microsoft/perfview來收集和檢視日誌,如下圖所示:
EventLog日誌提供程式
需要新增包:Microsoft.Extensions.Logging.EventLog。
主要用於向 Windows 事件日誌傳送日誌輸出。
關於ASP.NET Core的相關內容,我們先介紹到這裡。接下來我們主要是圍繞Docker開發工作流程在進行講解。
搭建並使用Docker
Docker的安裝非常簡單,我們這裡僅以windows 10作業系統(推薦)為例進行講解。
安裝Docker
這裡以Docker for windows為例,其他環境請參考官網教程。
注意:
不推薦使用Docker Toolbox,Docker Toolbox適用於較舊的Mac和Windows系統。
要安裝 Docker,請先檢視用於 Windows 的 Docker:安裝須知瞭解相關資訊。
安裝須知連結:https://docs.docker.com/docker-for-windows/install/#what-to-know-before-you-install
注意:
使用Docker for windows需要啟用Hyper-V功能。以下是系統要求:
-
Windows 10 64位:Pro,Enterprise或Education(Build 14393或更高版本)。
-
在BIOS中啟用虛擬化。通常,預設情況下啟用虛擬化。這與啟用Hyper-V不同。
-
支援CPU SLAT的功能。
-
至少4GB的RAM。
Docker for Windows安裝包括:安裝提供 Docker Engine,Docker CLI客戶端,Docker Compose,Docker Machine和 Kitematic。
安裝包下載連結:https://store.docker.com/editions/community/docker-ce-desktop-windows
參考:https://docs.docker.com/docker-for-windows/
安裝完後,會提示點選重啟電腦。重啟後會自動啟動Docker程式,如果彈出下圖所示提示,則需要在Windows 功能中啟用Hyper-V功能和 在BIOS CPU配置中開啟 “虛擬化配置”,開啟之後,如下圖所示,虛擬化會顯示已啟用。反之安裝成功。
注意虛擬化已啟用,如下圖所示(這裡秀一把我NB的桌上型電腦,是不是比你們的伺服器都高階N個檔次):
以上配置完成後我們推薦將docker容器切換到Linux環境,選擇右下角Docker圖示右鍵選擇” Switch to Linux containers”進行切換,如果顯示” Switch to Windows containers”則已處於Linux容器。
這是我們可以測試Docker環境是否正常,開啟命令列,輸入docker –version:
注意:
我們推薦使用Linux容器服務,因為目前主流的容器系統是Linux,並且從資源的利用來說,Linux可以讓資源得到更大的利用。
關於docker的安裝和配置,這裡不再細說,大家可以關注我們的公眾號“magiccodes“來查閱相關的教程以及錄屏。
配置Docker本地環境
安裝完成並且啟動後,右下角有個小圖示:
右鍵開啟設定。
Docker for Windows 中的共享驅動器必須配置為支援卷對映和除錯。右鍵單擊系統托盤中的 Docker 圖示,單擊“設定”,然後選擇“共享驅動器”。 選擇 Docker 儲存檔案的驅動器。 單擊“應用”。
其他的配置我們這裡就不多說了,具體見公眾號“magiccodes”中提供的錄屏教程。
執行一個簡單的demo
我們先執行官方的Hello world示例:
docker run hello-world
我們也可以簡單執行一個web示例,比如:
docker run --name aspnetcore_sample --rm -it -p 8000:80 microsoft/dotnet-samples:aspnetapp
應用程式啟動後,使用瀏覽器開啟http://localhost:8000,即可看到以下介面:
Docker的安裝和配置在Windows 10作業系統下非常簡單,我們也極力推薦大家使用此環境。畢竟,一個好的開發環境可以大大提高大家的使用和開發效率。