ServiceFabric: 在Windows上创建容器应用并部署到ServiceFabric中

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: ServiceFabric: 在Windows上创建容器应用并部署到ServiceFabric中

目的


现在做项目大多采用前后端分离的方式,本文会建立一个web前端(angular 6),一个后端API(传统的.net framework),前端代码会调用后端的API,接着将这两个分别打包成基于windows的docker 镜像,最后将这两个镜像部署到Azure的service fabric中。


前提条件


有微软的Azure的帐号及订阅


了解Docker并已安装在本地,切换为Window Container模式


大致了解Service Fabric,猛戳这里


本机安装了Visual Studio、VSCode、Git、NodeJS、angular-cli.


在Azure上注册一个docker registry


它就是一个镜像仓库,我们不用docker的公共镜像仓库,我们需要创建自己的私有仓库,点击create a resource,搜索container registry,接着点击创建,如下。

640.jpg

创建完成后,进入Access keys中,启用Admin user,这里你就可以使用如下用户名和密码登录此registry中了。

640.jpg


创建一个基于angular的Web前端,打包成镜像,推送到镜像仓库


PS C:\Users\cong.wu\Desktop\SFDemo> ng new FrontendDemo 
PS C:\Users\cong.wu\Desktop\SFDemo\FrontendDemo> cd FrontendDemo
#打开VSCode
PS C:\Users\cong.wu\Desktop\SFDemo\FrontendDemo> code .

创建完成之后,结构如下:


640.jpg

运行如下命令build这个应用

ng build --prod

可以看到有一个dist文件夹,这里就是编译好的静态代码,然后在dist\FrontendDemo文件夹中创建一个Dockerfile


640.jpg


Dockerfile的内容如下,可以看出这是一个基于windows server 2016的aspnet基础镜像, 额!为啥不用nginx,因为报错额,难道nginx没有window 版本的镜像?


FROM microsoft/aspnet:4.7.1-windowsservercore-ltsc2016
ARG source
WORKDIR /inetpub/wwwroot
COPY . .
EXPOSE 80
#docker build -t accenturecode/frontenddemo .


然后运行如下命令,将其打包成镜像、推送到刚创建的私有镜像仓库中:


#打包成accenturecode/frontenddemo镜像
PS C:\...\dist\FrontendDemo> docker build -t accenturecode/frontenddemo .
#登录到镜像仓库
PS C:\...\dist\FrontendDemo> docker login -u accenturecode accenturecode.azurecr.io
Password:
Login Succeeded
#给镜像打标签
PS C:\...\dist\FrontendDemo> docker tag accenturecode/frontenddemo accenturecode.azurecr.io/accenturecode/frontenddemo
#推送到镜像仓库
PS C:\...\dist\FrontendDemo> docker push accenturecode.azurecr.io/accenturecode/frontenddemo


创建一个基于.net framework的后端,打包成镜像,推送到镜像仓库


使用Visual Studio创建一个.net framework webApi,这个应用程序采用http.sys作为web 服务器,所以它必须寄宿在IIS下才能运行,目的是我们希望能把传统的.net应用程序放到service fabric之中,当然你也可以创建.net core,不过那样就可以使用linux docker container了。项目文件结构如下。

640.jpg


在项目上右击发布,生成的代码如下:


640.jpg



创建一个Dockerfile文件,内容如下


FROM microsoft/aspnet:4.7.1-windowsservercore-ltsc2016
WORKDIR /inetpub/wwwroot
COPY . .
#docker build -t accenturecode/backenddemo .
运行如下命令,将其打包成镜像、推送到刚创建的私有镜像仓库中
#打包成accenturecode/backendenddemo镜像
PS C:\...\bin\Release\Publish> docker build -t accenturecode/backenddemo .
#登录到镜像仓库
PS C:\...\bin\Release\Publish> docker login -u accenturecode accenturecode.azurecr.io
Password:
Login Succeeded
#给镜像打标签
PS C:\...\bin\Release\Publish> docker tag accenturecode/backenddemo accenturecode.azurecr.io/accenturecode/backendenddemo
#推送到镜像仓库
PS C:\...\bin\Release\Publish> docker push accenturecode.azurecr.io/accenturecode/backendenddemo
#最后你本地会有如下几个images
PS C:\...\bin\Release\Publish> docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED             SIZE
accenturecode.azurecr.io/accenturecode/backenddemo    latest                             952e1dab2704        3 hours ago         13.7GB
accenturecode/backenddemo                             latest                             952e1dab2704        3 hours ago         13.7GB
accenturecode.azurecr.io/accenturecode/frontenddemo   latest                             6c84ef65f4d6        3 hours ago         13.6GB
accenturecode/frontenddemo                            latest                             6c84ef65f4d6        3 hours ago         13.6GB
microsoft/aspnet                                      4.7.1-windowsservercore-ltsc2016   b4e67c95c3c6        4 weeks ago         13.6GB

查看你的镜像仓库,会看到有两个镜像


640.jpg


创建一个Service Fabric项目


创建此项目的主要目的是将这两个镜像部署到service fabric之中,此项目完全与你具体的应用程序或代码没有啥关系。

