傳統.NET 4.x應用容器化體驗(1)
- 2021 年 7 月 18 日
- 筆記
- .NET, 【002】ASP.NET WebForm, 【003】ASP.NET MVC, 【005】雲原生, docker
我們都知道.NET Core應用可以跑在Docker上,那.NET Framework 4.x應用呢?藉助阿里雲ECS主機(Windows Server 2019 with Container版本),一切變得So Easy!
1 關於Windows Container
自從Windows Server 2016版開始,原生Docker就得到了支援,在這之前,想要在Windows系統上運行Docker(包括Windows 10),都得先裝一個Hyber-V的虛擬機,然後在虛擬機上跑Docker,完全無法發揮Docker在進程隔離級別的優勢。
下圖展示了兩種模式的區別:
可以確定的是,無論是哪種運行模式,我們都可以使用標準的Docker命令行進行操作,同時容器鏡像的格式也和Linux容器鏡像保持一致。
畫外音:這就意味著Windows Container可以通過docker hub或私有鏡像倉庫如Harbor進行分發,我們之前在Linux容器上的經驗積累也可以平滑遷移到Windows容器上。
但是,Windows Container受限於Windows內核屬性,只能跑Windows應用程式,比如和Windows內核強耦合的.NET Framework應用程式。這一點,也是攜程等.NET應用大戶選擇Windows Container的原因。而攜程曾經的問題,也正是目前我司所遇到的痛點,即在.NET與Java雙技術棧並存的前提下,如何統一運行環境和打包部署機制,成為了一大難題。在.NET 4.x(廣大核心業務系統)、.NET 5(部分新興服務) 與 Java (電商業務)應用共存的異構技術棧背景下,.NET 4.x又無法同時快速升級到.NET 5的歷史包袱前提下,統一運行環境 和 編排流程 對於整個技術團隊來說是很有必要的,而容器化帶來的紅利也應該要讓.NET Framework 4.x 應用程式享受到。
2 關於阿里雲ECS與ACK
在現今企業伺服器OS市場,Windows依然佔據半壁江山,其市場份額達60%之多,把Windows應用搬站上雲不僅僅是基礎設施的遷移,更重要的是通過Kubernetes等雲原生技術讓傳統的Windows應用架構體系升級,充分利用雲上的彈性、敏捷等能力,實現業務應用的快速迭代和交付。
阿里雲ECS主機率先提供了 Windows Server 2019 with Container 與 Windows Server Version 1909 with Container 兩個OS鏡像,滿足了.NET應用程式跑在Windows Container上的需求。Windows Version 1909鏡像是指運行在伺服器核心模式下不含UI版本的系統,Version 1909不含UI沒有圖形介面,佔用伺服器資源少。而Windows Server 2019 with Container鏡像版本,是指Windows鏡像是在原有的鏡像基礎上增加了Docker容器運行環境,如果在使用過程中需要Docker容器運行環境則可以選擇with Container版本鏡像。
更令人興奮的是,阿里雲容器服務已正式發布Windows Container支援,用戶可通過控制台或Open API創建Windows Kubernetes集群並部署Windows容器。
阿里雲容器服務ACK通過Windows容器的支援,幫助企業輕鬆實現Windows容器應用的部署,其兼容kubernetes標準,支援cpu/memory資源編排,支援deployment/statefulset/job/cronjob等應用部署模型。同時用戶可以添加Linux節點,實現Linux/Windows應用混合部署的統一管理。
想要進行Windows Server Node + Linux Node混合管理的童鞋,可以考慮一下阿里雲ACK服務。
3 快速開始
本篇會主要介紹在藉助阿里雲ECS(Windows Server 2019 with Container鏡像版本)來實現.NET 4.8應用的容器化初步運行。
第一步,選擇阿里雲ECS主機,在OS鏡像區域選擇Windows Server 2019 with Container鏡像。
第二步,遠程登錄阿里雲ECS主機,查看docker版本與資訊。由於該鏡像版本已經設置好了Docker運行環境,因此無需再手動安裝(如果是Windows Server 2019鏡像版本的話則需要手動安裝)。
> docker version Client: Mirantis Container Runtime Version: 20.10.5 API version: 1.41 Go version: go1.13.15 Git commit: 105e9a6 Built: 05/17/2021 16:36:02 OS/Arch: windows/amd64 Context: default Experimental: true Server: Mirantis Container Runtime Engine: Version: 20.10.5 API version: 1.41 (minimum version 1.24) Go version: go1.13.15 Git commit: 1a7d997053 Built: 05/17/2021 16:34:40 OS/Arch: windows/amd64 Experimental: false
此外,阿里雲已經提前設置好了鏡像加速,因此也無需手動配置daemon.json設置鏡像加速源。
> docker info Client: Context: default Debug Mode: false Plugins: app: Docker Application (Docker Inc., v0.8.0) cluster: Manage Mirantis Container Cloud clusters (Mirantis Inc., v1.9.0) registry: Manage Docker registries (Docker Inc., 0.1.0) Server: Containers: 1 Running: 1 Paused: 0 Stopped: 0 Images: 4 Server Version: 20.10.5 Storage Driver: windowsfilter Windows: Logging Driver: json-file Plugins: Volume: local Network: ics internal l2bridge l2tunnel nat null overlay private transparent Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog Swarm: inactive Default Isolation: process Kernel Version: 10.0 17763 (17763.1.amd64fre.rs5_release.180914-1434) Operating System: Windows Server 2019 Datacenter Version 1809 (OS Build 17763.1999) OSType: windows Architecture: x86_64 CPUs: 1 Total Memory: 1.92GiB Name: yz-jc-poc-ecs ID: P7LP:34B5:PQHH:YVKG:ADDM:5KOQ:6ATZ:CWNW:M74Z:D7SM:WAZO:R66T Docker Root Dir: C:\ProgramData\docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false
第三步,Run一個.net framework控制台示例容器:
docker run --rm mcr.microsoft.com/dotnet/framework/samples:dotnetapp
運行結果如下圖所示:
我們也可以看到這個示例鏡像的大小,WTF,真的不小!
> docker images REPOSITORY TAG IMAGE ID CREATED SIZE mcr.microsoft.com/dotnet/framework/samples dotnetapp 52c54f01bc20 3 weeks ago 8.03GB
第四步,Run一個asp.net webform示例容器:
docker run --name aspnet_sample --rm -it -d -p 8000:80 mcr.microsoft.com/dotnet/framework/samples:aspnetapp
需要注意的是,這裡映射到主機的埠是8000,需要在阿里雲ECS控制台的安全組裡為其開放入網規則。
在Windows Server 2019中,對容器支援localhost的訪問(在2019之前,只能通過容器IP或本機IP地址訪問),因此可以在ECS中直接通過瀏覽器訪問://localhost:8000
這時,從外部瀏覽器訪問公網IP地址:8000也可以訪問到這個ASP.NET應用程式了。
如果你想了解容器的具體IP,你可以使用下面的這個命令:
docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" aspnet_sample
如果你想進入這個示例容器內部看看,你可以使用下面這個命令:
docker exec -it aspnet_sample powershell
進入這個容器的工作目錄(這裡是/inetpub/wwwroot),你會看到一堆ASP.NET WebForm的Release文件:
> docker exec -it aspnet_sample powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. PS C:\inetpub\wwwroot> ls Directory: C:\inetpub\wwwroot Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 6/9/2021 9:35 AM App_Start d----- 6/9/2021 9:47 AM bin d----- 6/9/2021 9:35 AM Content d----- 6/9/2021 9:35 AM fonts d----- 6/9/2021 9:47 AM obj d----- 6/9/2021 9:35 AM Properties d----- 6/9/2021 9:35 AM Scripts ......
你也可以在容器內部訪問localhost(默認80埠)驗證一下:
> iwr -useb http://localhost StatusCode : 200 StatusDescription : OK Content : ...... ParsedHtml : RawContentLength : 5096
4 總結
本文介紹了Windows Container的基本概念、阿里雲ECS與ACK對Windows Container的支援,然後介紹了如何在阿里雲ECS(Windows Server 2019)上進行.NET 4.x應用的容器化部署運行。
下一篇,我們會自己通過編寫Dockerfile的方式來部署一個ASP.NET MVC應用程式到Docker上來體驗一下。