在之前一篇的博客中,介绍了如何通过Virtual Studio 2015的Docker扩展工具直接发布ASP.NET应用程序到Azure公有云中的Windows Server 2016 TP3的Windows容器中,这个并不难理解,毕竟Windows 服务器内核就是Windows运行.NET应用程序是必须的;不过这里的伏笔是ASP.NET 5(vNEXT)的开源项目中具备通过DNX(.NET Execution Environment运行环境)将Bootstrap .NET应用程序的编译系统,SDK工具以及CLR跨平台的能力,所以我们也可以把ASP.NET 5的WEB应用程序或控制台程序发布到Linux或MAC OS的包含DNX环境的主机或Docker容器上;借助了容器技术的帮助,我们的应用程序托管过程就真的不但可以跨平台而且可以跨越云环境了,这个不是想着就开心的事情?呵呵:)目前DockerHub上已经发布了ASP.NET预览版的Docker容器映像。
接下来将分别介绍如何两种方式发布自己的ASP.NET 5预览版应用程序到托管到Azure公有云上运行的Linux虚拟机容器中,使用的客户机就是我的测试机Windows 10客户端环境,第一种方式需要确保在测试机安装以下组件:
Git for windows 或者 GitHub desktop
Azure CLI 或者 Azure Powershell
Docker toolbox 1.8.x
第一种方式我们需要通过以上工具获得我们的测试使用的ASP.NET项目,连接和构建我们发布在Azure端的Docker虚拟机并构建和运行我们的项目容器。
第二种方式请参考我之前的博客在测试机上有安装Virtual Studio 2015开发IDE及Virtual Studio 2015的Docker扩展工具就可以直接在Azure上构建Docker的Linux虚拟机并将项目发布到Azure中了,这种方式就不再需要上述组件就可以独立构建和部署。
请注意:目前Docker的扩展在国内版的Azure还没有支持,因此本文介绍的内容均为国际版Azure中具有的功能,要实现和测试该功能需要国际版Azure云环境的订阅,并且ASP.NET 5 的Docker映像目前也处于预览阶段,即便是我的测试过程中也是遇到并解决了一些问题,因此如果你关注这个技术和项目的话,请持续关注Docker Hub中的变更以及Git 库中项目更新文档说明。
第一步,预先准备Azure上创建Docker的Linux虚拟机
需要打包我们的应用程序到ASPNET映像并运行的容器,我们首先需要在Azure上构建托管的Docker Linux虚拟机环境,因为过程较为简单如果不清楚怎么操作可以参考这篇文档,直接通过Azure门户市场创建。如果你参考过我之前的博客,那么可以也可以通过Virtual Studio Docker 扩展,在创建步骤中选择Linux的环境虚拟机映像即可,见下图:
本文中的测试环境使用的是Ubuntu Server 15.04版本。
接下来不论采用哪种方式部署ASP.NET 5应用,我们都是在Azure上我们已经构建好了Linux Docker虚拟机环境用于我们应用程序的部署。
接下来,我们将分别介绍两种方式:
方式1,创建包含ASP.NET应用程序的映像用于容器创建;Docker的一大魅力在于通过AUFS文件系统扩展了一层轻量级扩展的映像层,通过该层我们可以基于一个原始的映像一层一层的构建我们标准化的应用运行环境封装,我们在这里需要的基础映像是microsoft/aspnet开源项目映像;因此我们只要在之前部署在Azure Docker虚拟机环境中部署该镜像,之后我们添加应用程序打包创建的新的映像就只是基于代码的Checkin而已,不但轻量而且部署过程非常快速。这也是Docker在开源环境中如此受欢迎的原因之一。
部署基础映像并添加我们的代码过程只要通过Docker提供的声明式的Dockerfile进行构建即可,关于Dockerfile的详细使用语法等可以参考Docker官方文档,这里就不赘述了。
本方式测试我们就直接引用aspnet/home中的Web应用程序样例代码,因此我们先把项目克隆到本地Git库,
git clone [email protected]:aspnet/Home.git aspnet-Home
进入项目环境,可以看到项目中的文件如下:
我们打开并编辑目录中的Dockerfile,修改为如下内容:
FROM microsoft/aspnet
COPY project.json /app/
WORKDIR /app
RUN ["dnu", "restore"]
COPY . /app
EXPOSE 5004
ENTRYPOINT ["dnx","kestrel"]
(我测试时使用了酷酷的免费IDE, 可是支持Dockerfile语法智能感知的Virtual Studio Code,感兴趣你也可以尝试一下啊!见下图)
这里把Dockerfile都干了哪些事情构建了添加了测试代码的映像过程大致说明一下,首先FROM帮助我们从DockerHub中找到并下载aspnet:latest最新的基础映像到部署在Azure端的Docker虚拟机环境。
接下来,COPY帮助我们把本地项目定义的Json文件拷贝到 挂接基础映像/app目录中用于dnu部署应用;接下来WORKDIR将当前工作路径设置为 /app,COPY . /app帮助我们把当前克隆的Git样例代码上传到基础映像的 /app目录,最后设置WEB对外服务侦听端口为5004,我们可以通过下图中显示的Project.json中的定义看到kestrel启动的ASPNet服务端口,并且容器启动时的入口是"dnx kestrel"启动kestrel环境并在启动时应用project.json中的定义。
好了,现在我们有了可以构建包含代码的应用基础映像环境了,包括Dockerfile,project.json以及我们的应用程序项目。下面我们开始连接Azure Docker虚拟机并通过TLS加密的Restful WEB访问Docker Deamon获得Dockerfile构建整个Docker映像:
docker --tlsverify -H tcp://{Your Azure Docker VM DNS Name}:2376 build -t myapp .
以下是我测试时设置:
docker --tlsverify -H tcp://vnextserver.westus.cloudapp.azure.com:2376 build -t myapp .
完成之后,可以查看到映像的aspnet:latest基础映像以及扩展了测试应用的myapp映像已经创建完毕。
接下来我们只要通过将此映像创建容器运行进程就可以了,
docker --tlsverify -H tcp:// {Your Azure Docker VM DNS Name}:2376 run -t -d -p 80:5004 myapp
实际测试设置:
docker --tlsverify -H tcp://vnextserver.westus.cloudapp.azure.com:2376 run -t -d -p 80:5004 myapp
关于Docker run使用的参数和方法可以参考官方文档,这里就简要说明一下,-t为容器挂接了一个pseudo-tty, 据称该参数未来ASPNET容器创建将不再需要。
-d代表将在后台启动改容器进程,-p指定了该容器端口对外通过Azure Docker虚拟机暴露出来的端口,这里设置为80的映射,注意这里特别说明一下,容器的网络环境在云中感觉想盗梦空间或者虫洞穿越一样,烧不烧脑可能看我们的状态和智商,开个玩笑,见下图,网络层次映射出来有这样几个层次,上述命令完成了将容器服务端口映射到了虚拟机的外部端口80,但是如果访问的Azure上的外网服务的话还需要将外网端口通过负载均衡或者端点Endpoint映射到虚拟机上,此外还有可能通过Azure NSG控制的网络访问控制策略等,相关知识点可以通过Azure的网络部分介绍,这里就不展开介绍了,以后多做些博客慢慢介绍。
检查一下我们的创建的容器是否已经运行起来了,
docker--tlsverify -H tcp:// {Your Azure Docker VM DNS Name}:2376 ps
实际测试设置:
docker--tlsverify -H tcp://vnextserver.westus.cloudapp.azure.com:2376 ps
访问Azure 虚拟机外网的80端口,现在我们的ASPNET的测试应用程序已经运行在了Azure公有云的Linux虚拟机容器环境了,怎么样,跨越云跨越平台任务完成了 :)
接下来,给大家也介绍一下第二种方法,这种方式就是可以直接通过Virtual Studio发布ASP.NET到Azure的Docker虚拟机中,由于集成了对Docker CLI的支持,如果你不是Docker的深度用户,可以更加关注你的代码本身,让IDE工具帮助你完成发布和部署工作,怎么样?酷吧!
这里只给大家介绍一下发布的方法,其中首先确保我们已经按照预准备阶段的需求准备好了Azure上的Docker虚拟机(当然我们就用我们的IDE创建最好了),然后我们仍然选择我在之前博客中使用的ASP NET WEB项目,我们做一点点修改部署就可以了,我的测试发现当前版本的工具生成的project.json文件有个小Bug,因此我们需要进行简单的修改,这个问题应该在后面发布的Docker Virtual Studio 2015 扩展工具中得到解决。
在Virtual Studio 项目中打开project.json, 修改下图部分:
注意,通过扩展工具发布项目到Azure时,容器端口要和配置端口匹配;
为了确定我们发布的项目有所更新,我们简单的修改一个页面about.cshtml通过Razor扩展html的C#标记代码如下,显示我们的当前应用运行的容器:
然后发布我们的应用,发布后访问Azure Docker虚拟机外网进行验证,打开about页面可以看到当前运行的容器名称:
我们检查一下当前运行的容器,Bingo,就是这个了,我们发布的更新已经生效。
写在最后,这篇博客给大家介绍了通过两种方式在Azure公有云中部署跨平台运行的运行在Linux容器中的ASP .NET 5应用程序,个人感觉通过Virtual Studio 2015的确是个开发+部署的利器,不过如果你是Docker的深度用户,采用第一种方式也无不可。需要注意的是,ASP .NET的基础映像和项目在以及Virtual Studio 2015 Docker扩展工具都在持续更新中,所以你的测试或验证过程可能略有出入,建议你感兴趣的话持续关注这些项目的进展。