Docker4Dev #6 使用 Windows Container 运行.net应用

关于d4d系列:之前这个系列叫做docker4dotnet,因为当时主要是为了能够探索在docker上运行.net应用;现在我觉得应该叫做docker4developer,因为我希望能够帮助更多的开发人员使用docker技术。今天这篇就算是新的Docker4Dev系列的开始,后续我会陆续发布更多的帮助开发人员使用容器的文章。


随着 Windows Server 2016 的正式发布,Windows Container也可以被部署到生产环境了。Linux Container存在的时间很久了,但是直到2013年Docker的出现我们才有了一种很简单的方式来使用Container技术,而在Windows平台上,类似的Container技术其实也存在很长时间了,但是由于Windows本身的一些特点,我们一直很难(就算经过复杂的配置)使用类似Linux Container的完整应用级别的隔离。这其中的原因我个人觉得主要是因为Windows的封闭性,造成社区无法按照自己的要求对其进行改进。2013年Docker发布后,对整个IT市场造成的冲击巨大,微软同样也感受到了威胁,对于Container技术的追赶也随即开始,让人感到欣慰的是,微软这次没有再次采用闭门造车的方式,而是采用了更加开放的方法与社区合作,接受社区中已有的工具和方法;Windows Container对于Docker工具链的良好支持就说了这一点。


因此,如果你熟悉Docker,那么这篇文章的内容对你没有什么新奇之处;但是如果你像我一样是个在Windows平台上工作多年的开发人员,就会发觉其中的好处。


你需要怎样的环境?

首先,搭建一个可以运行 Windows Container 的环境有3个选择:Windows Server 2016, Windows 10 和 Nano Server。另外,你需要了解 Windows Container 有2种不同的运行模式:Windows Server Container 和 Hyper-V 模式。这其中的区别请见下图:


其实在我们运行的时候,你是感觉不到其中的区别的,你仍然使用熟悉的 docker run 命令来启动容器,不过操作系统会根据上面表格所列自动的选择当前平台上的默认Container类型运行你的容器。


如果你希望尝试 Windows Container, 最简单的方式就是安装 Windows 10 (专业版或者企业版),然后安装 Docker for Windows 的工具。具体方法可以参考:https://docs.docker.com/docker-for-windows/


这里我准备了一个简单的PowerShell脚本,直接运心就可以完成启用Windows 10上的Container和Hyper-V功能,由于Windows 10只能运行Hyper-V Container,所以一定需要打开这个功能才可以。

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
Enable-WindowsOptionalFeature -Online -FeatureName containers -All
Restart-Computer -Force


用Docker支持传统 .net 开发

之所以说“传统”,这主要是为了和 .net core做区分,因为.net core本身是跨平台的,所以完全可以使用 Linux Container 来运行(具体请见之前的d4d系列文章),也就不需要 Windows Container 的支持,当然你也可以使用 Windows Container 来运行 .net core,这完全没有问题。但是我觉得大多数 .net 开发人员还是更加关心自己的 .net 2.0/3.5/4.5 应用如何使用 Container。


在配置好以上所需要的开发环境之后,你就可以用 Visual Studio 进行传统.net应用的开发,并用docker完成Windows Container的镜像打包和运行了。只是有一点,你需要将你的Docker for Windows 工具切换到 Windows Container的支持上才行。


一旦完成了切换,你用 docker 所做的所有操作就都转向 Windows Container 了。(注:这其实只是现在的一个折中做法,未来的 docker 工具一定是可以同时操作 Windows 和 Linux 两种 Container 类型的)。


首先我们用 Visual Studio 2017 来创建一个 asp.net 4.5的应用程序,然后F5运行一下,确保程序可以正常启动。


现在,我们来添加一个Dockerfile,为了区分我把它命名为 Dockerfile.windows


以下是这个Dockerfile.windows的内容

