传统.NET 4.x应用容器化体验(1)
我们都知道.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中直接通过浏览器访问:http://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上来体验一下。

传统.NET 4.x应用容器化体验(1)的更多相关文章
- 传统.NET 4.x应用容器化体验(4)
上一篇我们试着将.NET 4.x的镜像推送到harbor私有镜像仓库,本篇我们来使用一下阿里云的镜像仓库服务并了解一下携程的实践. 1 关于阿里云镜像仓库 阿里云容器镜像服务(简称 ACR)是面向容器 ...
- 传统.NET 4.x应用容器化体验(5)
前面几篇都是基于阿里云ECS直接玩的,有童鞋问直接用Windows Server 2019可以玩不,本篇就为你介绍一下如何给Windows Server 2019配置Docker环境. 1 准备工作 ...
- 传统.NET 4.x应用容器化体验(2)
上一篇我们基于Windwos Server 2019 with Container初步跑了一个ASP.NET WebForm应用程序.本篇我们来自己编译部署一个ASP.NET MVC应用程序到Wind ...
- 传统.NET 4.x应用容器化体验(3)
上一篇我们自己通过编写Dockerfile来编译部署一个ASP.NET MVC应用程序到Windows Container,这一篇我们来试着将.NET 4.x的镜像推送到harbor私有镜像仓库. 1 ...
- 容器化ICT融合初体验
[编者的话]本次将分享的容器化ICT融合平台是一种面向未来ICT系统的新型云计算PaaS平台,它基于容器这一轻量级的虚拟化技术以及自动化的"微服务"管理架构,能够有效支撑应用快速上 ...
- Rio手把手教学:如何打造容器化应用程序的一站式部署体验
11月19日,业界应用最为广泛的Kubernetes管理平台创建者Rancher Labs(以下简称Rancher)宣布Rio发布了beta版本,这是基于Kubernetes的应用程序部署引擎.它于今 ...
- Docker最全教程——MongoDB容器化(十二)
MongoDB容器化 MongoDB是一个免费的.开源的.跨平台分布式面向文档存储的数据库,由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和 ...
- 开箱即用,Knative 给您极致的容器 Serverless 体验
作者 | 冬岛 阿里巴巴技术专家 导读:托管 Knative 开箱即用,您不需要为这些常驻实例付出任何成本.结合 SLB 云产品提供 Gateway 的能力以及基于突发性能型实例的保留规格功能,极大 ...
- 4 个场景揭秘,如何低成本让容器化应用 Serverless 化?
作者 | changshuai FaaS 的门槛 Serverless 形态的云服务帮助开发者承担了大量复杂的扩缩容.运维.容量规划.云产品打通集成等责任,使得开发者可以专注业务逻辑.提高交付速度 ( ...
随机推荐
- 【源码解析】阿里在线诊断工具greys源码
撸起袖子加油干!开门见山! 一.源码下载 下载代码: git clone https://github.com/oldmanpushcart/greys-anatomy.git 二.源码分析 2.1 ...
- [leetcode] 68. 文本左右对齐(国区第240位AC的~)
68. 文本左右对齐 国区第240位AC的~我还以为坑很多呢,一次过,嘿嘿,开心 其实很简单,注意题意:使用"贪心算法"来放置给定的单词:也就是说,尽可能多地往每行中放置单词. 也 ...
- Lua 业务 脚本
Lua 脚本 #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice ...
- node.js学习(5)读写文件(同步异步)
1 导入文件系统库 # 同步的 读文件 写文件 # 异步 需要用异步处理耗时
- 学习Python中出现的错误集合(不定时更新)jupyter平台
出现的问题:1. 本图的错误,一个是line 7 init的两侧应该是是双下划线"__"导致所示错误 2. 本图的错误是 line 12 Student.student_tatal ...
- Python分析离散心率信号(中)
Python分析离散心率信号(中) 一些理论和背景 心率信号不仅包含有关心脏的信息,还包含有关呼吸,短期血压调节,体温调节和荷尔蒙血压调节(长期)的信息.也(尽管不总是始终如一)与精神努力相关联,这并 ...
- C++标准模板库(STL)——vector常见用法详解
vector的定义 vector<typename> name; 相当于定义了一个一维数组name[SIZE],只不过其长度可以根据需要进行变化,比较节省空间,通俗来讲,vector就是& ...
- 作为一名双非本科毕业的Java程序员,我该如何在日益严重的内卷化中避免被裁?
前言 对一个 Java 程序员而言,并发编程能否熟练掌握是判断他是不是优秀的重要标准之一.因为并发编程在 Java 语言中最为晦涩的知识点,它涉及内存.CPU.操作系统.编程语言等多方面的基础能力,更 ...
- Linux芯片驱动之SPI Controller
针对一款新的芯片,芯片厂商如何基于Linux编写对应的 SPI controller 驱动? 我们先看看 Linux SPI 的整体框架: 可以看到,最底层是硬件层,对应芯片内部 SPI contro ...
- Spring Cloud专题之二:OpenFeign
欢迎查看上一篇博客:SpringCloud专题之一:Eureka . OpenFeign是一种声明式的webservice客户端调用框架.你只需要声明接口和一些简单的注解,就能像使用普通的Bean一样 ...