【编者的话】本文的作者是微软的Azure平台的工程师,去年年底微软就宣布开源.Net核心运行时,并与Mono合作以推进.Net在Linux等非Windows平台的移植。同时,微软也宣布将在新一代的Windows服务器上支持Docker,支持容器化部署,这让我们看到了微软拥抱开源的决心。本文介绍了如何在Linux中使用Docker容器部署基于ASP.NET 5的应用程序。
作为ASP.NET 5跨平台部署实现的一部分,我们正在为简化ASP.NET应用部署、兼容Linux或者Mac OS X等操作系统运行而努力工作。最近,我们发布了首个ASP.NET的Docker镜像:ASP.NET 5预览版Docker镜像。
Docker是一个开源的项目,目的是在Linux操作系统下轻松的以沙箱的方式运行应用程序。当你下载了ASP.NET 5的Docker镜像,你就有了一个能够运行ASP.NET 5应用程序的Linux环境;现在你所要做的仅仅是在这个镜像中添加你的应用程序,然后启动一个容器,运行它,发布它。
本教程中我们为你展示如何在微软Azure云上利用Docker在Linux操作系统中部署一个使用ASP.NET 5预览版编写的简单的Web应用程序。这个教程中的例子可以在Linux、Mac OS X或者所有能装Docker客户端的操作系统下运行(如果喜欢,你也可以远程登录Linux虚拟机运行)。当然,当你安装了Docker的Windows客户端,你就能在Windows上运行本文中的例子。以后,如果Window Server支持容器化部署了,你就能使用Docker在Windows Server中来管理Windows Server的容器了。
注:文中所有的演示流程与代码都是基于ASP.NET 5(vNext)预览版的,在正式发布后运行的方式可能会有所不同。所以,到时候如果读者需要知道如何使用Docker部署ASP.NET 5的应用程序,还请自行登陆ASP.NET 5的Docker Hub页面或者GitHub仓库去参看最新的部署文档。
第一步:创建运行环境
现在Docker还只能在Linux上运行,所以你必须找一台Linux机器或者装了Linux虚拟机的机器来运行Docker;你在这里可以找到Docker的安装步骤或者通过参考这篇文章Getting Started with Docker On Azure(在Azure云端安装Docker的起步教程)。当然你可以从Azure云获取一个安装好Docker的Linux虚拟运行环境。
这个教程假设你已经在Azure上有了安装好Docker的Linux虚拟机。如果你拥有其它类似的运行环境,那这个教程也是可以使用的。
第二步:为你的ASP.NET 5应用创建一个Docker镜像
为了能让ASP.NET应用程序在云端部署,你需要一个Docker镜像来承载你的应用。
Docker镜像的文件系统是层叠式的(AUFS文件系统),可以这样形象的理解:你的应用程序只是“基础镜像”上层新加的一个层而已(译者注:就像盖房子一样,新增的楼层是基于它下面的楼层建立起来的),而在我们的例子中“基础镜像”为microsoft/aspnet(译者注:这是一个Docker镜像的名称,这个镜像存在于Docker Hub中)。在Docker中镜像的层级是增量叠加起来的(译者注:这点跟Git原理一样),Docker保存了每个层之间的差异,所以当我们用Docker部署应用时,提交的更新不会包含Linux发行版内核或者ASP.NET的运行时,因为这些都已经存在于“基础镜像”中了,你只会提交基于此“基础镜像”构建的应用程序本身,所以Docker的这种差异化提交、部署机制能够确保应用程序以最快速、最小化的增量方式进行部署,为运维带来极大的便利。
如何创建Docker镜像呢?答案是使用:Dockerfile。跟Makefile相似,Dockerfile包含了供Docker用来构建一个镜像的所有步骤。
本教程所用到的ASP.NET源代码可以从GitHub的aspnet/Home仓库下的HelloWeb目录提取。首先,使用如下命令将源代码从GitHub上克隆下来:
切换到aspnet-Home的sample目录下:
完成后目录结构应该如下所示:
然后我们在此目录下创建一个名叫Dockerfile的文件,并输入如下指令:
让我们逐条解释此Dockerfile中命令的含义:
第一行中
FROM
命令后面的‘microsoft/aspnet’说明我们要下载Docker Hub中名为‘microsoft/aspnet’(此镜像也是ASP.NET在Docker Hub上的官方镜像)的镜像作为我们例子程序的“基础镜像”;COPY
命令告诉Docker在构建镜像的时候同时将当前目录(译者注:.
表示当前目录)下的所有文件(译者注:Startup.cs、image.jpg与project.json这三个文件)拷贝到容器的/app
目录下;紧接着,使用WORKDIR
命令告诉Docker将容器启动目录设置为/app
目录;RUN [kpm, restore]
命令告诉Docker运行kpm restore
命令安装ASP.NET相关依赖项,这些都是Docker在第一次运行此容器之前要做的准备工作;EXPOSE 5004
命令会告诉Docker正在构建的镜像有个监听5004号端口的服务(可以查看project.json文件确认)(译者注:意思是以此镜像为基础运行的容器需要向外暴露5004号端口);最后,
ENTRYPOINT [k, kestrel]
命令说明每次用Docker启动此容器时都会自动执行k kestrel
命令,同时通过运行此命令保证容器始终在运行不退出,其实kestrel
命令就是启动了ASP.NET 5的服务器,启动此服务器后会启动一个监听5004号端口的进程,处理HTTP连接请求。(译者注:这就是为什么要向外暴露5004号端口的原因。)
第三步:创建镜像
当我们编写完Dockerfile后,当前目录应该是如下结构,Dockerfile和程序源代码在一起:
现在我们来创建此Docker镜像。这个过程非常简单——运行Docker的build
命令即可,命令如下:
这条命令运行结束后Docker就生成了一个名为myapp的镜像;同时,你对镜像所做的任何变化都能通过重新运行此命令来生成一个新的镜像。在你的Linux虚拟机或者开发环境中运行docker images
命令可以看到我们刚刚创建的myapp镜像了:
你可以看到你的应用镜像以及ASP.NET镜像都存在于你的主机上。
现在我们开始讲如何将ASP.NET应用程序部署到云端。
第四步:运行容器
运行一个容器非常的简单,通过运行以下命令可以在你的开发机上启动myapp容器:
-t
表示附加一个伪终端(tty)到容器(在以后的ASP.NET 5版本中可能不在需要);-d
表示以后台的方式运行容器,如果不使用此标识的话,ASP.NET运行时后台的输入/输出流信息就会显示在你的终端上;-p 80:5004
告诉Docker将容器的5004号端口映射到宿主机的80号端口上。这样,宿主机80号端口接收的数据包就会被转发到容器的5004号端口上了;最后,
myapp
是镜像的名称,我们可以用这个名称来启动之前Dockerfile构建的镜像。
容器启动之后(译者注:容器和镜像的区别就相当于OO中的对象和实例,对象是编译时的概念,实例是运行时的概念。以这样理解,容器是运行时的镜像。),可以通过以下命令查看容器运行的状态:
好的,容器启动了!但是我们的演示还没结束,我们还要完成Azure VM的终端端口映射(endpoint port mapping for Azure VM)。你必须到Azure云的管理页面将Linux虚拟机(容器的宿主机)的80号端口映射到公网的TCP 80号端口上(具体可以参考这个教程)。
好了,现在我们在浏览器中打开http://your-cloud-service-name.cloudapp.net:80/
看!我们已经在Linux中使用Docker容器运行ASP.NET 5的应用程序了!(译注:屌炸了!)
当然,如果你要构建一个比我们演示程序更复杂的业务系统,你需要学会编写Dockerfile来构建更加复杂的镜像,你可以参考这里。
结论
我们会持续为ASP.NET 5能更好的运行在Linux的Docker容器中而不断的努力、投入;同时,我们很高兴为你带来微软在Docker Hub上的首个官方镜像:ASP.NET 5 Preview Image.
当然,本教程依赖预览版的ASP.NET 5与预览版的Docker镜像,所以随着时间与开发进度的推进,本文的指令可能会过时。所以读者可以通过登录Docker Hub或者GitHub仓库来获取最新的镜像与程序版本。
你也可以在GitHub上给我们反馈,以帮助我们改善Docker镜像与ASP.NET 5。
原文链接:Running ASP.NET 5 applications in Linux Containers with Docker(翻译:肖劲 审校:李颖杰)