FROM harbor-bj.devopshub.cn/microsoft/iis
SHELL ["powershell"]RUN Install-WindowsFeature Net-Framework-45-ASPNET ; \Install-WindowsFeature Web-Asp-Net45ARG source=.
WORKDIR 'c:\app'RUN Remove-Website -Name 'Default Web Site'
RUN New-Website -Name 'aspnet45docker' -Port 80 \-PhysicalPath 'c:\app' -ApplicationPool '.NET v4.5'EXPOSE 80
COPY $source .


注意几点:

1. 为了能够更快的下载基础镜像,我这里使用了LEANSOFT在北京的harbor站点;这里我已经预先同步了Docker Hub上的基础镜像。
2. 建议大家先预先下载这个基础镜像,因为 Windows 的基础镜像都很大 (WindowsServerCore 有4个G,NanoServer也有400M)
3. 这个Dockerfile中使用了 PowerShell 作为脚本引擎,所以后续你看到的命令都是 PowerShell 命令,比如: Install-WindowsFeature, New-Website 等等。

说实话,这个Dockerfile写得很顺手,毕竟之前对PowerShell的熟悉程度还是超过了shell script,这可能是 Windows 开发人员的好消息。


现在你就可以用熟悉的方式“发布站点”到本地文件夹,然后在里面进行 docker build 了,为了保证这个Dockerfile.windows可以被正常的复制到发布站点中,我还添加了一个Post-Build 脚本,确保每次发布都自动复制这个Dockerfile.windows 文件。


在发布完成的目标目录内运行以下命令就可以打包了

docker build -f Dockerfile.windows -t aspnet45web01:win-v1 .


好了,现在启动Container

docker run -itd -p 81:80 aspnet45web01:win-v1

进行到这里,用过 Docker for Windows 的同学一定会打开浏览器 http://localhost:81 来访问站点,但是你啥也看不到;这是因为 Docker for Windows 对 Windows Container 的支持还不够完整,没有进行 localhost 的自动映射,所以你需要使用 docker inspect 来获取容器的 ip 地址,然后通过 ip地址直接访问。

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" <container id>


打开以上命令获取的ip地址,注意不要用 81 端口,而使用容器本身的80端口,因为我们是直接对容器进行访问。现在你就可以看到一个传统的.net 4.5应用运行在 Windows Container中了,如果你注意看了我的 Dockerfile,你就知道这个站点实际是跑在 IIS 上面的。


一点感受

Windows Container虽然已经可以投入生产了,但是就和 Docker 刚刚出现时一样存在一些问题,最大的问题是镜像文件太大。上面说了,WindowServerCore镜像4个G,这确实是有点夸张。我觉得微软的目的是为了能够用同样的镜像同时支持Windows Server Container和Hyper-V Container,毕竟Hyper-V Container是作为一个VM存在的,用一个完整的操作系统镜像就可以同时在2中模式上运行,这样当然是有好处的,因为大家不用考虑不同的运行模式而改用不同的基础镜像。但是我觉得从技术上,如果采用 Windows Server Container,微软应该是可以提供非常小的基础镜像,类似 docker 提供的空镜像,这样对第一次部署容器会有很大的性能提升。


但是话说回来,当你第一完成一个容器部署后,因为基础镜像已经存在,每次更新的数据就只有很小的部分(只是应用程序本身),这样后续的部署速度还是很快的。


另外,对于Hyper-V Container的存在的目的,我觉得除了可以提供更好的容器隔离能力(因为是VM,所以根本就是2台机器,不存在共享内核的问题),另外一个重要的目的就是在Windows平台上支持Linux Container的运行。希望微软的动作可以更快一点,毕竟你有全球最好的开发人员,没有什么是技术上做不到的。


相关文章:

docker4dotnet #1 – 前世今生 & 世界你好

docker4dotnet #2 容器化主机

docker4dotnet #3 .net猿和小鲸鱼的苹果山之旅

docker4dotnet #4 使用Azure云存储搭建高速 Docker registry