使用Visual Studio创建一个新的项目

640.jpg


点击OK

640.jpg

选择Container,并输入service Name, image name, host port, container port, 其中host port代表你虚拟机的端口,container port是容器的端口,到时访问我们的应用程序的网址时,端口是host port的80端口。创建完成之后,你的代码的结构看起来是这样子的。

640.jpg


这里你会发现在两个重要的文件,一个是ApplicationPackageRoot/ApplicationManifest.xml,一个是ApplicationPackageRoot/FrontendContainerServicePkg/ServiceManifest.xml。这里先不解释,我们继续创建一个新的service,左击ApplicationPackageRoot,创建一个新的Service


640.jpg

弹出的窗口中输入像下面这样的内容,注意这里的Host Port是83,也就是说后端的API暴露83端口,供前端调用。


640.jpg


创建完成之后,

ApplicationPackageRoot/BackendContainerServicePkg/ServiceManifest.xml的内容如下。
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="BackendContainerServicePkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="BackendContainerServiceType" UseImplicitHost="true" />
  </ServiceTypes>
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ContainerHost>
        <ImageName>accenturecode.azurecr.io/accenturecode/backenddemo</ImageName>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>
  <ConfigPackage Name="Config" Version="1.0.0" />
  <Resources>
    <Endpoints>
      <Endpoint Name="BackendContainerServiceTypeEndpoint" Port="83" />
    </Endpoints>
  </Resources>
</ServiceManifest>
 ApplicationPackageRoot/ApplicationManifest.xml的关键内容如下。你需要在RepositoryCredentials节点中填入登录到你私有镜像仓库的用户名和密码,并标记PasswordEncrypted为false
<ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="FrontendContainerServicePkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <!-- See https://aka.ms/I7z0p9 for how to encrypt your repository password -->
        <RepositoryCredentials  AccountName="accenturecode" Password="XXXXXX" PasswordEncrypted="false" />
        <PortBinding ContainerPort="80" EndpointRef="FrontendContainerServiceTypeEndpoint" />
      </ContainerHostPolicies>
    </Policies>
  </ServiceManifestImport>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="BackendContainerServicePkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <!-- See https://aka.ms/I7z0p9 for how to encrypt your repository password -->
        <RepositoryCredentials  AccountName="accenturecode" Password="XXXX" PasswordEncrypted="false" />
        <PortBinding ContainerPort="80" EndpointRef="BackendContainerServiceTypeEndpoint" />
      </ContainerHostPolicies>
    </Policies>
  </ServiceManifestImport>

你会发现这个image对应的service,都是StatelessService,即无状态服务。


到目前为此,此项目的配置就结束了。接下将它部署到Azure上的Service Fabric中。


部署到Service Fabric中


右击ServiceFabricDemo, 点击Publish, 点击创建一个新Cluster.


640.jpg


弹出如下窗口,下面有4个tab,特别要注意最后一个tab,这里暴露的端口只有80,83,80对应frontend,83对应backend.

640.jpg


等待几分钟之后,就会在azure上看到cluster已经创建好了。然后你在点击上面的pubish,这样你的两个镜像就部署上去了。直接访问83端口,如下图,因为这是asp.net web api,它和mvc集成了,所以我创建此后端应用程序的时候,它顺便把页面也写了,看下面第二张图,就是调用API的效果,这个链接可以在Azure cluster的界面上找到,端口需要你自己指定。


640.jpg


640.jpg


在Azure上,你的所有资源如下图,servicefabricdemo就是刚创建的cluster,第一行是你的虚拟机的集合。



640.jpg

Cluster的界面如下图这样。


640.jpg


cluster有一个explore界面,如下,你可以进行scale up or down.


640.jpg


更你的应用程序、重新打包镜像、推送到私有镜像仓库、部署到service fabric


更你的应用程序、重新打包镜像、推送到私有镜像仓库、部署到service fabric

写到这里,我们前端还没有具体的代码调用后端,这里我们修改前端代码去调用后端,这里只贴出app.component.ts的改动:


640.jpg


至于后端,在web.config中把如下代码加进去解决跨域的问题


<system.webServer>    
   <httpProtocol>
      <!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
   </httpProtocol>
</system.webServer>

重新将前后端代码打包镜像、推送到私有镜像仓库、部署到service fabric后,最终效果是这样的,其中这里面的值是调后端API获得的,如下图:


640.jpg


源码地址

NaN


总结与讨论

只使用容器部署到service fabric,用起来相对简单,感觉微软把它封装的很好,但也带来了另一个困难,就是让你不太容易理解里面的原理,不像k8s直接深入浅出地告诉你原理。做这个Demo时,发现service fabric的文档非常少,主要是从官网上得来的。花了一整天时间做了个demo及写此篇文章,还有如下问题需要进一步探索。


1、使用window镜像打包出来的东东非常大,刚才创建的一个镜像就是13G,  可以使用docker 分层镜像来解决

2、可以考虑使用Azure DevOps来完成CI/CD

3、创建Cluster的时候,只开放了80,83端口,在哪里可以修改?

