Azure App Service 多容器部署实例

概要

1. 项目结构
2. 构建以及部署
3. 相关链接

项目结构

一个简单的Web应用 – Switches

应用实现了一个可变长度的布尔数组修改存储,并在前端以switch的形式展示。点击switch时发送请求修改数组中某元素值,修改成功后重新获取数组值。
项目使用Angular, .Net Core, Redis, 前后端分离结构。后端连接redis以实现简单存储的功能。

在一个App Service中实现

App Service实例中只需要运行两个容器即.Net Core App以及Redis, 前端打包后的js以静态文件的形式host在Net Core的默认目录下。
核心是Docker Compose的使用,并为.Net Core App,redis两者之间建立连接。

为什么要需要Scaling

AutoScale在应用负载时让适当数量的资源运行。 当负载增加时,添加资源来处理增加的负载;当资源空闲时,删除资源以节省资金。
App Service中存在两种Scaling即Scale Up以及Scale Out。

Scale Up即对整个实例进行扩大,得到更强计算能力的同时也意味着需要付出更多的成本。
Scale Out即对实例的数量进行调整,即时每个实例的大小相同,但处理工作的能力自然随着数量增加而提高

AutoScale只支持Scale out,并能制定复杂的规则自动化调整,对于用户数量不多但并发较高的应用更加友好。

为什么要需要多容器运行

发挥多实例即Scale Out的优势。Scale Out后拥有多个后端实例,多个redis实例。为高并发提供保障。

App Service的Scaling功能以实例为单位,故多容器运行的实例在Scaling时容器运行数量会成倍增长。而且由于自动创建销毁的特性,App Service不适用于存储功能的应用,但我们可以在实例中使用缓存服务来提高应用的响应速度。
例如WordPress的Redis应用。每个实例第一次访问数据库后将数据存储在Redis,下一次获取数据时先检索redis获取,由此减少对数据库的访问。

当然也可以对Redis做持久化的存储,在容器重启时不丢失数据。

构建以及部署

构建.Net Core App

工程简单分为API以及Data两个工程,Data中的RedisService类包含连接Redis,操作Redis的方法。
在StartUp时注册为一个singleton service,注入至Controller实现调用。
API中存在两个接口,获取当前布尔数组值,修改当前数组值。

[HttpGet]
public async Task<string> Get()
{
    return await _redisService.Get(_switchKey);
}

异步调用RedisService中方法并返回结果。

构建Angular App

工程简单分为Service,Components两个部分,Service中使用Anglar HttpClient发送请求,Component中存在一个组件使用多个Switch的状态展示当前数组值。OnChange时获取所有Switch状态作为参数通过注入的Service发起修改请求。
这里修改了build prod时的输出目录为.Net Core App开启静态文件支持后默认的wwwroot目录,即以静态文件的形式serve。

  "scripts": {
    "build:prod": "ng build --prod --output-path=../Switches/wwwroot/",
  }
构建Dock Compose

App service中多容器运行的核心即Dock Compose,
这里首先声明所有需要的容器即.Net Core App以及Redis。
由于.Net Core App在启动时首先尝试连接Redis,但若此时Redis仍未启动,将导致无法连接从而无法正完成startUp。如何解决?使用depends_on字段,使得Redis容器能够先于.Net Core App启动。

version: "3"

services:
  switches:
    container_name: APIServer
    image: "ymhvic/switches"
    depends_on:
      - redis
    restart: always
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
      - "443:443"

  redis:
    container_name: redis
    image: "redis:latest"
    restart: always
    ports:
      - "6379:6379"

以此模板启动,宿主机的80以及443端口将映射到.Net Core App容器对应端口,6379映射至Redis。

由于App Service不支持networks字段,这里无法使用内网ip连接
.Net Core App的redis连接字符串如下:

{
    "RedisConnectionString": "redis:6379"
}

可以在下文的git仓库中找到使用networks的Docker compose。
这里附上App Service不支持的Docker compose字段。https://docs.microsoft.com/en-us/azure/app-service/containers/configure-custom-container#configure-multi-container-apps

迭代更新流程

前端修改后build prod输出至wwwroot,后端修改后重新生成镜像push至仓库。
重启app service下载最新镜像即完成新版本的更新。

相关链接

App Service实例
https://switches.azurewebsites.net

ymhvic/Switches镜像仓库
https://hub.docker.com/repository/docker/ymhvic/switches

.Net Core App代码仓库
https://github.com/VictorYMH/Switches

Azure App Service 多容器运行以及代码直接部署

概要

1. 多容器以及代码直接部署
2. 部署过程

多容器以及代码直接部署

Azure App Service中同时运行多个容器

在之前的博客中我们提到过,App Service本质上以容器的方式运行在一个Azure VM中,只是根据选择的Service Plan不同在网络环境以及硬件上有所区别。由此,一个App Service理所当然可以同时运行多个容器。主要的实现方式为使用Docker Compose构建规划多容器的运行。

什么是Docker Compose

Docker Compose是一个用于定义和运行多容器 Docker 的应用程序工具,在目录中添加yaml文件,列出所有需要运行的容器及其相关信息如版本,运行命令等。最后使用docker-compose up即可开始运行多个容器。

Azure App Service中Code直接部署

Code直接部署即直接由本地开环境的代码一步直接部署至Azure。相较于其他部署方式,Code直接部署更快更方便。真正实现了无需任何前置操作的“一键部署”。

部署过程

Code直接部署

Code直接部署这里以C#为例,本文使用了一个.Net Core 3.1的WebAPI工程,Visual Studio中简单构建代码后,直接打开需要发布工程的Publish发布标签,选择App Service为目标。