docker4dotnet #5 使用VSTS/TFS搭建基于容器的持续交付管道



推荐一个培训

基于Docker的DevOps实战培训】是由徐磊老师主讲的三天封闭式收费课程,地点北京,时间2017年03月24-26日。课程结合了徐磊老师多年来在DevOps上的实践经验和Docker技术,具有很强的实战意义。详细内容及报名方式点击“阅读原文”。


内容转载自公众号

DevOps
DevOps
了解更多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows 容器

什么是容器 它们是隔离、资源控制且可移植的操作环境。 基本上&#xff0c;容器是一个隔离的位置&#xff0c;应用程序可在其中运行&#xff0c;而不会影响系统的其他部分&#xff0c;并且系统也不会影响该应用程序。 容器是虚拟化的下一个演化。 如果你在容器内&#xff0c;看…

选择排序+推导过程

图解 代码实现 package com.atguigu.sort;import java.util.Arrays; import java.util.List;/*** 创建人 wdl* 创建时间 2021/3/21* 描述*/ public class SelectSort {public static void main(String[] args) {int []arr{101,34,119,1};System.out.println("排序前"…

Echart折线图 柱状图

echat_百度搜索 Examples - Apache ECharts Examples - Apache ECharts Examples - Apache ECharts 修改左侧的数据 点击右侧下载可以得到html页面 Examples - Apache ECharts Examples - Apache ECharts

软件定义数据中心—Windows Server SDDC技术与实践

《软件定义数据中心—Windows Server SDDC技术与实践》是国内第一本讲解微软Windows Server 软件定义数据中心的中文图书&#xff0c;书中系统、全面地介绍了微软Windows Server 软件定义数据中心各个模块&#xff08;SDS/SDN/SDC/容器&#xff09;的概念、技术和架构&#xff…

插入排序+思路分析

图解 代码实现 package com.atguigu.sort;import java.util.Arrays;/*** 创建人 wdl* 创建时间 2021/3/22* 描述*/ public class InsertSort {public static void main(String[] args) {int[] arr{101,34,119,1};insertSort(arr);}//插入排序public static void insertSort(in…

.NET 十五岁,谈谈我眼中的.NET

2002年2月13日&#xff0c;第一个版本随着visual studio.net的发布&#xff0c;今天已经走过15年, .net团队写了一篇文章&#xff0c;里面有一个视频&#xff0c;Anders Hejlsberg已是白发苍苍的老人&#xff0c;我也从刚出校门的码农长成软件开发工程师&#xff0c;我爱编程。…

理解并从头搭建redis集群

部分开发人员工作当中只是在应用中使用redis&#xff0c;比如用来做数据结果的缓存。而且现在有很多不错的redis客户端工具(redisson)&#xff0c;基本上可以不用关注redis命令就可以完成相当部分的功能。所以可能会对如下这些问题关注点不够&#xff1a; 如何容灾&#xff1f;…

希尔排序+过程分析

图解 代码实现 package com.atguigu.sort;import java.util.Arrays;/*** 创建人 wdl* 创建时间 2021/3/22* 描述*/ public class ShellSort {public static void main(String[] args) {int[] arr {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};shellSort(arr);}//使用逐步推导的方式来编写…

Java 程序员必须掌握的 5 个注解

转载自 Java 程序员必须掌握的 5 个注解 自 JDK5 推出以来&#xff0c;注解已成为Java生态系统不可缺少的一部分。虽然开发者为Java框架&#xff08;例如Spring的Autowired&#xff09;开发了无数的自定义注解&#xff0c;但编译器认可的一些注解非常重要。 在本文中&#xff…

Docker4Dev#7 使用 Windows Container运行ASP.NET MVC 2 + SQLExpress 应用

上一篇Windows Container文章中给大家介绍了如何使用Windows Container运行一个传统的.net 4.5 web应用程序&#xff0c;当时我们使用了默认的Visual Studio模版创建了一个简单的项目&#xff0c;而且没有链接数据库。我相信使用.net进行应用开发的程序员们一定在想&#xff0c…

Mybatis+MySQL动态分页查询数据经典案例

最近在用Mybatis做项目的时候遇到了不少问题&#xff0c;今天我就在这和大家分享一下&#xff0c;稀稀拉拉的研究了两天&#xff0c;终于搞好了&#xff01;开发人员&#xff1a;1111开发软件&#xff1a;Myeclipse用到的框架技术&#xff1a;Mybatis数据库&#xff1a;MySql主…

那些年的骗子

中午一觉睡醒之后&#xff0c;忽然发现多年不联系的初中同学给我发了个消息&#xff0c;觉得事情没那么简单&#xff1a;正好我的公众号需要大量的用户&#xff0c;我就顺水推舟了&#xff01;一看到QQ的安全提示&#xff0c;我就感觉事情确实不妙&#xff01;初步推断对方是个…

干货 | 彻底弄懂 HTTP 缓存机制及原理

转载自 干货 | 彻底弄懂 HTTP 缓存机制及原理 前言 Http 缓存机制作为 web 性能优化的重要手段&#xff0c;对于从事 Web 开发的同学们来说&#xff0c;应该是知识体系库中的一个基础环节&#xff0c;同时对于有志成为前端架构师的同学来说是必备的知识技能。 但是对于很多…

Visual Basic的未来之路

上周&#xff0c;微软宣布了他们改变Visual Basic语言未来发展计划的想法。这次公布给Visual Basic开发人员留下了很多不确定性&#xff0c;但Visual Basic语言的设计者Anthony D.Green说明了这个新策略的一些细节。 Green首先列出了当时使用VB进行开发的四个基础指导原则&…

快速排序+思路分析

图解 代码实现 package com.atguigu.sort;import com.sun.org.apache.xpath.internal.WhitespaceStrippingElementMatcher;import java.util.Arrays;/*** 创建人 wdl* 创建时间 2021/3/22* 描述*/ public class QuickSort {public static void main(String[] args) {//[-9,78,…

jquery sleep函数

function sleep(n) { //n表示的毫秒数 var start new Date().getTime(); while (true) if (new Date().getTime() - start > n) break; } console.log(new Date()); this.sleep(3000); console.log(new Date());

2017 年编程语言排行榜:Python 排第一

站长之家(ChinaZ.com) 7 月 24 日消息&#xff0c;近日根据 IEEE Spectrum 发布的研究报告显示&#xff0c;在 2016 年排名第三的 Python 在今年已经成为世界上最受欢迎的语言&#xff0c;C 和 Java 分别位居第二和第三位。IEEE Spectrum 的排行依据数据记者 Nick Diakopoulos …

Spring 获取 request 的几种方法及其线程安全性分析

转载自 Spring 获取 request 的几种方法及其线程安全性分析 本文将介绍在Spring MVC开发的Web系统中&#xff0c;获取request对象的几种方法&#xff0c;并讨论其线程安全性。 一、概述 在使用Spring MVC开发Web系统时&#xff0c;经常需要在处理请求时使用request对象&…

2的负x次幂图像_数学| NO.2,3 函数 T15

点击蓝字&#xff0c;关注我们函数题目2020.11.30#2,3函数 T15函数发展&#xff1a;函数就是在某变化过程中有两个变量X和Y&#xff0c;变量Y随着变量X一起变化&#xff0c;而且依赖于X。如果变量X取某个特定的值&#xff0c;Y依确定的关系取相应的值&#xff0c;那么称Y是X的函…

AspNet Identity 和 Owin 谁是谁

英文原文:http://tech.trailmax.info/2014/08/aspnet-identity-and-owin-who-is-who/ 最近我发现Stackoverflow上有一个非常好的问题.提问者问:为什么在调用AuthenticationManager.SignIn后,claim仍然可以被添加到Identity并持久化到cookie里. 示例代码如下所示: ClaimsIdenti…