相关实践学习
通过workbench远程登录ECS,快速搭建Docker环境
本教程指导用户体验通过workbench远程登录ECS,完成搭建Docker环境的快速搭建,并使用Docker部署一个Nginx服务。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
23小时前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略
|
23小时前
|
监控 Kubernetes Docker
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
【5月更文挑战第9天】本文探讨了Docker容器中应用的健康检查与自动恢复,强调其对应用稳定性和系统性能的重要性。健康检查包括进程、端口和应用特定检查,而自动恢复则涉及重启容器和重新部署。Docker原生及第三方工具(如Kubernetes)提供了相关功能。配置检查需考虑检查频率、应用特性和监控告警。案例分析展示了实际操作,未来发展趋势将趋向更智能和高效的检查恢复机制。
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
|
22小时前
|
运维 监控 Kubernetes
构建高效自动化运维体系:基于容器技术的持续集成与持续部署(CI/CD)实践
【5月更文挑战第15天】 随着云计算和微服务架构的普及,传统的IT运维模式面临转型压力。为提高软件交付效率并降低运维成本,本文探讨了利用容器技术实现自动化运维的有效策略。重点分析了在持续集成(CI)和持续部署(CD)流程中,容器如何发挥作用,以及它们如何帮助组织实现敏捷性和弹性。通过具体案例研究,文章展示了容器化技术在自动化测试、部署及扩展中的应用,并讨论了其对系统稳定性和安全性的影响。
|
23小时前
|
运维 监控 安全
构建高效自动化运维系统:基于容器技术的持续集成与持续部署(CI/CD)实践
【5月更文挑战第14天】 随着DevOps文化的深入人心,持续集成与持续部署(CI/CD)已成为现代软件工程不可或缺的组成部分。本文将探讨如何利用容器技术,尤其是Docker和Kubernetes,构建一个高效、可扩展的自动化运维系统。通过深入分析CI/CD流程的关键组件,我们将讨论如何整合这些组件以实现代码从提交到生产环境的快速、无缝过渡。文章还将涉及监控、日志管理以及安全性策略等运维考量,为读者提供一个全面的自动化运维解决方案蓝图。
|
23小时前
|
运维 Kubernetes 持续交付
构建高效自动化运维体系:基于容器技术的持续集成与部署实践
【5月更文挑战第13天】 在现代软件开发周期中,持续集成(CI)和持续部署(CD)已成为提升开发效率、保障产品质量的关键环节。随着云计算和微服务架构的普及,容器技术如Docker和Kubernetes为运维领域带来了革命性的变革。本文旨在探讨如何利用容器技术构建一个高效、可靠的自动化运维体系,实现从代码提交到产品发布的全过程自动化管理。通过深入分析容器化技术的核心原理,结合实际案例,我们将阐述如何优化持续集成流程、确保自动化测试的覆盖率、以及实现无缝的持续部署。
14 2
|
23小时前
|
存储 安全 数据库
【Docker 专栏】Docker 容器内应用的状态持久化
【5月更文挑战第9天】本文探讨了Docker容器中应用状态持久化的重要性,包括数据保护、应用可用性和历史记录保存。主要持久化方法有数据卷、绑定挂载和外部存储服务。数据卷是推荐手段,可通过`docker volume create`命令创建并挂载。绑定挂载需注意权限和路径一致性。利用外部存储如数据库和云服务可应对复杂需求。最佳实践包括规划存储策略、定期备份和测试验证。随着技术发展,未来将有更智能的持久化解决方案。
【Docker 专栏】Docker 容器内应用的状态持久化
|
23小时前
|
存储 文件存储 数据安全/隐私保护
Windows部署开源文件管理器File Browser并实现远程访问本地文件
Windows部署开源文件管理器File Browser并实现远程访问本地文件
34 1
|
23小时前
|
存储 Prometheus 监控
【Docker 专栏】Docker 容器内应用的调试与故障排除
【5月更文挑战第8天】本文探讨了Docker容器内应用的调试与故障排除,强调其重要性。方法包括:通过日志排查、进入容器检查、使用监控工具及检查容器配置。常见问题涉及应用启动失败、性能问题、网络连接和数据存储。案例分析展示了实战场景,注意事项提醒避免不必要的容器修改、备份数据和理解应用架构。掌握这些技能能确保Docker应用的稳定运行和性能优化。
【Docker 专栏】Docker 容器内应用的调试与故障排除
|
23小时前
|
安全 Linux 数据安全/隐私保护
Windows 部署 Elasticsearch + kibana 8.0 指南
Windows 部署 Elasticsearch + kibana 8.0 指南
19 0
|
23小时前
|
前端开发 API 数据库
【Docker专栏】Docker Compose实战:编排多容器应用
【5月更文挑战第7天】Docker Compose是Docker的多容器管理工具,通过YAML文件简化多容器应用部署。它能一键启动、停止服务,保证开发、测试和生产环境的一致性。安装后,创建`docker-compose.yml`文件定义服务,如示例中的web和db服务。使用`docker-compose up -d`启动服务,通过`docker-compose ps`、`stop`、`down`和`logs`命令管理服务。
【Docker专栏】Docker Compose实战:编排多容器应用

热门文章

最新文章