在VS中登陆需要发布到目标的Azure账号,在创建发布模板时即可通过选择账号下的Subscription订阅、Resource Group资源组,找到对应的App Service(笔者已经先行在Azure中创建了一个App Service实例)。

点击发布,即可以看到Output中的开始输出的发布过程,首先在本地生成DLL等文件,在App Service中创建目录,传输至对应的目录。

笔者由于需要在K8s中测试负载均衡的原因,在WebAPI中添加了一个接口/api/ServerInfo, 线程挂起5s后返回当前主机IP。
使用POSTMAN 请求接口 https://vicdemocode.azurewebsites.net/api/serverinfo

这里返回的是App Service实例在资源组中的内网地址。

到此,就实现了一个WebAPI至App Service的Code方式部署。

单实例运行多容器

与单容器部署类似,多容器的部署只是选择了以Docker Compose的方式完成对实例的设置。在Container Setting中选择Docker Compose,选择上传yaml文件或直接键入文件内容,运行后即可在下方日志看到实例的运行情况。

Azure App Service 解读与部署

概要

1. 什么是Azure App Service?
2. 创建Azure App Service以及维护?
3. 一些思考

什么是Azure App Service?

Azure App Service概念

App Service是Azure云的一种资源类型,通过创建App Service类型的资源,我们可以快速实现Web应用的部署运行。
为后续包括绑定域名,版本管理等工作节省更多时间,实现更多自动化的操作。

Azure App Service支持

作为一个Azure希望用来掌管所有Web应用的资源类型,App Service除了支持主流的语言,也可以运行一个Docker容器。所以几乎所有的应用,都可以以App Service类型的资源运行在Azure上。
App Service支持多种主流语言,甚至可以用来运行一些脚本语言编写的后台服务。
App Service为DevOps,Github等代码管理库高度优化,可以实现全自动的continuous integration and deployment

App Service Scaling

类似于一个迷你的K8s,App Service也可以进行实时不间断的增加运行实例或减少。对应不同的流量选择不同的App Service Plan以实现更优的资源分配。

更多信息参考Azure App Service Documentation

2. 创建Azure App Service以及维护?

笔者以上一篇博客中提到的Net Core 3 WebAPI实例工程为例,将其以Docker容器的方式部署在App Service中。具体过程可以参考上篇博客 Docker + Kubernetes 部署.Net Core3 WebAPI
要运行一个容器,首先当然需要搭建一个镜像。
这里笔者在本地搭建生成一个Docker Image并上传至DockHub,来使Azure可以通过DockerHub获取到此Image。
当然可以使用保存在Azure容器库或是其他私有库中的镜像。

进入Azure选择App Service, 选择运行类型为Docker Container。
可以在下方选择不同的App Service Plan,由此决定容器的运行方式,即
1. 与其他容器在同个Azure VM中共享同个CPU运行
2. 在某一专用Azure VM中运行
3. 在某个此应用专用的Azure VPN中运行

填入获取Docker Image的必要信息,稍加配置即完成了一个以Docker容器运行的App Service。
这里可以获取的笔者使用的镜像ymhvic/para

可以看到在Azure部署完成后我们得到了一个地址指向我们刚才创建的实例。

从左侧的Container Setting中可以重新配置以及查看日志。日志中可以看到所有的layer已经下载完成,镜像build成功准备接受请求。
Linux上运行的App service只支持暴露一个端口,且无需实现https(平台会将所有的https请求在公用的前端处理,即http与https都可以访问到)。

这里笔者将此WebAPI工程的随机生成的默认端口55170(http)映射至容器暴露的80端口。需要在startup file中填入命令 -p 55170:80 -p 55170:443,重写默认运行的Docker run命令的端口参数。使得发送至App Service的可以通过80以及443端口发送至容器的55170端口。

笔者由于需要在K8s中测试负载均衡的原因,在WebAPI中添加了一个接口/api/ServerInfo, 线程挂起5s后返回当前主机IP。
使用POSTMAN 请求接口 https://vicdemo.azurewebsites.net/api/ServerInfo
由于WebAPI以容器的方式运行,故这里会得到一个对应此容器实例的局域网ip。

到此,就完成了一个简单的Docker Image快速部署。

3. 一些思考

为什么Azure要推出App Service?

随着Web应用开发语言,运行环境种类越来越繁多,部署维护的工作成本相应地上升甚至在软件迭代中占很大比重。
如同Docker等虚拟化技术的崛起,App Service是Azure开放给用户自定义的虚拟化资源,通过Docker进行quick deploy, scale up and down都大大提高了软件运行的效率。
笔者个人认为由于运行环境,部署等出错的问题,也就是由于这类可以通过自动化工具解决的问题而付出的时间成本,是在整个软件迭代中最令人惋惜的,最值得优化的。我们大可以把时间花在优化业务逻辑,优化项目结构的工作上。

关于Azure的管理理念

所有Azure提供的服务都可以称为一个资源类型,由此,用户可以对所有创建的实例进行独立的操作。
例如,一个外网的公共IP就是一种资源类型,可以将它与某个VM关联,也可以与某个App Service关联,关联后,就可以通过此IP访问到VM对应端口的内容,或是此App Service中运行的Web应用。
类似于软件开发中的不断抽象,Azure高度分离各种类型的资源,使得用户能以更小的成本完成对应用的修改,迭代等工作。

笔者认为App Service是Azure在Web应用+虚拟化技术方向上探索非常成功的案例。结合Azure的高抽象化,App Service可以在整个软件迭代过程有效的提高效率,并为部署维护节省成本。