Tag: Amazon EC2 Container Service


基于Amazon EC2 Container Service的持续集成/持续交付解决方案

基本概念

持续集成/持续交付

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)和持续交付(Continuous delivery,简称CD)。

通过CI/CD构建自动化的代码交付管道,可以实现:

(1) 快速交付。通过CI/CD自动化软件发布的过程,可以更快速地发布新的功能,快速迭代反馈并让新功能更快提供给客户。

(2) 提高质量。自动化构建、测试和发布过程致使可以轻松测试每次代码更改并捕捉易于修复的小型漏洞,通过标准化发布过程运行每一项更改,从而保证应用程序或基础设施代码的质量。

(3) 可配置工作流。通过图形用户界面模拟软件发布过程的各个阶段。

容器

本文涉及到的另外一个概念是容器,相信大家都已经不再陌生,并且很多朋友已经在自己的环境中有实际的运行、部署基于容器的应用,这边简单的回顾下容器的几个重要优势:

一是因为容器可以跨平台,从而让程序猿可以享受到研发生产环境一致性的便利,也就是DevOps。在没有容器之前,常常一个应用做好了在笔记本上可以运转起来,在数据中心就运转不起来,因为操作系统版本不同、库版本不对;或者有的时候生产环境里出现了问题,在笔记本的开发环境中复制不出来。有了容器之后,这些问题就大大减少了。

其二,容器在虚拟机里面可以大幅度提升资源利用率。因为一旦把应用容器化,虚拟机资源就可以通过部署多个容器而得到充分利用,而不是每一个应用去申请一个虚拟机,造成资源的浪费。

Amazon ECS/ECR

Amazon EC2 Container Service (ECS)是一个托管的容器集群管理和调度服务, 可使您在 Amazon EC2 实例集群中轻松运行和管理支持 Docker 的应用程序。

使用 Amazon ECS 后,您不再需要安装、操作、扩展您自己的集群管理基础设施,可以根据资源需求和可用性要求在集群中安排支持 Docker 的应用程序。借助 Amazon ECS,您可以从一个容器扩展到覆盖数百个实例的数千个容器,而运行应用程序的方式并不会因此而变得复杂。您可以运行包括应用程序、批量作业和微服务在内的任何东西。Amazon ECS 将基础设施的一切复杂因素全部消除,让您能够集中精力设计、开发、运行容器化应用程序。

Amazon EC2 Container Registry (ECR) 是完全托管的 Docker 镜像仓库,可以让开发人员轻松存储、管理和部署 Docker 容器映像。Amazon ECR 集成在 Amazon EC2 Container Service (ECS) 中,从而简化产品工作流的开发。

本文主要介绍如何在AWS云上,使用Jenkins快速构建针对容器应用的持续集成/持续交付管道。

下图是整个CI/CD的流程图:

  1. 开发者commit/push新版本的软件工程到GitHub仓库
  2. GitHub的webhook触发Jenkins预先定义好的构建Pipeline
  3. Jenkins下载GitHub,并基于下载的DockerFile构建新的docker镜像并上传ECR仓库
  4. Jenkins调用aws cli更新ECS的task definition引用新的docker镜像并更新相关的service
  5. ECS基于新的service配置更新集群中的container

可以看到,整个代码的发布过程,开发人员只需要在本地开发新版本的软件并提交到GitHub,之后的一系列代码构建、部署等过程可以完全实现自动化,无需人为干预,大大提高了软件迭代的速度,为敏捷开发、微服务化提供支持,同时,可以根据需要添加测试步骤、代码审查、人工审批等步骤,构建一条更为强大灵活的代码交付流程。

 

  1. 准备工作启动一台EC2用于安装jenkins,本例使用Amazon Linux AMI,建议分配EIP(52.34.X.X),并且赋予合适role使其能够操作ECR和ECS
  2. 安装java jdk 1.8
  3. 安装并运行docker daemon,

    yum install docker –y

    chkconfig docker on

    service docker start

  4. 安装并运行jenkins

    wget -O /etc/yum.repos.d/jenkins.repo http://jenkins-ci.org/redhat/jenkins.reporpm –import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.keyyum install jenkins

    chkconfig jenkins on

    service jenkins start

  5. 将jenkins用户加入docker用户组,使其拥有docker cli执行权限
    usermod -a -G docker jenkins
  6. 安装git,jq
    yum install git jq –y

第一步 配置GitHub与Jenkins联动

生成GitHub token,用于jenkins访问GitHub

记录下生成的token字符串

为需要做CI/CD的GitHub创建hook,实现代码更新自动通知Jenkins,Payload URL设置Jenkins Server的地址,默认Jenkins监听8080端口

第二步 配置Jenkins的构建步骤

在浏览器中输入jenkins server的地址(52.34.X.X:8080),开始配置jenkins

初始化登入

安装推荐的插件

安装CloudBees Docker Build and Publish plugin,用于构建docker镜像并上传到ECR仓库

配置github插件,使得jenkins能够连接到github

点击Add GitHub Server增加GitHub服务器,并添加Credentials

在Secret中输入之前记录的GitHub Personal Access Token

点击Test connection测试连通性

创建jenkins项目

设置GitHub项目路径

源代码管理选择Git

勾选GitHub hook trigger for GITScm polling,使得github项目的更改自动触发构建行为

添加三个构建步骤

第一个步骤为通过aws cli登入ECR仓库

第二个步骤为通过CloudBees Docker Build and Publish plugin构建docker镜像并上传到ECR中

第三个步骤为通过脚本注册新的ECS task definition并更新service,实现服务部署,详细代码可以从如下链接获取

https://s3.cn-north-1.amazonaws.com.cn/junyublog/buildstep3.sh

第三步 测试

https://github.com/iwasnobody/ecs-cicd-jenkins

本例使用的GitHub工程对外提供一个apache PHP的静态页面

在本地PC上clone下工程兵修改工程下的src/index.php文件

commit并push到GitHub上

Jenkins界面可以看到自动触发了一次新的构建

查看新的镜像已经被上传到ECR

查看jenkins创建了新版本的task definition

查看service已经引用了新版本的task definition

访问应用,确认已经更新到最新版

 

作者介绍

余骏,AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广。在加入AWS之前,他在思科中国担任系统工程师,负责方案咨询和架构设计,在企业私有云和基础网络方面有丰富经验。

 

 

 

如何在Amazon EC2 Container Service上实现服务高可用的自动伸缩

1. 简介

Amazon EC2 Container Service (ECS)是Amazon提供的一项Docker容器管理服务,可以让您轻松构建、运行、管理您的Docker容器服务。ECS Service是ECS的重要组件,它可以在集群中运行指定数量的任务,当某个任务不可用时,它会重新启动新的任务,维持住任务的指定数量。这个特性从一定程度上保证了服务的可用性,但当面对突发流量,ECS本身并不能动态地进行任务数量的扩展,当流量较少时,ECS也无法动态地进行任务数量的缩减。为解决此问题,可以使用Auto Scaling和Amazon CloudWatch等实现服务的自动伸缩,保证服务高可用。本文将介绍一个运用Auto Scaling在ECS中实现服务高可用的方案,并通过对方案构建过程的剖析,让您对高可用、自动伸缩的服务架构有更进一步的了解。

2. 方案构建

2.1 整体结构图

本方案使用AWS CloudFormation模板声明整个资源堆栈所需资源和相关配置,并实现自动化构建。关于AWS CloudFormation相关知识,请通过以下链接了解:CloudFormation入门

从上面这个结构图可以看出以下主要组成部分:

  1. 初始由两个跨AZ的Container Instance组成的ESC Cluster。
  2. 初始ESC Service中有两个task。
  3. Service Auto Scaling与CloudWatch结合,当Service维度的 CPUUtilization与Threshold满足设定的触发条件时,触发CloudWatch Alarm,CloudWatch Alarm根据设定的Scaling Policy进行Task数量伸缩。
  4. Auto Scaling Group与CloudWatch结合,当Cluster维度的CPUReservation与Threshold满足设定的触发条件时,触发CloudWatch Alarm,CloudWatch Alarm根据设定的Scaling Policy进行实例数量的伸缩。

2.2 准备工作

(1)准备好CloudFormation模板脚本

请从这里(点我)下载用于构建整个资源堆栈的模板脚本文件。

或者通过点击下面按钮来运行堆栈:

(2)准备好Lambda Function

本方案在Auto Scaling Group中的实例关闭时,会调用一个实现自动切换Draining状态的Lambda Function。那么在构建整个堆栈之前,需要先准备好这个Lambda Function。这里我们使用Python编写了这个脚本auto_drain.py来实现此功能。您可以了载包含了这个脚本的压缩包(点我)

下载完成后,请将它上传到您账户上同个Region的S3 Bucket中。记住这个S3 Bucket Name,在构建堆栈时,将它传给Lambda Function S3 Bucket 这个参数。

2.3 构建过程

(1)构建堆栈

打开您的CloudFormation控制面板,使用模板脚本创建堆栈,创建成功后,打开堆栈“输出”栏,可以看到ALBDNS输出值如下所示:

将这个URL复制到浏览器访问,看到It Works字样,表示堆栈构建成功。

(2)测试service auto scaling

我们在模板中定义了基于ECS Service维度的CPU使用率(CPU Utilization)指标进行自动伸缩service的task个数。初始状态下,我们设置Service的Desired Count(参见模板中的ServiceDesiredCount参数)为2,查看ECS Service Management Console,选中左边栏“集群”,再选中as-demo-cluster,点击“ECS Service实例”。可以看到现在有两个容器实例,每个容器实例运行一个任务,总共有两个任务。

接下来我们利用Apache ab压测工具进行测试,向我们的ALB发送30000条请求,并发为每秒1000。相应的ab命令如下:

$ ab -n 300000 -c 1000 http://as-in-publi-xxxxxxxxxxxxxx/

等待ab请求运行完成后,查看此时ECS Service中实例的状态,如下图所示,可以发现在某台实例上新增加了一个task,总的task数量变成了3个,也就是成功触发了Service Scale out。

等待几分钟,再次查看ECS Service中实例的状态,可以看到task总数量又变成了2个,即当Service CPUUtilization小于我们设的的Threshold一定时间(默认设置的是5分钟)后,自动触发了Service Scale in。

(3)测试cluster auto scaling

同样使用Apache ab进行压测,不过为了达到效果,需要加大请求数量和并发数量。

使用以下ab命令(当然您可以根据自己实际情况进行调整)

$ ab -n 1000000 -c 2000 http://as-in-publi-xxxxxxxxxxxxxx/

如果遇到 socket:Too many open files异常。可以使用以下命令修改linux系统最大打开文件数

$ ulimit -n 2048

等待压测结束后,查看ECS中实例的状态(因为实例的启动与容器的启动不同,耗费时间比较长,可能需要等待几分钟才能看到效果),如下图所示,Cluster自动增加了一台实例。

等待一段时间后,再次查看ECS Service中实例的状态,如下图所示,Cluster自动减少了一台实例。

(4)测试自动切换实例Draining状态

我们使用Lambda Function实现在Scale in时自动切换实例到Draining状态(具体讲解见后面章节)。

当前集群中总的实例数量为2,我们通过修改Auto Scaling Group的desired count(在EC2管理窗中界面选中我们模板创建的Auto Scaling Group,修改desired count),将它设为1,这样Auto Scaling会自动关闭一台实例,看看运行的任务数量有什么变化。

可以看到被停掉的实例状态自动切换成了DRAINING,任务也被移到了另一台实例上。

3. 基于两个维度的自动伸缩

CloudWatch监听ECS中的四个指标,分别是CPUUtilization、MemoryUtilization、CPUReservation和MemoryReservation。这四个指标可以分为两大类,前两者是指资源使用率,后两者是指资源占有率。本方案通过集群和服务这两个维度,分别对占用率和使用率进行监控,定制不同的伸缩策略,从而实现自动伸缩。

3.1 什么是资源使用率和资源占有率

资源使用率(CPUUtilization和MemoryUtilization)是指ECS集群(或服务)中所有运行着的任务实际使用资源的总和除以EC2 Container Service集群(或服务)总的资源得到的数值,表现的是集群或服务中资源的使用情况

资源占有率(CPUReservation和MemoryReservation)是指ECS集群(或服务)中所有运行着的任务申请占有的资源的总和除以EC2 Container Service 集群(或服务)总的资源得到的数值,表现的是集群或服务中资源的剩余情况

3.2 基于服务中CPU使用率实现服务自动伸缩

为了简单起见,本方案只监控CPU的使用率和占有率。

当服务面对越来越大的流量时,服务中CPU使用率快速上升,这时可以根据这个CPU使用率来动态地增加任务数量,以达到分担负载的作用。而不是根据CPU占有率来进行扩展,因为无论流量如何变大,CPU占用率是与服务中任务数量相关的,任务数量不同,CPU占用率也不会改变。

在本方案中,具体的构建过如下:

(1)首先,我们声明了对服务中task desired count作为Auto Scaling调整的对象ScalableTarget,ResourceId指向我们创建的ECS Service代码如下:

ServiceScalingTarget:

    Type: AWS::ApplicationAutoScaling::ScalableTarget

    DependsOn: DemoService

    Properties:

      MaxCapacity: !Ref ServiceMaxSize

      MinCapacity: !Ref ServiceMinSize

      ResourceId: !Join [”, [service/, !Ref ‘ECSCluster’, /, !GetAtt [DemoService, Name]]]

      RoleARN: !GetAtt [ServiceAutoscalingRole, Arn]

      ScalableDimension: ecs:service:DesiredCount

      ServiceNamespace: ecs

(2)我们声明了两个Scaling Policy,分别针对Scale Out和Scale In两种情况,当Scale Out时修改ServiceScalingTarget中的Service Desired Count,增加1个task;当Scale In时修改ServiceScalingTarget中的Service Desired Count,减少1个task。主要代码如下:

ServiceScaleOutPolicy:

    Type: AWS::ApplicationAutoScaling::ScalingPolicy

    Properties:

      PolicyType: StepScaling

      PolicyName: StepOutPolicy

      ScalingTargetId: !Ref ‘ServiceScalingTarget’

      StepScalingPolicyConfiguration:

        AdjustmentType: ChangeInCapacity

        MetricAggregationType: Average

        StepAdjustments:

        – MetricIntervalLowerBound: “0”

          ScalingAdjustment: “1”

 

  ServiceScaleInPolicy:

    Type: AWS::ApplicationAutoScaling::ScalingPolicy

    Properties:

      PolicyType: StepScaling

      PolicyName: StepInPolicy

      ScalingTargetId: !Ref ‘ServiceScalingTarget’

      StepScalingPolicyConfiguration:

        AdjustmentType: ChangeInCapacity

        MetricAggregationType: Average

(3)最后,我们声明两个CloudWatch Alarm,分别在Service的CPUUtilization满足Threshold关系时,触发Scale Out和Scale In的Alarm。

ServiceCPUUtilizationScaleOutAlarm:

    Type: AWS::CloudWatch::Alarm

    Properties:

      EvaluationPeriods: !Ref ServiceCPUUtilizationScaleOutMinutes

      Statistic: Average

      Threshold: !Ref ServiceCPUUtilizationScaleOutThreshold

      AlarmDescription: Alarm if Service CPUUtilization greater then threshold.

      Period: ’60’

      AlarmActions: [!Ref ‘ServiceScaleOutPolicy’]

      Namespace: AWS/ECS

      Dimensions:

      – Name: ClusterName

        Value: !Ref ECSCluster

      – Name: ServiceName

        Value: !GetAtt [DemoService, Name]

      ComparisonOperator: GreaterThanThreshold

      MetricName: CPUUtilization

 

  ServiceCPUUtilizationScaleInAlarm:

    Type: AWS::CloudWatch::Alarm

    Properties:

      EvaluationPeriods: !Ref ServiceCPUUtilizationScaleInMinutes

      Statistic: Average

      Threshold: !Ref ServiceCPUUtilizationScaleInThreshold

      AlarmDescription: Alarm if Service CPUUtilization less then threshold.

      Period: ’60’

      AlarmActions: [!Ref ‘ServiceScaleInPolicy’]

      Namespace: AWS/ECS

      Dimensions:

      – Name: ClusterName

        Value: !Ref ECSCluster

      – Name: ServiceName

        Value: !GetAtt [DemoService, Name]

      ComparisonOperator: LessThanThreshold

      MetricName: CPUUtilization

3.3 基于集群中CPU占有率实现集群自动伸缩

当服务中任务的数量随着流量增大也不断增加时,集群中CPU的占有率也会上升,当CPU占有率不断上升,表示可用的资源已不多了,此时需要扩展新的实例,增加整个集群总的资源。

在本方案中,具体的构建过如下:

(1)首先声明两个Scaling Policy,当集群Scale Out时修改集群中的实例数量,增加1个实例;当Scale In时修改集群中的实例数量,减少1个task。主要代码如下:

ClusterScaleOutPolicy:

    Type: “AWS::AutoScaling::ScalingPolicy”

    Properties:

      AdjustmentType: “ChangeInCapacity”

      AutoScalingGroupName:

        Ref: “ECSAutoScalingGroup”

      PolicyType: “StepScaling”

      MetricAggregationType: “Average”

      StepAdjustments:

        –

          MetricIntervalLowerBound: “0”

          ScalingAdjustment: “1”

 

  ClusterScaleInPolicy:

    Type: “AWS::AutoScaling::ScalingPolicy”

    Properties:

      AdjustmentType: “ChangeInCapacity”

      AutoScalingGroupName:

        Ref: “ECSAutoScalingGroup”

      PolicyType: “StepScaling”

      MetricAggregationType: “Average”

      StepAdjustments:

        –

          MetricIntervalUpperBound: “0”

          ScalingAdjustment: “-1”

(2)我们声明两个CloudWatch Alarm,分别监听的指标是集群的CPUReservation,当CPUReservation满足Threshold设定的关系时,触发Scale Out和Scale In的Alarm。主要代码如下:

ClusterCPUReservationScaleOutAlarm:

    Type: AWS::CloudWatch::Alarm

    Properties:

      EvaluationPeriods: !Ref ClusterCPUReservationScaleOutMinutes

      Statistic: Average

      Threshold: !Ref ClusterCPUReservationScaleOutThreshold

      AlarmDescription: Alarm if Service CPUUtilization greater then threshold.

      Period: ’60’

      AlarmActions: [!Ref ‘ClusterScaleOutPolicy’]

      Namespace: AWS/ECS

      Dimensions:

      – Name: ClusterName

        Value: !Ref ECSCluster

      ComparisonOperator: GreaterThanThreshold

      MetricName: CPUReservation

 

  ClusterCPUReservationScaleInAlarm:

    Type: AWS::CloudWatch::Alarm

    Properties:

      EvaluationPeriods: !Ref ClusterCPUReservationScaleInMinutes

      Statistic: Average

      Threshold: !Ref ClusterCPUReservationScaleInThreshold

      AlarmDescription: Alarm if Service CPUUtilization less then threshold.

      Period: ’60’

      AlarmActions: [!Ref ‘ClusterScaleInPolicy’]

      Namespace: AWS/ECS

      Dimensions:

      – Name: ClusterName

        Value: !Ref ECSCluster

      ComparisonOperator: LessThanThreshold

      MetricName: CPUReservation

4. Cluster scale in时切换实例到Draining保证服务容量

我们的ECS集群并不是一创建好就一成不变的,特别是当集群空闲的时候,触发了EC2的Auto Scaling Group的缩减实例之后. 有些时候我们需要关闭其中某个实例,无论是由于系统升级、安装软件、还是为了节省运行成本。那么在关闭实例时,实例上正在运行的task怎么办呢?把它们全杀掉?那可不行,那样就等于减小了整个ECS服务的容量和负载能力,对性能有很大影响。另外就是当直接关闭EC2机器的时候杀死其中的task, 可能造成运行在上面的task处理的请求异常终止,而影响到我们所提供服务的SLA, 这种情况下,将实例切换到Draining状态就是一种解决方案。

当您要关闭集群中某个实例时,运行在这个实例上的task会被停止,然后ECS会在集群中另一个(或多个)实例上运行这些被停掉的task,从而保证整个ECS Service 的task数量保持不变,保证了整个服务容量和负载能力不受影响。同时,当实例被设置成为Draining状态之后,ECS将会自动平滑关闭EC2宿主机中的task资源,利用定义task模版时候所定义的放置规则,将其移动到其他拥有剩余资源的集群中的宿主机上. 关于实例Draining的更多信息,请参见文档.

在本方案中,我们使用AWS SNS 和Lambda实现了实例在集群的Auto Scaling Group Scale in时关联Auto Scaling的LifecycleHook,实现被关闭前调用Lambda Function自动切换Draining状态,将task转移到集群中其它实例上。

我们定义了一个Lambda Function运行Python脚本auto_drain.py,这个脚本主要完成两个工作:

(1)判断传到Lambda Function中的event是否包含autoscaling:EC2_INSTANCE_TERMINATING,是的话就将这个实例状态切换成Draining,这样ECS就会自动停止此实例上所有运行中的task,并在集群中别的实例启动同样数量的task。

切换实例到Draining状态的代码:

containerStatus = containerInstances[‘status’]

            if containerStatus == ‘DRAINING’:

                tmpMsgAppend = {“containerInstanceId”: containerInstanceId}

            else:

                # Make ECS API call to set the container status to DRAINING

                ecsResponse = ecsClient.update_container_instances_state(cluster=clusterName,

containerInstances=[containerInstanceId],status=’DRAINING’)

(2)判断实例上还有没有task正在运行中。如果仍然有运行中的task,则过发送一条SNS通知重新触如这个Lambda Function。如果实例上所有task都已经被停止,则解开LifecyleHook,使这个实例被停掉。

根据task运行情况做不同处理的代码:

# If tasks are still running…

            if tasksRunning == 1:

                response = snsClient.list_subscriptions()

                for key in response[‘Subscriptions’]:

                    if TopicArn == key[‘TopicArn’] and key[‘Protocol’] == ‘lambda’:

                        snsClient.publish(

                            TopicArn= key[‘TopicArn’],

                            Message=json.dumps(message),

                            Subject=’Publishing SNS message to invoke lambda again..’

                        )

            # If tasks are NOT running…

            elif tasksRunning == 0:

                completeHook = 1

                try:

                    response = asgClient.complete_lifecycle_action(

                        LifecycleHookName=lifecycleHookName,

                        AutoScalingGroupName=asgGroupName,

                        LifecycleActionResult=’CONTINUE’,

                        InstanceId=Ec2InstanceId)

                    logger.info(“Response received from complete_lifecycle_action %s”,response)

                    logger.info(“Completedlifecycle hook action”)

                except Exception, e:

整个Python脚本代码,可以解压您在准备工作中下载的auto_drain.zip,查看auto_drain.py脚本文件。

5. 总结

本文主要介绍了如何在ECS 中使用 Auto Scaling、Amazon CloudWatch和其他常用AWS服务实现高可用,可伸缩的服务架构,并结合Lambda Function和AWS SNS 做到当集群中由于Auto Scaling缩减关闭某个实例时,自动切换实例状态到Draining,将task转移到其他实例上,保证服务容量以及回收实例资源时候的task的平滑过渡。通过本套方案,可以让ECS服务在可用性和伸缩性上得到保证,从而为您解决实际业务场景中相类的问题提供一定的帮助和思路。您也可以在本方案基础上,结合实际业务需求,定制自己的Scaling Policy、监控指标和监控维度,实现更符合您需求的解决方案。

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

基于Amazon EC2 Container Service构建安全高可用的Docker私有库

1. 背景

Docker hub作为docker官方镜像仓库,提供了大量Docker镜像的托管服务。但使用它来托管企业私有Docker镜像存在一些问题,比如:

(1)Docker hub托管私有镜像的服务目前只面对收费账户;

(2)使用Docker hub托管私有镜像并不适合一些特殊场景,比如工作环境网络是内网,不允许访问外网,那就更不可能到Docker hub去下载镜像。

在这种情况下,如果能构建一个安全可靠的Docker私有库,将会是一个更好的选择。本文将介绍在Amazon EC2 Container Service基础上结合AWS Elastic LoadBalancer、AWS Autoscaling Group、AWS S3及Docker官方提供的registry镜像构建安全、高可用的Docker私有库的方案,帮助您轻构实现这一需求。

2. 方案详解

我们会使用AWS CloudFormation服务,使用自定义的模板脚本声明所需的资源,实现自动化构建。接下来结合我们的模板脚本对本方案进行详细介绍。

注意:以下内容与代码相关部分只贴出主要代码,部分代码用…表示省略;红字部分请替换成您自己账号相关的信息。

完整模板代码地址:https://s3-us-west-2.amazonaws.com/blog.leonli.org/registry.yml

         或者点击按钮直接在控制台中运行:

2.1 架构图

根据以上架构图,基本数据传输过程为:

(1)Docker客户端向镜像仓库发送的pull/push等命令事实上都是通过docker daemon转换成restful请求的形式再发送给镜像仓库的。在本架构中,我们利用AWS Elastic LoadBalancer(简称ELB)接收客户端发来的请求,作为整个架构的接入层。由于我们要求数据是通过TLS加密传输的,所以我们需要使用AWS IAM中的server certificate(由AWS IAM账户上传的TLS证书)与ELB关联,实现对客户端发来的请求进行加密。

(2)ELB会将请求反向代理给后端分布在不同可用区的两台Container Instance(安装了Docker运行环境的EC2实例),Container Instance中运行了Docker registry服务。当请求到达registry时,我们需要首先使用内置在registry中的用户认证文件(比如本架构中使用apache htpasswd创建的基本用户名密码保护文件),进行用户认证,认证不通过,则驳回请求,认证通过,才可以读写数据。

(3)我们将数据统一存储在一个只供创建者使用的S3 Bucket中。

2.2 基于AWS ECS运行Docker Registry服务

Amazon EC2 Container Service (ECS) 是一项高度可扩展的高性能容器管理服务,它让您能够在托管的 Amazon EC2 实例群集上轻松运行Docker应用程序。 Amazon ECS主要有以下几个组件:ECS Cluster、 Container Instance、Task , ECS Service。这里我们基于ECS运行了Docker registry服务,架构如下:

(1)首先我们在模板中定义了一个ECS Cluster,用来管理相关的Container Instance。ECS提供了ECS-Optimize AMI来创建EC2实例作为Container Instance,ECS-Optimize AMI已经内置Docker运行环境和Container Agent代理,可以为我们节省安装这些环境所需的时间。Container Instance在启动时可以由Container Agent根据配置文件/etc/ecs/ecs.config中的ClusterName属性的值知道需要将实例注册到哪个ECS Cluster上。

因为我们要使用Auto Scaling服务实现对EC2实例的伸缩控制。所以我们使用Auto Scaling的Launch Config组件声明我们的Container Instance。并通过UserData传入Shell脚本,此脚本主要完成以下三件事:

– 调用 echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config ,将Container Instance注册到我们的ECS Cluster中。

– 创建/docker-registry/certs目录和/docker-registry/auth目录,并调用aws s3 copy命令从指定的S3 Bucket中复制TLS证书文件和htpasswd用户认证文件。这些文件将在运行Docker Registry时使用到。

– 调用cfn-signal命令,通知AutoScaling Group资源EC2实例已经启动完毕。

Container Instance相关的主要模板代码如下:

(2)然后我们定义了一个TaskDefinition来声明我们要运行的容器及其相关配置。这里我们运行的是Docker registry镜像的容器,它是官方提供的用于构建镜像仓库服务的镜像文件。

ContainerInstances:

    Type: AWS::AutoScaling::LaunchConfiguration

Properties:

      …

      UserData:

Fn::Base64: !Sub |

          #!/bin/bash -xe

          echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config

  yum install -y aws-cfn-bootstrap

          yum install -y aws-cli

          sudo rm -rf /docker-registry

          sudo mkdir -p /docker-registry/certs

          sudo chmod 777 /docker-registry/certs

          sudo mkdir -p /docker-registry/auth

          sudo chmod 777 /docker-registry/auth

          aws s3 cp s3://${SSLCertificateFileBucket}/${SSLCertificateFileName} /docker-registry/certs/domain.crt

          aws s3 cp s3://${SSLCertificateFileBucket}/${SSLKeyFileName} /docker-registry/certs/domain.key

          aws s3 cp s3://${SSLCertificateFileBucket}/${HtpasswdFileName} /docker-registry/auth/htpasswd

          /opt/aws/bin/cfn-signal -e $? –stack ${AWS::StackId} –resource ECSAutoScalingGroup –region ${AWS::Region}

– 配置环境变量REGISTRY_AUTH、REGISTRY_AUTH_HTPASSWD_REALM、REGISTRY_AUTH_HTPASSWD_PATH指定宿主机目录/auth/htpasswd文件作为Basic Authentication基础用户认证文件,从而实现用户授权认证。

    – 配置环境变量REGISTRY_HTTP_TLS_CERTIFICATE、REGISTRY_HTTP_TLS_KEY指定宿主机目录/certs/中存放的domain.crt作为TLS证书文件,domain.key作为TLS秘钥,从而实现TLS传输加密。

    – 通过配置环境变量REGISTRY_STORAGE指定registry的存储驱动为AWS S3,配置REGISTRY_STORAGE_S3_REGION为存储的S3所在Region,配置REGISTRY_STORAGE_S3_BUCKET为存储的Bucket。从而实现将镜像文件存储到AWS S3指定的Bucket中。

关于构建私有库的更多细节和更多配置可以通过Docker官方文档进行了解:Deploy a registry server

TaskDefinition相关的主要模板代码如下:

RegistryTaskDefinition:

    Type: AWS::ECS::TaskDefinition

Properties:

      NetworkMode: bridge

      ContainerDefinitions:

       – Name: RegistryContainer

          Image: registry:2

          …

PortMappings:

            – ContainerPort: 443

              HostPort: 443

          Environment:

            – Name: REGISTRY_AUTH

              Value: htpasswd

            – Name: REGISTRY_AUTH_HTPASSWD_REALM

              Value: “Registry Realm”

           – Name: REGISTRY_AUTH_HTPASSWD_PATH

             Value: /auth/htpasswd

            – Name: REGISTRY_HTTP_TLS_CERTIFICATE

              Value: /certs/domain.crt

            – Name: REGISTRY_HTTP_TLS_KEY

              Value: /certs/domain.key

            – Name: REGISTRY_HTTP_ADDR

              Value: 0.0.0.0:443

             – Name: REGISTRY_STORAGE

              Value: s3

            – Name: REGISTRY_STORAGE_S3_REGION

              Value: !Ref AWS::Region

            – Name: REGISTRY_STORAGE_S3_BUCKET

              Value: !GetAtt StorageBucket.DomainName

          …

(3)最后我们定义了一个ECS Service,指定TaskDefinition、Cluster和所需运行的任务个数DesiredCount。这样,我们就构建了一个运行着docker registry镜像的ECS服务了。

2.2 如何实现高可用性

(1) 跨可用区部署服务

– 首先,我们在模板中声明了一个VPC和两个私有子网PrivateSubnet1和PrivateSubnet2,这两个子网是分别部署在不同可用区的。

– 其次,我们的ECS服务是通过Elastic Load Balancing(ELB)来平衡多个容器的负载,ELB是高可用且自动伸缩的。我们在模板中定义了一个命名为RegistryELB的ELB组件,指定它是internet-facing模式可供外网访问、并且是跨可用区的。ELB接收外网的请求,并且将请求代理给Container Instance中的容器。

– 最后,我们在模板中声明了一个Auto Scaling Group,指定VPCZoneIdentifier为跨可用区的两个子网PublicSubnet1和PublicSubnet2,由RegistryELB代理请求,从而实现跨可用区部署服务。

(2) 利用Auto Scaling保障可用实例数量

当服务遇到一些突发或者预期的高流量时,或者您的服务出现某些异常时,可以利用Auto Scaling服务保障可用实例数量。比如某台Container Instance宕机了,那么可以利用Auto Scaling自动启动相同配置的另一台Container Instance代理宕机的实例继续提供服务。

大部分情况下,企业Docker私有库承受的流量负载不会太大,所以本方案不介绍Auto Scaling的扩展策略,当然您也可以根据自己的业务需要修改模板代码,实现此功能。本方案使用Auto Scaling主要是为了保障可用实例数量一直维持在DesiredCapacity,这个参数是我们通过模板的参数传入的。

Auto Scaling Group相关的主要模板代码如下:

ECSAutoScalingGroup:

    Type: AWS::AutoScaling::AutoScalingGroup

    Properties:

    …

LaunchConfigurationName: !Ref ‘ContainerInstances’

      MinSize: !Ref MinSize

      MaxSize: !Ref MaxSize

     DesiredCapacity: !Ref DesiredCapacity

    …

(3) 利用s3确保数据完整性

Amazon Simple Storage Service (Amazon S3) 是AWS提供的对象存储服务,它可用于在 Web 上的任何位置存储和检索任意数量的数据,能够提供 99.999999999% 的持久性,使用S3来存储Docker私有库的镜像文件,可以确保数据完整。Docker registry镜像支持使用S3作为存储驱动,只需传入存储所在Bucket和所在Region即可。我们在模板中声明了一个Bucket用来存储镜像数据。并且这个Bucket只能由创建者进行控制。

2.3 如何实现安全性

(1) 利用TLS加密传输

Docker官方建议与私有库通信的所有数据传输皆使用TLS加密,我们通过上传IAM server certificate证书并将其与ELB关联,ELB的Listener使用SSL安全监听443端口,并将请求代理给实例的443端口,实例上也需要安装TLS证书。从而实现全链路的安全传输。

(2)利用apache htpasswd实现基本用户认证

如果我们创建的私有库没有用户认证机制,那么无论是谁只要知道私有库链接,就可以肆无忌惮地访问和操作我们托管在私有库的文件,这显然不是我们想要看到的。所以需要实现用户认证,只有通过认证的用户,才有权进行相关操作。

这里,我们使用apache htpasswd实现基本用户认证。这也是Docker registry镜像默认支持的认证方式。

3. 构建过程

3.1 准备工作

(1) 域名

您必须拥有一个用来指向registry的域名,这样您才可以通过域名访问您的私有库。

(2)TLS证书

yourcertificate.crt intermediate-certificates.pem > yourcertificate.crt

Docker官方建议私有库数据传输基于TLS,这样您还需要为您的域名申请CA认证,得到TLS证书和秘钥文件。有以下两种方式:

向CA供应商购买。

利用Let’s Encrypt生成免费的证书,具体操作参考letsencrypt官网。

另外,如果您的证书供应商还提供给你intermedia证书,那么您需要将它与你的证书进行合并,运行如下命令可以进行合并

aws iam upload-server-certificate —server-certificate-name YourCertName —certificate-body file:///path/to/certificate.pem —certificate-chain file:///path/to/chained.pem —private-key file:///path/to/private_key.pem

(3)上传IAM Server Certificate

{

    “ServerCertificateMetadata”: {

        “Path”: “/”,

        “ServerCertificateName”: “MyRegistryCert”,

        “ServerCertificateId”: “ASCAJHAWE3QRHEHH3L6KM”,

         “Arn”: “arn:aws:iam::xxxxxxxxx:server-certificate/YourCertName”,

“UploadDate”: “2017-07-01T16:16:45.125Z”,

        “Expiration”: “2017-09-26T12:15:00Z”

     }

}

 

openssl x509 -inform DER -in Certificate.der -outform PEM -out Certificate.pem

当Docker客户端向我们的ELB发送请求时,出于安全考虑,需要对传输加密,这时可以利用IAM Server Certificate,将我们的TLS证书、秘钥以及证书链文件上传,IAM会帮我们自动生成一个Server Certificate,再将它与ELB绑定即可。

可以使用AWS CLI按照以下命令上传:

openssl rsa -in PrivateKey.pem -out PrivateKey.pem

上传完成后,您会得到类似以下响应信息,将红字部分ARN记录下来,后面构建时需要它作为参数传入模板中。

注意:

– TLS证书、秘钥及证书链必须都是PEM格式,如果不是,可以使用以下命令进行转换:

– AWS IAM 要求证书秘钥是不加密的,所以当您的秘钥是加密时,需要使用以下命令转换

– 如果您在上传Server Certificate过程中遇到问题,可参考AWS官网指南:

Working with Server Certificate

(4)htpasswd用户认证文件

使用apache htpasswd来做基本认证,首先需要安装httpd,安装完后运行以下命令可以生成一个包含 一条用户名和密码记录的htpasswd文件

htpasswd -c username password > htpasswdfile

后面如果需要加入更多条记录,只需将 -c 参数去除,运行上面相同的命令即可。

(5) 将证书、秘钥和认证文件上传到S3

我们需要将前面几步生成好的TLS证书、秘钥、htpasswd文件上传到S3中,Container Instance启动后会从S3中将这些文件拷贝下来,通过映射到容器中供registry容器使用。

创建一个S3 Bucket, 将这几个相关文件上传。

3.2 自动化构建

接下来,我们在AWS Management Console中使用CloudFormation指定我们的模板文件创建一个Stack。如何使用CloudFormation创建Stack,请参考AWS CloudFormation用户指南:CloudFormation入门

Stack构建成功后,在输出栏会有输出值 RegistryELBDns,它是我们创建的ELB的DNS域名。我们需要将我们之前TLS证书签发的域名DNS解析(CName解析)转发到这个ELB的DNS域名。这样就可以使用我们自己的域名访问我们的私有库了。

3.3 开始使用

构建完Docker私有库后,现在可以开始使用了。

首先,在Docker客户端,我们可以从Docker Hub上拉取一个ubuntu镜像。

docker pull ubuntu:16.04

然后tag这个镜像到我们自己的域名下

docker tag ubuntu:16.04 myregistrydomain.com/my-ubuntu

登录我们的私有库

docker login myregistrydomain.com

输入用户名,密码后,调用push命令将镜像上传

docker push myregistrydomain.com/my-ubuntu

上传完后,可以调用pull命令拉取镜像

docker pull myregistrydomain.com/my-ubuntu

4. 总结

本文介绍了如何利用AWS ECS及其他AWS服务构建一个高可用、安全可靠的docker私有库,通过本方案的详细介绍和构建实践,相信您对于docker registry以及AWS Elastic LoadBalancer、AWS Autoscaling Group、AWS S3及AWS CloudFormation有了更进一步的认识。接下来,您可以利用AWS ECS容器管理服务及Docker容器技术,更加轻松地构建和管理您的应用程序,发挥更大的效益。

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

白皮书:Amazon EC2 Container Service(ECS)上的微服务架构(下篇)

ECS上构建微服务架构

在构建微服务架构时面临的一个主要问题就是,如果减轻运行、维护、扩展和管理微服务架构所需大规模分布式集群资源的工作量和复杂性。目前主流的解决此问题的方案之一就是通过容器化部署和运行服务,降低运维和部署的复杂性。Amazon EC2 Container Service(ECS)是AWS提供的一个容器管理服务,能够应对和解决微服务架构的部署和运维中面临的种种挑战。

本章节首先介绍Amazon ECS及其架构和工作原理,然后介绍利用Amazon ECS及其他相关AWS服务分层构建的一个高可用、高可扩展性、容错的微服务,并讨论该方案中涉及的分布式系统监控、服务发现、异步通信等问题。

Amazon ECS 简介

什么是Amazon ECS

Amazon ECS是一个高度可扩展伸缩、高性能容器管理服务,支持Docker容器[vi]并能够让你轻构地在EC2实例构建的集群中运行应用程序。

Amazon ECS能够让你轻松地进行安装、操作和扩展你的集群资源。使用简单的API调用,你就可以启动和停止基于Docker的应用程序、查询你的集群状态、还可以使用其他熟悉的服务,诸如安全组、ELB、EBS卷和AWS IAM角色。

Amazon ECS的特点
  • 与Docker完美兼容:支持 Docker 并使您能够在 Amazon EC2 实例的集群间运行和管理 Docker 容器。Amazon ECS 所管理的集群中的每个 EC2 实例都运行有 Docker 守护程序,所以无论您将何应用程序打包为本地容器,它都将部署和运行在 Amazon ECS 上,无需进行任何配置更改。
  • 内置集群托管:管理自己的容器管理基础设施通常涉及安装、操作、扩展自己的集群管理软件、配置管理系统和监控解决方案。这些系统的可用性和可扩展性架构和管理很难。Amazon ECS 消除了容器管理工作的复杂性。使用 Amazon ECS,您只需要启动容器实例集群并指定想要运行的任务即可,所有集群管理工作将由 Amazon ECS 完成。
  • 编程控制:Amazon ECS 为您提供一组简单的 API,方便您集成和扩展服务。使用 API,您可以创建和删除集群、注册和取消注册任务、启动和终止 Docker 容器,并能提供集群及其实例的状态相关详细信息。您还可以使用 AWS CloudFormation[vii] 预置 Amazon ECS 集群、注册任务定义和安排容器。
  • 任务调度:Amazon ECS  包含许多任务调度程序和内置的Placement Engine,可以根据您的资源需求(例如 CPU 或 RAM)和可用性要求在集群中放置容器。通过使用可用的任务调度程序,您可以安排长期运行的应用程序和服务以及批量作业。Amazon ECS API 还能提供完整的集群状态信息,允许您编写自己的任务调度程序或集成现有的第三方调度程序(例如 Marathon)。Amazon ECS 是共享状态的乐观并发系统,可以将集群的完整状态呈现给所有的计划程序。通过使用 Amazon ECS API 或 Blox (一个用于容器管理和编排的开源对象集合),您可以开发自己的任务调度程序或集成第三方调度程序。
  • 负载均衡:Amazon ECS 已与 Application Load Balancing (ALB) 集成,支持您在多个容器之间分配流量。您只需指定任务定义和要使用的 ALB,Amazon ECS 服务计划程序将自动添加和删除 ALB 中的容器。您可以在任务定义中指定动态端口,这可为安排在 EC2 实例上的容器提供未使用的端口。您还可以使用基于路径的路由与多个服务共享 ALB。
  • 监控:Amazon ECS 为您的容器和集群提供了监控功能。您可以监控正在运行的任务的 CPU 和内存使用率及总和,这些任务通过 Amazon CloudWatch 按任务定义、服务或集群进行分组。您还可以设置 CloudWatch 警报,在您的容器或集群需要扩大或缩小规模时提醒您。
  • 日志记录:您可以将各个容器实例的 ECS 代理日志和 Docker 容器日志发送到 Amazon CloudWatch 日志,以简化问题诊断。借助 AWS CloudTrail,您还可以记录所有的 Amazon ECS API 调用并将日志文件发送给您。记录的信息包括 API 调用者的身份、API 调用的时间、API 调用者的源 IP 地址、请求参数以及 Amazon ECS 返回的响应元素。
  • 安全性:Amazon ECS支持您为每项 ECS 任务指定一个 IAM 角色。如此一来,ECS 容器实例将获得遵循“最低权限”访问策略的最小角色,允许您分别管理实例角色和任务角色。您还可以查看哪项任务使用哪个角色,这些信息均记录在 CloudTrail 日志中。
Amazon ECS的架构及工作原理
 
ECS的架构

ECS由以下主要组件构成:

  • Task Scheduler:任务调度器负责将task和service以task definition文件描述的形式按照一定的调度策略,放置到相应的Container Instance上进行运行。
  • Resource Manager:Resource Manager负责对宿主机进行通信,申请、释放并管理任务运行时所需资源。
  • ECS Cluster:ECS集群是一组EC2实例的集合,由运行Docker容器的Container Instance(容器实例)组成,构成了ECS运行的整体资源。当运行任务时,ECS会根据task definition的信息从ECR或者任何其他Docker镜像仓库中拉取对应的镜像文件,并在集群中运行。
  • Container Agent:Container Agent负责Container Instance与集群的心跳通信,负责访问Container Instance、健康检查、发送命令等等。默认Container Agent是内置在 Amazon ECS-optimized AMI中的,当您创建Container Instance就已经自动安装了Container Agent。
  • Container Instance:Container Instance就是安装了Container Agent并在ECS集群上进行了注册的EC2实例。当您运行ECS任务时,ECS会根据任务调度策略将任务放置到特定的Container Instance上运行。

图3:ECS的架构
跨AZ保证高可用性

Amazon ECS通过跨可用区(AZ)运行应用程序容器来保证高可用性。您需要在VPC中创建您的ECS集群,通过task definition(任务说明)和task service(服务说明)定义好Docker容器镜像文件,并其运行在您的ECS集群上。此外,您还可以通过Amazon ECR,Docker Hub或任何私有镜像仓库来存储和管理您的Docker容器镜像文件。

图4:跨分区运行ECS集群
灵活的任务调度

Amazon ECS将运行在容器中的作业分为两种类型:task(任务)和service(服务)。

一个task通常指的是一次性的作业,比如定时触发器、批量数据处理等,task 需要由一个task definition文件定义其所需的资源和处理过程,并将它运行在您的集群上。您可以指定运行在您的ECS集群上的task个数。

一个service服务指的是永久运行在后台的作业,您同样需要在task definition文件中对其进行定义。Amazon ECS允许您定义一定数量(由desired count参数指定)的任务进程来支持一个service,当某个任务进程失败或者不健康,ECS会自动启动新的任务进程,以保证该服务的任务数量达到desired count。

那么如何将这些任务放到特定的容器实例上呢?Amazon ECS提供的Task Placement Engine支持多种容器任务调度策略:

  • Binpacking:最少资源利用(根据CPU或者内存)的实例会优先被放置,这种策略会先将任务放到可用资源最少的实例上,减少了启动过多的实例,提高了资源利用率。
  • Spread:根据某个特定值进行平衡放置,这个特定值可以是一个键值对,也可以是instanceId或者host。一般可使用这种策略实现跨AZ的任务放置。
  • Affinity:组合条件的放置策略,比如两个符合条件的task不能同时放到某个实例中,或者两个符合条件的task必须同时放到某个实例中。
  • Distinct Instance:将每项任务放置在不同的容器实例中。

图5:任务调度策略

此外,您可以任意组合多种调度策略,或者通过BLOX项目自定义您的任务调度策略。关于BLOX,详见https://blox.github.io/

分层构建微服务方案

本节我们通过分布式应用中经典的CDN层、API层、应用层以及数据持久层分层介绍使用AWS ECS及其他AWS服务构建一个高性能、高可用的微服务。

图6:分层构建微服务
CDN层

CDN层的意义在于加速静态和动态资源的传输,并潜在地减轻后端服务器的压力。

使用CDN,可以让您的微服务应用客户端从最近的端点或者代理服务器、缓存服务器上获取资源,或者可以让您通往原数据服务器的链路得到优化,从而降低延时, 加快您网站及应用上的图片、视频、脚本等数据的传输。

API层

API层是所有请求的入口,它可以隐藏应用程序的业务逻辑细节,通过诸如HTTP REST API接受外部请求。API层一般还需要对所接收的请求进行流量管理、请求过滤、缓存及访问授权和控制。您可以使用Application Load Balancer(ALB)来实现您的API层。ALB是 Amazon Elastic Load Balancing(ELB) 服务的一个负载均衡选项,支持您在运行于一个或多个 EC2实例上的多个服务或容器之间基于内容定义路由规则。它可以做到:

  • 基于主机的路由:您可以基于 HTTP 标头的“主机”字段路由客户端请求,以便您从同一个负载均衡器路由到多个域。
  • 基于路径的路由:您可以基于 HTTP 标头的 URL 路径路由客户端请求。

ALB提供了对容器化应用程序的支持,您可以对应用程序负载均衡器进行配置,以在单个 EC2 实例的多个端口之间对容器进行负载均衡。借助 Amazon EC2 Container Service (ECS),您可以在 ECS 任务定义中指定一个动态端口,以便在将容器安排到 EC2 实例上时为其提供一个未使用的端口。ECS 计划程序会自动使用该端口将任务添加到 ALB Target Group。

如下图所示:您可以将ALB作为API层的入口,接收外部API调用请求,可以对请求进行过滤和访问控制,并根据一定的分发策略将请求分发给其代理的ECS集群,从而起来负载均衡的作用。关于更多ALB的介绍,请参考:http://docs.amazonaws.cn/elasticloadbalancing/latest/application/introduction.html

图7:使用ALB实现API层作为服务调用入口
应用层

应用层实现了具体的应用程序业务逻辑。AWS提供了多种方式来运行应用程序,您可以将程序直接部署到EC2上、或者使用Elastic Beanstalk服务快速构建运行环境,或者使用无服务器服务AWS Lambda、当然也可以使用容器管理服务ECS。这里介绍ECS利用容器技术运行应用层的好处。

  • 一致性:容器镜像文件具有一致性,无论您将同一个容器镜像部署到开发者的笔记本还是测试环境,抑或是生产环境,容器都会保持一致的工作。
  • 灵活性:容器技术将应用程序划分为各个独立的、松耦合的服务,这一点跟微服务架构思想是完美融合的。容器可以使微服务架构的灵活性得到更好的表现。
  • 高资源利用率:容器允许您预先定义需要使用的资源数据(比如CPU和内存),可以在多个下层宿主机构成的集群上共享资源,达到比虚拟机技术更好的资源利用率。
  • 高工作效率:容器具有一致性、版本公开性、松耦合和可轻松回滚等特性的可以重复使用的工作集。您不需要重复“造轮子”,无论从开发和运维上都可以提高您的工作效率。
数据持久层

数据持久层负责将业务中使用到的数据进行存储和管理。将数据管理和持久化单独封装一层,可以让应用层实现无状态化,从而便于应用层进行水平伸缩扩展和实现容错机制。

静态数据一般可以存储在AWS Simple Storage Service(S3)服务上,并通过AWS CloudFront进行分发。关于S3,可以参考 https://www.amazonaws.cn/s3/

会话数据和常用的数据,可以存储在数据缓存中间件中,比如Memcached或者Redis。AWS提供了ElasticCache服务管理这两种缓存服务。关于ElasticCache,可以参考 https://www.amazonaws.cn/elasticache/

对一致性要求较高的业务数据可以存储在关系型数据库中,AWS Relational Database Service(RDS)服务可以管理六大常见关系型数据库引擎(Microsoft SQL Serve,Oracle,MySQL,MariaDB,PostgreSQL, Amazon Aurora)。关于RDS,可以参考 https://www.amazonaws.cn/rds/

关系型数据库不利于伸缩和业务扩展,利用NoSQL数据库得到了更好的可扩展性、可用性和性能。您可以使用Amazon DynamoDB创建可以存储任意数据、应对大量访问的数据库表。DynamoDB可以将表中数据分布到足够多的服务器上,以满足高性能、大数据量、大访问量的存储要求。关于DynamoDB,可以参考https://www.amazonaws.cn/dynamodb/

解决微服务架构中的常见问题

在讨论如何分层构建微服务后,通过ECS和AWS相关服务,我们已经很大程序上减轻了架构和运维微服务应用所需的工作量。本节我们将讨微服务架构中另外几个常见的问题,并结合AWS提供的相关服务对这些问题进行分析和处理。

服务发现

如何让服务发现彼此并进行交互,这是微服务架构必须解决的问题。服务发现包括检查服务的健康状态以及自动发现新服务上线。在AWS中提供了几种方式来实现服务发现:

1. 基于 Application Load Balancer实现的服务发现

ALB具有健康检查和服务上线注册下线注销的功能,将这些功能与DNS解析服务相结合,可以低成本地轻松解决服务发现问题。

您可以给每个微服务设置自定义的域名,然后通过一个CNAME入口,将这些服务绑定到某个Elastic Load Balancer的DNS下。这些服务的DNS名将会被发布给所有需要访问服务的应用程序, 同时结合ALB基于路径路由的功能,能够利用Target Group和Path的结合分发给不同的微服务,节省资源和成本。

图8:基于Elastic Load Balancer的服务发现

2. 基于Key-Value对存储的服务发现

您还可以使用Key-Value键值对存储的形式来实现服务发现,虽然这种方式实现起来需要您花费比其他方式更多的时间,但是它能提供更好的灵活性和扩展性,并且不用担心DNS缓存问题。这种方式天生与客户端负载均衡技术相吻合,客户端负载均衡可以解决性能瓶颈并简化流量管理。

图9展示的是一个利用Amazon DynamoDB作为Key-Value键值存储,并结合DynamoDB Stream以生产者消费者模式来实现服务状态更改通知的架构。


图9:基于Key-Value对存储的服务发现

3. 基于第三方开源组件的服务发现

您还可以使用开源社区中的服务发现组件来构建服务发现,例如Hadoop的子项目ZooKeeper或者Hashicorp公司的Consul[vii], 这种方式的好处在于合理利用了已有的开源社区中的优秀框架来提供基于Key-Value的特定服务,并且这些开源社区的组件对AWS的集成也非常对友好,能够非常快速的搭建服务发现的方案。下图10展示了Consul与ECS的协同工作, 宿主机将会首先利用Registrator[ix]的Agent在Docker启动时将Consul Agent注册到Consul Server,由于Consul基于消息订阅的模型设计,所以其他服务很快收到订阅知道新的组件上线并且能够通过其API了解到其他服务的状态.


图10:基于Consul服务发现

 

数据一致性

单体型架构的应用一般都是将数据存储在一个数据库中,应用程序中所有模块统一使用一致的数据模型。微服务则不能使用这些中心数据库,因为这与微服务去中心化、要求独立型的原则不符。每一个微服务组件都可以拥有自己的一套数据持久化方案。那么如何在服务通信过程中,保持数据的一致性呢?

通常情况下,微服务中状态的变化将会影响整个系统数据的一致性。在这种情况下,事件驱动模型被实践证明可以用于实现数据的最终一致性。事件驱动模型的核心就是将应用程序每一次状态变化当作一个事件记录下来,与持久化数据状态不同,数据是通过一连串事件流存储起来的。数据库事务日志和版本控制就是应用事件驱动模型最出名的两个例子。

在微服务场景中,事件驱动模型以“订阅者-消费者”形式进行应用程序各服务间的解耦,在各个应用不同数据系统的微服务组件之间共享事件流数据,事件驱动模型还可用于读写分离场景,提升读和写的性能。

下图展示如何利用AWS Kinesis Stream作为中心事件流,捕获各个服务的数据变化作为事件,并将事件流记录在S3上。图中各个微服务组件由ALB、ECS和RDS组成,如图所示,微服务组件Microservice 1由于某个状态改变,向Kinesis发布事件,Kinesis将事件持久化到S3中(客户可以使用Redshift服务对这些事件流进行分析),其他微服务组件如Microservice 2和3订阅了这个事件,会拉取并过滤事件,并在本服务组件中进行相应的处理。通过这种机制,可以实现不同数据系统间数据的最终一致。

图11:Kinesis实现事件驱动
异步通信

在单体型架构的应用中,各个模块间的通信是非常简单的,可以是简单的方法调用或者通过内部事件发布机制。而当使用微服务架构时,服务间的通信必须通过网络远程调用。

常用的微服务通信机器除了HTTP REST API进行API调用外,对于一些对实时性要求不高,又耗时较长的通信场景,经常需要使用到消息队列实现异步通信。Amazon Simple Queue Service(SQS)和Amazon Simple Notification Service(SNS)都是AWS提供的用于异步通信、通知推送的服务。

服务监控与日志记录

在微服务架构中,您需要对各个服务进行监控,以判断服务是否健康,是否可用。您还需要对服务的API调用记录、访问记录等日志进行记录,以实现问题发现和追踪。

您可以使用Amazon CloudWatch来收集系统指标,集中管理和监控日志文件,设置预警并自动适应您的运行环境中发生的变化。Amazon CloudWatch可以监控的AWS资源包括EC2实例、DynamoDB表和RDS DB实例,也可以监控任何您的应用和服务生成的自定义指标和日志文件。

1. 监控

利用Amazon CloudWatch,您可以轻松地对微服务组件进行监控,可以监控整个系统的资源利用率、应用程序的性能和服务的健康状态。CloudWatch非常简单,只要进行一些简单的设置,您就可以拥有一套可靠、可伸缩、灵活的监控方案。您不再需要自己去维护一个复杂的监控系统。在微服务架构中运用CloudWatch的另一个好处就是,CloudWatch提供的自定义收集指标可以让开发人员针对特定服务定制特定指标。另外,基于收集到的自定义指标,自动伸缩也可以得到轻松地实现。

2. 记录日志

持续记录日志对于排查和发现问题起到非常重要的作用。微服务让产生的更新发布频率比以往传统架构更多,并鼓励工程师团队更多地尝试新的功能和特性。了解用户的影响对整个应用的逐步提升起来决定性的作用。
为了更好地调试和总览整个分布式系统的状况,我们必需将日志存储在一个统一的中心。在AWS中,您可以使用Amazon CloudWatch Logs来监控、存储和访问您EC2实例上、CloudTrail或者其他资源上的日志文件。

3. 集中管理日志

您可以有很多不同的选择来集中管理日志文件。大部分AWS服务已经“开箱即用”地集中了日志文件。在AWS中,首要的存放日志文件的地方就是Amazon S3和Amazon CloudWatch Logs。图13展示的是一些AWS服务的日志记录能力。日志文件对于每个系统来说都是重要的部分,基本每一个系统操作都会生成一条日志记录。中心化的日志管理方案就是将所有日志文件放在一个统一的中心位置,这样便于日志的访问、查询和分析。

图12:AWS部分服务的日志记录能力

4. Correlation IDs(关联ID)

在很多场景中,一个请求需要由多个微服务共同合作进行处理。想象一下,一个由数十个微服务组成的复杂的系统,当服务链中某个服务出现一个错误时的对整个服务链所造成的影响有多大。即使每一个微服务都有进行很好的日志记录,并集中化日志管理,要追踪出现的错误,需要将所有这些跟这个错误关联的日志都找出来,这是非常困难的。

关联ID的中心思想就是,当负责面向用户的服务收到请求时创建一个特定的ID。这个ID可以放在HTTP头(比如,使用类似“x-correlation-id”这个的头字段)然后在服务链中传递到其他服务中去。这个ID就可以在各个服务独立的日志中记录,这样针对特定请求,就可以根据这个关联ID将所有关联的日志记录都找出来了。

为了得到日志文件中正确的服务调用顺序,可以在HTTP头中传递一个计数器,每经过一个服务就累加一次。

审计

在微服务架构中需要处理的另一个挑战,就是潜在的数百个分布式服务如何既确保所有用户操作的可见性,又能够在组织层面获得良好的整体感观。为了加强安全管理,对资源访问和引起系统变化的操作进行审计就显得非常重要。对系统的更改无论在独个服务中,还是在跨服务的整个系统层面,都必须进行严格追踪记录。在微服务架构中,更改是经常需要发生的,这也就让对更改的审计变得更加重要。

1. 审计追踪

AWS CloudTrail是一个非常有用的在微服务中追踪更改的工具,因为它能将所有在AWS平台上的API调用进行记录,并实时传送到CloudWatch Logs或者几分钟内传送到Amazon S3中。它可以记录从AWS Management Console、AWS CLI、SDK发起或者直接调用的记录。

所有用户的行为和自动化运行的系统行为都变成可以查询和分析的。CloudTrail记录的信息包括用户账号、时间戳、调用的目标服务、调用者的IP地址、请求参数和返回响应元素。

2. 事件和实时操作

整个系统结构中有一些系统状态的变化是必须对其进行快速响应的,必须快速进行修复或者必须及时跟进处理这些变化。Amazon CloudWatch Events实现了一个近实时的事件系统。它可以声明一些适配某些系统状态变化的规则,并定义好自动响应这些变化的措施。

Amazon CloudWatch Events与CloudTrail结合,可以为所有AWS服务上的所有API调用生成事件。它还支持自定义事件或者根据某个特定的调度策略生成事件(比如定时事件)。当一个事件发生并且符合您系统中定义的规则时,CloudWatch Events将立即通知您预先定义好的系统中的某个角色或人物,以便他们及时做出响应措施。更好的做法是,当事件触发时,您可以定义自动化处理的工作流或者调用一个自定义的Lambda function。

图13展示的是使用CloudTrail和CloudWatch Events处理在一个微服务架构系统中进行审计和系统修复的需求。所有的微服务都由CloudTrail进行追踪、审计并将审计信息存储在S3 bucket中。当一个对您系统的更改发生时,CloudWatch Events能在CloudTrail基础上触发事件警告,及时通知系统管理员。您还可以对所有这些日志信息使用Elasticsearch等搜索引擎技术进行日志查询。

图13:审计追踪和系统修复

总结

微服务架构可以突破传统单体型架构遇到的种种限制,它是松耦合的,去中心化的,黑盒的,多语种的,在可用性、可靠性、可伸缩性、可扩展性、安全性、性能和工作效率上更加优秀。但微服务架构也面临着像资源管理、服务发现、消息通信、数据一致性等诸多问题和挑战,利用AWS提供的ECS及其他相关服务,可以解决微服务架构面临的挑战和难题,轻松架构微服务应用,更好地拥抱微服务带来的种种便利。

客户案例

Remind

(https://aws.amazon.com/cn/solutions/case-studies/remind/)

Remind 是一款 Web 和移动应用程序,教师可以使用该应用程序向学生发送短信并与家长保持联系。Remind 在自己的平台上拥有 2500 万名用户和 150 多万名教师,该应用程序每月可发送 1.5 亿条消息。

“迁移到 Amazon ECS 后,我们服务的性能得到了显著提升。我们将服务响应时间的第 99 个百分位降低了 50%。” – Jason Fischl 工程师副总裁

Coursera

(https://aws.amazon.com/cn/solutions/case-studies/coursera-ecs/)

Coursera 是一家教育技术公司,致力于在全球范围内提供世界上最好的课程。该公司与世界各地的顶尖大学和机构合作,为所有人免费提供各种在线课程。Coursera 拥有来自 190 个国家/地区的 1300 多万用户,提供来自 119 个机构的 1000 多个课程,涵盖从 Python 编程到作曲的各个主题。

“借助 Amazon ECS,Coursera 可以集中精力发布新软件,无需花时间管理群集。” – Frank Chen软件工程师

Shippable

(https://aws.amazon.com/cn/solutions/case-studies/shippable/)

Shippable 是一个提供托管式持续集成、测试和使用 GitHub 和 Bitbucket 等存储库进行部署的平台。该公司在从应用程序创建一直到向最终用户交付软件的整个过程中为开发人员和运营团队提供帮助,并在整个过程中实现完全的自动化和完全的控制。Shippable 的平台有助于消除实现重复性持续集成/持续交付和工作流中的阻碍和难题,这样,开发人员便能够专注于交付高质量代码。

“借助 Amazon ECS,我们的开发人员几乎不用花时间在运营相关工作上。过去,我们的高级开发人员需要将 80% 的时间花费在后端基础设施管理功能方面,而现在则将 80% 的时间投入在客户功能上。” – Avi Cavale首席执行官兼联合创始人

Segment

(https://aws.amazon.com/cn/solutions/case-studies/segment/)

Segment 为企业提供一种可从枢纽中心收集客户数据,以备日后用于分析、市场营销和其他用途的服务。该公司的总部位于旧金山,拥有广泛的客户群,从初创公司到大型企业,其中包括 Nokia、Angie’s List、Conde Nast、The Motley Fool 和 Salesforce Foundation 等。

“转而使用 Amazon ECS 大大简化了服务的运行,无需担心预配置或可用性。”- Calvin French-Owen联合创始人兼首席技术官

mytaxi

(https://aws.amazon.com/cn/solutions/case-studies/mytaxi/)

mytaxi 基于 AWS 设计了一款采用速度快且可轻松扩展的 Docker 容器的微服务架构,以应对新年除夕等特别日子的需求高峰。该公司运行着欧洲领先的出租车应用程序,此应用程序在 40 个城市中将 1000 万用户与 45000 辆出租车联系起来。整个基础设施都构建在 AWS 之上,其中的 Amazon EC2 和 Amazon ECS 等服务可为 mytaxi 的 Docker 容器提供支持。

“2015 年 11 月,我们将 Docker 容器架构移动到了 Amazon ECS,而在 12 月,我们有史以来第一次能够庆祝新年,因为我们的系统可以处理大量请求,并且没有发生任何崩溃或中断,我们对这项成就感到极为自豪。”- Sebastian Herzberg系统工程师

 

Burda Studios

(https://aws.amazon.com/cn/solutions/case-studies/burda-studio/)

BurdaStudios 是全球媒体集团 Hubert Burda Media 的一个部门,拥有近 10000 名员工和 500 多个品牌,包括家庭和生活方式类杂志以及企业间出版物。BurdaStudios 专门从事影视制作和数字出版。该公司的旗舰网站是 Bunte.de,一个在德语欧洲国家/地区 (德国、瑞士和奥地利) 处于领先地位的名人八卦门户。该网站是了解好莱坞演员、体育明星和皇室成员最新新闻的首选网站。它吸引了 600 万独立用户,月访问量高达 3000 – 3500 万次 (其独立用户的数量比最大竞争对手高出约 20%),通过展示、视频和本地广告盈利。

“我们通过 AWS 和微服务架构所做的事情正是数字出版业的未来。”- Hansjörg Posch BurdaStudios 首席技术官

Airtime

(https://aws.amazon.com/cn/solutions/case-studies/airtime/)

使用 AWS 服务重新设计其应用程序之后,Airtime 能够以更加快速可靠的方式为客户提供社交体验,而且不会产生任何延迟。Airtime 是一家社交媒体公司,也是一款移动应用程序,可让用户在 iOS 和 Android 设备上实时分享自己喜爱的音乐、视频,并进行消息收发。该公司通过使用 Amazon EC2、Amazon Route 53 和 Amazon S3 等基本服务开始了采用 AWS 的过程,然后重新设计了自己的平台,以便能在采用 Amazon EC2 Container Service (Amazon ECS) 和 Docker 容器的微服务架构上运行。除了改善客户体验之外,Airtime 还通过滚动部署简化了内部流程,而且可以利用 Elastic Load Balancing Connection Draining 等较新的 AWS 功能。

Abema TV

(https://aws.amazon.com/cn/solutions/case-studies/abema-tv/)

AbemaTV 是一家互联网媒体服务公司,运营着日本领先的流媒体平台之一 – FRESH!by AbemaTV。目前, FRESH! by AbemaTV 可提供大约 1400 个频道和将近 37000 个节目:从广播电台的流媒体服务到由 CyberAgent (AbemaTV 的母公司) 开发的原版影视剧,应有尽有。AbemaTV 使用 Amazon Aurora 数据存储来执行其写入密集型微服务 (例如时间表和聊天),并利用 Amazon Relational Database Service (Amazon RDS) 上的 MySQL 数据库来处理剩余的微服务 API。所有 API 都通过 Amazon CloudFront 和 Amazon API Gateway 进行管理。对于可能会影响 API 响应时间的流程,AbemaTV 实施了一套可通过 Amazon Simple Queue Service (Amazon SQS) 队列接收任务的工作程序。

“Amazon EC2 Container Service 对于我们构建具有高可用性、稳定性的微服务,以及受益于各种 AWS 服务而言至关重要。”- Akinori Yamada 工程团队

Linden Lab

(https://aws.amazon.com/cn/solutions/case-studies/linden-lab/)

Linden Lab 是一家总部位于旧金山的互联网公司,因推出 Second Life 虚拟世界而广为人知。Second Life 为用户提供了一个可生成 3D 内容并与之进行互动的平台。用户可通过 Linden Lab 的客户端程序或通过可选的第三方查看器访问 Second Life 虚拟世界。该公司的其他产品包括 Blocksworld,它让用户可以构建虚拟 3D 块并使用这些 3D 块进行游戏;还包括“Project Sansar”,这是计划于 2016 年发布的用于提供虚拟体验的新平台代码名称。

“使用 Amazon EC2 Container Service,我们可以切实地提高开发速度,从而将构建和部署时间缩短 50% 或更高。借助 Amazon ECS,我们拥有了一个非常稳定的平台,这让我们可以大幅扩展产品规模。” – Landon McDowell 运营副总裁

CyberAgent

(https://aws.amazon.com/cn/solutions/case-studies/cyberagent/)

CyberAgent 是一家互联网媒体服务公司,运营着日本领先的流媒体平台之一 – FRESH!。目前,FRESH! 可提供大约 1400 个频道和将近 37000 个节目,从广播电台的流媒体服务到原版影视剧,应有尽有。CyberAgent 使用 Amazon Aurora 数据存储来执行其写入密集型微服务 (例如时间安排和对话),并利用 Amazon Relational Database Service (Amazon RDS) 上的 MySQL 数据库来处理其余的微服务 API。所有 API 都通过 Amazon CloudFront 和 Amazon API Gateway 进行管理。对于可能会影响 API 响应时间的流程,CyberAgent 实施了一套可通过 Amazon Simple Queue Service (Amazon SQS) 队列接收任务的工作程序。

“Amazon EC2 Container Service 对于我们构建具有高可用性、稳定性的微服务,以及受益于各种 AWS 服务而言至关重要。” – Akinori Yamada 工程团队

Meteor Development Group

(https://aws.amazon.com/cn/solutions/case-studies/meteor-development-group/)

Meteor Development Group 是一款开源的跨平台 JavaScript 应用程序平台,开发人员可以使用它为 Web、Android 和 iOS 应用程序编写代码。Meteor 由总部位于旧金山的 Meteor Development Group 创建,使用分布式数据协议和发布-订阅模式自动将更改传送给客户,无需开发人员编写同步代码。Meteor 是 GitHub 上领先的 Web 应用程序框架,每天有数以千计的公司要依靠该平台构建现代化应用程序。

“AWS 的稳定性大家有目共睹。我们面临的难题是:‘我们能够扩展运行所有客户应用程序所需的计算资源数量吗?’以及,“我们能够扩展协调所有这些资源的机制吗?”使用 AWS,我们可以对这两个问题回答‘能’。” – Matt DeBergalis 联合创始人兼产品副总裁

引用

[vi] https://www.docker.com

[vii] https://aws.amazon.com/cloudformation/

[viii] https://www.consul.io/

[ix]http://gliderlabs.github.io/registrator/latest/

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(上篇)

更多白皮书:https://aws.amazon.com/cn/whitepapers/

观看在线研讨会视频-运行在Amazon ECS上的微服务架构及实践

 

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(上篇)

简介

微服务是一种软件开发的组织和架构方法,它可以加快软件交付周期、增强创新和自主性,提高软件的可维护性和可伸缩、可扩展性,同时也提高了企业开发和发布软件服务的能力。使用微服务架构,软件产品将由多个独立的、可通过API进行交互的服务组成。这些服务将由各个小团队独自负责。

通过本白皮书,我们将首先总结一下微服务架构的特性,讨论构建微服务架构面临的挑战和难题,然后介绍AWS的ECS容器集群服务,以及如何利用ECS结合其他AWS提供的服务解决微服务架构中遇到的难题。

什么是微服务架构

微服务架构的特性

近些年,微服务架构的概念变得越来越火[i],事实上微服务并非某项具体的技术或框架,它也不是软件工程学中新的概念,而是一些成功的,经过实践论证的概念的组合,比如面向对象方法论、敏捷开发、面向服务架构、API-first设计、以及持续集成。

“微服务”这个名词是一个概括性的术语,很难对其进行精确的定义。但是所有微服务架构方法都具有以下共同特性:

  • 去中心化:微服务架构是由去中心化数据管理的分布式系统组成。它不依赖中心数据库上统一的数据库模式。每一个服务都有自己独立的数据模型。去中心化的另一个含义是,每个服务在开发、部署、管理和维护过程中也是相互独立的,不依赖某个中心系统。
  • 独立:微服务架构中各个服务组件都可以独立进行更改、升级和替换,而不会影响其他服务组件的正常功能。同样,负责各个服务组件的团队之间也都是相互独立的,互不干扰的。
  • 专注做好一件事:每个服务组件都是专注于某个问题域的功能集合,一旦某个服务复杂度到达一定程度,则应该考虑将其进行服务切分或对其进行再次微服务架构。
  • 多语种:微服务并不是“一体通用”的方法,它允许各个团队根据自己的喜好选择最适合自己问题域的开发语言、开发工具。因此,微服务无论在操作系统、开发语言、数据存储还是工具,都是兼容的。也就是说,微服务是“多语种”的。
  • 黑盒子:微服务中的服务都是按照“黑盒”设计的,也就是说,它们将内部逻辑对外隐藏进来,各个服务间通过定义良好的API进行通信,避免了暗含的相互依赖。
  • 谁构建,谁运行:通常情况下,在生产环境中,构建了某个服务的团队负责该服务的运行和维护。这条规则也称之为DevOps[ii]。DevOps除了能让各个团队按照自己的安排独立工作外,还可以让开发人员更贴近软件产品的真正使用者,能帮助他们更好地了解用户的需求。微服务对于企业组织架构上的影响也是不容忽视的,正如康威定律所言,系统架构是公司组织架构的反映[iii]。

图1:微服务架构的特征

单体型架构 vs. SOA vs. 微服务架构

技术为业务而生,架构也为业务而出现,无论传统单体型架构、SOA和微服务都是因为业务的发展而出现。出现SOA以及微服务框架与业务的发展、平台的壮大密不可分。

单体型架构

当网站或者应用流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本,简化开发流程,适合于个人开发或者小团队开发一些功能单一的小产品使用。这是最传统的架构模式,一般整个系统都是有一个统一的数据中心,各个功能模块显式进行相互依赖(比如直接调用模块公开的方法)。当网站流量随着业务发展不断变大时,这种架构的应用在可扩展性、容错性(一旦某个功能模块被流量击溃,整个系统瘫痪)上存在致命性的缺陷。

SOA

当网站或者应用流量变大,单体型架构无法招架之时,可以采取面向服务架构方式,将应用根据系统维度、功能维度、读写维度或者模块维度进行划分成各个独立的服务组件,服务组件间通过某个约定的方式(比如Web Service或者HTTP REST API)进行通信。当服务越来越多,容量的难以准确评估,小服务导致资源浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率,这种架构一般仍然存在一个统一的数据中心或者调度中心。整个系统的可维护性、可扩展性相对于单体型架构得到提高,但在服务细粒度、隔度性、去中心化方面仍与微服务有差,另外就是SOA架构常常依赖于总线结构,利用可热插拔的中间件以及消息队列来完成服务与服务之间的解耦,对于总线结构的依赖也使得服务的独立性并没有被完全剥离。

微服务架构

在微服务架构中,每个服务都要去中心化,不存在单点故障问题。每个服务都要实现高可用、高负载,不会因为一个服务不可用而影响整套业务流。每个服务细粒度,专注于自己的问题域,与别的服务采用更好的Restful或者良好定义的API进行通信。服务都要高度通用化,即多种终端都可调用,不分语言和平台服务部署或升级简单,不会消耗大量人力并且部署过程不易出现人为错误,同时还具有快速注册与自动服务发现功能。

微服务的益处

许多AWS客户选择微服务架构来解决传统单体型架构中存在的敏捷性和可扩展性限制的问题。让我们来看看选择微服务架构能够带来哪些方面的益处吧。

敏捷

使用微服务的组织由多个负责运维独立服务的小团队组成。各个团队都是在界限明确的小范围内独立、快速地工作,从而起到减小迭代时间的效果。各个小团队效率的提升将使整个企业组织工作效率进行很大程序地提高。

图2标示由多个小团队组成的企业组织架构与由一个大团队组成的企业组织架构,在发布部署一个应用时的工作效率区别。

图2:部署微服务
创新

小团队可以独立自主地针对自己负责的问题域选择相关的技术、框架和工具,这就是创新的体现。职责与义务,让团队产生对自己的服务的责任感。

DevOps通过将开发与运维人员结合到一个团队中,让他们能更早地、更好地沟通,解决了开发部署过程中没必要的摩擦和矛盾。当应用程序部署时,敏捷的处理流程可以让开发和运维工作不再需要暂停下来,相反,整个软件交付周期,从提交代码到发布版本,整个流程将变成自动化的。测试一个新的想法,或者当新功能出现问题时及时回滚,将变得更加轻松。因为失败成本的降低,团队将更加乐于更改和创新。

质量

使用微服务架构您的应用程序,将一定程度上提高代码质量。这跟面向对象设计中提出的分模块开发有同样的效果:提高代码的可重用性、封装性和可维护性。

伸缩性

细粒度解耦的微服务架构另一个好处就是,它非常适合构建大规模系统。它允许针对不同的服务选择最适合的技术,这也是性能优化的体现。每个服务都可以使用最合适的开发语言和框架来实现,利用最优的数据持久化解决方案,并通过各自独立的服务配置进行调优。

合理解耦的微服务架构,可以独立地进行水平伸缩扩展。这相对于传统架构中使用的垂直伸缩有很大的优势。垂直伸缩指的是当业务量、流量增大时,升级硬件资源,将应用部署到“更大的机器”上,这会导致“机器硬件资源上限”和伸缩时宕机的问题。水平伸缩,通过将更多的服务部署到服务池(多个机器组成的集群)中,可以动态地适配流量,并且不会陷入单个机器资源上限问题。整个水平伸缩的过程将会是自动化的。另外,应用程序的可靠性将得到增加,因为出现问题的服务可以自动地被健康的服务替换掉,而不影响整个应用的运行。

可用性

微服务架构可以轻松实现故障隔离。通过健康检查、缓存、隔离仓、断路器等技术,可以减小当某个组件出现故障时的影响,从而保证应用的高可用性。

微服务架构面临的挑战

尽管拥有前面提到的那么多优点,但是微服务架构和所有其他架构一样,都不是解决所有问题的“银弹”。使用微服务架构也会面临一些挑战和难题。比如:

  • 微服务架构都是分布式的,也就会存在所有“分布式计算误区”中提到的问题[iv]。
  • 从单体型架构迁移至微服务架构,需要您准确地划分好各个服务间的界限,并且从应用层到数据库层松耦合代码依赖。
  • 除此之外,在组织管理方面还存在着一些挑战,比如如何组建一个高效的团队,如何将团队转变成DevOps的生产模式,如何合理化开发团队与运维团队的沟通等。

本白皮书主要关注的是架构和运维方面遇到的挑战,如果想了解更多关于AWS如何运用DevOps的知识,请访问https://aws.amazon.com/devops[v]

架构复杂度

在传统单体型架构中,所有的复杂度和依赖都存在项目的代码库中。而对于微服务架构而言,复杂度变成了各个服务间的交互。

在架构上面临的挑战有处理异步通信、连锁故障、数据一致性问题、服务发现和授权认证等问题。

运维复杂度

运用微服务架构,你不再只是运行一个服务,而是数十个,甚至数百个服务。这也就带来了以下问题:

  • 如何以可伸缩、低成本的方式配置好所需要的资源?
  • 如何避免不同的团队重复“造轮子”,重复处理同一个问题,或重复安装配置相同的软件工具?
  • 如何跟踪并管理好上百个代码流的部署过程和它们之间的相互依赖(不同服务可以单独部署)?
  • 如何监控整个系统的健康并提前感知潜在的热点和流量高峰?
  • 如何在整个系统各个服务间追踪和调试问题?
  • 如何分析一个快速增长并超出预期需求的分布式系统的海量日志数据?
  • 如何处理不同技术栈、开发环境间缺少统一标准的问题?
  • 如何受益于不同技术带来的开发效率,而不受困于维护升级这些技术带来的困难?

微服务与云平台

微服务近些年的崛起与诸如AWS这样的公有云平台的发展密切相关。AWS提供了可以直接解决微服务架构面临的挑战的服务。

  • 按需资源调配:资源可以快速根据资源进行配备。相对于传统的基础设施,云平台几乎可以说在资源上是没有上限的。运行于不同环境、不同版本的服务可以临时或永久地共存。不同需要进行困难的资源预测和评估。按需资源调配解决了如何以可伸缩、低成本的方式配置好所需要的资源的问题。
  • 低成本低风险地进行尝试:你只需为你使用的资源付费,从一定程序上降低了你尝试新想法的成本。新功能或者新服务可以快速地发布,并且当尝试失败时,可以快速关闭这些服务和其所需的资源。降低尝试新想法所需的成本和风险,将大力推动更多的创新。这也是跟微服务架构提倡的高度敏捷相符合。
  • 可编程性:AWS服务自带API、命令行工具(CLI)和针对不同语言的SDK。服务器甚至整个架构都可以通过编码的方式进行克隆、关闭、扩展、监控并且在发生故障时实现自动恢复。标准化和自动化是构建速度、一致性、重复性和可伸缩的关键。你可以通过编码的方式统一管理你所需的资源,减少运维微服务架构所需的精力。
  • 基础设施即代码:除了可以编写脚本来配置和管理你的资源,AWS还支持你将基础设施代码化,像应用程序的代码一样放置到版本管理工具中进行管理。因此,各个版本的基础设施都可以随时进行重新部署。你可以保证基础设施代码与应用程序代码一样的质量和性能。回滚不再只与代码相关,也包含整个基础设施。可编程性和基础设施即代码可以解决运行、维护、扩展微服务架构时面临的问题。
  • 持续交付:云平台的可编程性推动了配置和部署流程的自动化。开发阶段的持续集成概念也因此可以扩展到运维阶段(因为运维也是可编码的了),从而形成持续集成与交付的概念。持续交付解决了如何同时管理多个代码流并行部署交付的问题。
  • 自我管理的服务:云平台最出色的优点就是服务都是自我管理的。你不再需要进行繁重的配置虚拟机、安装配置优化软件、处理资源伸缩扩展、管理备份等运维工作。诸如监控、安全、记录日志、伸缩和保持可用性等系统操作和特性都在云平台服务中内置好了。自我管理的服务从一定程度上缓解了运行微服务架构的复杂度和工作量。
  • 面向服务:AWS本身就是微服务架构的。每一个AWS服务都是针对某个特定问题域的,并且都是通过API进行相互通信。你可以将这些服务像乐高积木一样组合成复杂的结构,用来解决特定的问题。这样就解决了重复“造轮子”的问题。
  • 多语种:AWS提供了多种存储得数据库技术供你选择。AWS Marketplace上有许多可以运行在EC2上的操作系统供你使用。AWS的SDK支持各种各样主流开发语言。这可以让你根据特定问题选择最合适的技术方案,从而避免重复“造轮子”问题。

引用

[i] https://www.google.com/trend/explore#q=Microservices
[ii] https://en.wikipedia.org/wiki/DevOps
[iii] https://en.wikipedia.org/wiki/Conway%27s_law
[iv] https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
[v] https://aws.amazon.com/devops/

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(下篇)

更多白皮书:https://aws.amazon.com/cn/whitepapers/

观看在线研讨会视频-运行在Amazon ECS上的微服务架构及实践

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

Amazon EC2 Container Service打造容器化的SaaS应用

概述

在SaaS化应用的改造中,容器技术的应用越来越广泛。相对于传统的虚拟机模式,容器化模式的隔离技术“更轻量”,“ 更快速”,“ 更便捷”. 目前业界越来越广的使用“容器”技术用于应用的微服务化改造,将自己产品的一些服务“微服务”化,构建基于云平台的SaaS化应用。

容器技术改造的难点

1. 技术的复杂性

容器技术应用的难点在于生产环境的实施及部署, 一般需要解决

  • 容器资源编排调度
  • 服务的自动发现及注册
  • 容器的监控及报警
  • 容器的扩展及收缩

这只是解决的部分问题,用户还必须去解决生产环境部署中怎样实现高可用部署及与公有云平台的集成问题。这使得Docker的生产化部署变得困难。

2. Docker编排框架的选型

许多人认为容器技术的价值在编排层,目前在容器的编排框架上主要的流派正在上演 “三国演义”包括,Google Kubernetes、Apache Mesos、Docker  DockerSwarm. Kubernetes,Mesos是目前市场上比较成熟的解决方案,占有较大的市场份额。DockerSwarm的优点是与Docker平台中的许多功能的集成,因为它平滑地内置于Docker平台中。上述三个编排框架都开放源代码,用户只需为技术支持服务付费。除了这些标准外还有许多初创公司也推出了自有的编排框架, 如Rancher使用Java语言开发了Cattle,它是Rancher实现的自有的一套基于Docker的编排引擎。众多的开源或自有的编排框架在不断发展,演进。这给客户的技术平台选型也带来极大的挑战。

Amazon EC2 Container Service(ECS)

为了降低容器平台生产部署的复杂性,Amazon ECS提供了一个平台来管理Docker容器。Amazon ECS是一项高度可扩展的高性能容器管理服务,您将不再需要安装、运维、扩展自己的群集管理基础设施。只需进行简单的 API 调用,您便可以启动和停止支持 Docker 应用程序,查询群集的完整状态,使用各种熟悉的功能,包括安全组、Elastic Load Balancing、EBS 卷和 IAM 角色。您可以使用 Amazon ECS 根据您的资源需求和可用性要求在您的群集中安排容器的置放。您还可以集成自己的或第三方的计划程序,以满足业务或应用程序的特定要求。Amazon EC2 Container Service 没有任何附加费用。您只需为您创建的用于存储和运行应用程序的 AWS 资源 (例如 EC2 实例或 EBS 卷) 付费。Amazon ECS的介绍,请参阅:https://aws.amazon.com/cn/documentation/ecs/

让我们来先看一个简单的Docker应用场景

客户有多套应用系统部署在云端,采用虚拟机隔离的方式,每套系统独占虚拟机资源,造成资源利用率不高。希望通过微服务化改造来提高云资源的利用效率及应用部署的敏捷性。改造的方法是从系统架构上分离应用层,使用Docker来封装应用层工作负载。采用Docker封装是微服务化改造最便捷的一种方式,因为对原有系统的代码修改少。降低了改造,迁移的成本。

将WEB,APP层直接封装成Docker容器运行。前端通过负载均衡传入流量,并负载均衡到Docker集群上。 需要实现服务的自动发现及注册,两级(Docker, EC2)自动扩展/收缩及容器的监控及报警。

下面我们就来介绍一下基于Amazon ECS的实现方法。

1. 应用层的封装

ECS提供了ECR(存储库),具有与Docker HUB一样的镜像存储管理功能.我们准备一个镜像来演示我们的应用层封装,这是一个Apache服务器的镜像,Dockerfile定义如下:

为了模拟三个不同的应用,我们对Apache服务器的配置做小小的更改:

在配置文件中新加了两个目录: app1, app2.并更改目录的初始页面的标题为目录名,这样当访问

提交更改

将镜像Push到ECR存储库,就得到了我们封装的应用层镜像

2. 创建服务

ECS有几个比较重要的概念。 任务服务集群

  • 任务就是您的应用程序的蓝图,是一个最基本的功能单元,包括构成应用程序的一个或多个容器,比如我们的案例中,封装的Apache镜像就是一个任务只包含了一个容器,但在实际案例中任务可能会有一个或多个容器,比如WEB容器,APP容器,它们共同组成一个任务。
  • 多个在一个容器实例或跨主机容器实例运行的任务就构成了服务,服务更像是一个应用的集群,ECS可以与ALB集成实现服务的自动注册及发现。通过使用动态端口映射选项,我们可以简单地注册一个服务到负载均衡器,而 ECS透明地管理Docker容器的注册和注销。我们还得到了传统负载平衡器的所有特性,如健康检查、连接保持和访问日志等。
  • 集群是EC2 实例的逻辑分组。Amazon ECS 从您指定的注册表中下载容器映像,并在集群内的容器实例上运行这些映像。

我们首先创建任务:

由于我们通过不同的URL路径来区分不同的应用,这里只需要创建一个任务定义

任务定义名称: taskweb

任务角色:

网络模式:        桥接

约束:

容器定义:

容器名称: dockerweb

映像: 772041933387.dkr.ecr.us-east-1.amazonaws.com/web-app:v1

内存限制:512M

端口映射:    主机端口:0  容器端口:80  协议:tcp

命令:    /usr/sbin/apache2,-D,FOREGROUND

然后创建集群:

集群名称: erp

实例配置:

预配置模型: 按需实例

EC2 实例类型: m4.large

实例的数量: 4

EC2 Ami Id: amzn-ami-2016.09.g-amazon-ecs-optimized [ami-275ffe31]

EBS 存储: 22

密钥对: martin

联网:

VPC: martin

子网: Pub1

Pub2

安全组: ECSSG

容器实例IAM 角色: ecsInstanceRole

创建负载均衡的ALB

名称: albdocker

模式: 面向internet

IP 地址类型: ipv4

侦听器: http:80

可用区

VPC: martin

AZ: pub1

pub2

分配安全组: ecssg
目标组名称: targetweb

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php
目标组名称: targetapp1

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php
目标组名称: targetapp2

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php

在集群中创建代表不同应用的服务:

服务名称:srvweb

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetweb

路径模式: /

运行状况检查路径: /index.php
服务名称:srvapp1

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetapp1

路径模式: /

运行状况检查路径: /index.php
服务名称: srvapp2

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetapp1

路径模式: /

运行状况检查路径: /index.php

创建完服务后,srvapp1, srvapp1, srvweb已经自动完成在ALB的注册

实现了如下的架构:

集群的状态如下:

现在我们已经实现了微服务化的改造,通过不同的URL就可以访问运行在Docker集群上不同的应用程序。

3. 自动扩展/收缩及监控,报警

还有两级(Docker,EC2)自动扩展/收缩及容器的监控及报警的功能怎么实现呢?  ECS集成了Auto Scaling, Cloudwatch。在集群和服务中都有Autoscaling组,只需要简单配置就可以了,如下图:

看看是不是很简单呢?除了我们可以通过Portal来实现外,ECS还提供了API接口。那还等什么,赶紧去试试吧!

 

作者介绍

杨历,AWS解决方案架构师负责AWS中国合作伙伴生态系统的技术支持工作,致力于为合作伙伴提供AWS云计算方案架构的咨询和设计,上云迁移, 应用优化,培训等服务。在高可用,灾备解决方案,大规模并发应用架构,自动化运维,RDBMS,数据仓库,数据集成等方面有着广泛的设计和实践经验。在加入AWS之前曾在Oracle研发中心,Oracle中国,微软中国担任研发工程师,资深技术顾问等工作。

Amazon EC2 Container Service – 发布回顾、客户案例和代码

今天似乎是回顾在过去一年左右的时间里我们添加到 [madison] 的一些功能,以及与您分享一些客户成功案例和代码的大好时机!该服务使您可以轻松地在托管的 EC2 实例群集上运行任意数量的 Docker 容器,并获得完整的控制台APICloudFormationCLIPowerShell 支持。您可以将您的 Linux 和 Windows Docker 镜像存储在 EC2 容器注册表中以方便访问。

发布回顾

我们先来看一些最新的 ECS 功能和一些演示如何使用这些功能的有用的操作方法博客文章:

应用程序负载均衡 – 去年我们添加了对应用程序负载均衡器的支持。这一高性能的负载均衡选项在应用程序级别运行,允许您定义基于内容的路由规则。它支持动态端口,并且可以跨多个服务共享,使您更容易在容器中运行微服务器。要了解更多信息,请阅读有关服务负载均衡的信息。

任务的 IAM 角色 – 您可以通过向 ECS 任务分配 IAM 角色来保护您的基础设施。这允许您基于每个任务精细地授予权限,从而可根据每个任务的需要自定义权限。阅读任务的 IAM 角色,了解更多信息。

服务 Auto Scaling – 您可以定义扩展策略,以根据需求的变化来扩展和缩减您的服务 (任务)。您只需设置所需的最小和最大任务数,并创建一个或多个扩展策略,服务 Auto Scaling 将负责其余的工作。服务 Auto Scaling 的文档可帮助您使用此功能。Blox – 在基于容器的环境中,调度是将任务分配给实例的过程。ECS 为您提供三个选项:自动 (通过内置的服务计划程序)、手动 (通过RunTask 函数) 和自定义 (通过您提供的计划程序)。Blox 是一个开源计划程序,支持每个主机一个任务模型,并留有适应将来的其他模型的空间。它监控群集的状态,非常适合运行监控代理、日志收集器和其他守护程序风格的任务。

Windows – 我们推出了支持 Linux 容器的 ECS,随后又增加了支持范围以支持运行 Windows Server 2016 Base with Containers

容器实例耗尽 – 有时您可能需要从正在运行的群集中删除一个实例,以便缩减群集规模或执行系统更新。今年早些时候,我们添加了一组生命周期挂钩,以便您可以更好地管理实例的状态。请阅读博客文章如何在 Amazon ECS 中自动实现容器实例耗尽,以了解如何使用生命周期挂钩和 Lambda 函数来自动执行耗尽实例的现有工作,同时防止为其安排新工作的过程。

CI/CD 管道与代码* – 容器可简化软件部署,是 CI/CD (持续集成/持续部署) 管道的理想目标。使用 AWS CodePipeline、AWS CodeBuild、Amazon ECR 和 AWS CloudFormation 对 Amazon ECS 进行持续部署一文显示了如何使用多个 AWS 服务构建和运行 CI/CD 管道。

CloudWatch 日志集成 – 此次发布使您能够配置运行任务的容器,以将日志信息发送到 CloudWatch 日志进行集中存储和分析。您只需安装 Amazon ECS 容器代理并启用 awslogs 日志驱动程序即可。

CloudWatch 事件 – 当任务或容器实例的状态更改时,ECS 会生成 CloudWatch 事件。这些事件允许您使用 Lambda 函数监控群集的状态。要了解如何捕获事件并将其存储在 Elasticsearch 群集中,请阅读使用 Amazon ECS 事件流监控群集状态

任务放置策略 – 此次发布使您能够精细控制群集中容器实例上的任务放置。它允许您构建包括群集约束、自定义约束 (位置、实例类型、AMI 和属性)、放置策略 (分散或装填) 的策略,并在无需编写任何代码的情况下使用它们。请阅读 Amazon ECS 任务放置策略简介,了解如何做到这一点!

EC2 Container Service 实际运用

我们的许多客户都使用 Amazon ECS 在生产环境中运行他们的微服务应用程序,这些客户既包括大型企业,也包括炙手可热的初创公司,并且身处各行各业,例如金融服务、酒店和消费电子等行业。Capital One、Expedia、Okta、Riot Games 和 Viacom 等公司都依靠 Amazon ECS。

Mapbox 是用于设计和发布自定义地图的平台。该公司使用 ECS 为整个批处理架构提供技术支持,以收集和处理他们用来为其地图提供支持的每天超过 1 亿英里的传感器数据。他们还使用竞价型实例在 ECS 上优化其批处理架构。Mapbox 平台为 5,000 多个应用程序提供支持,每个月覆盖超过 2 亿的用户。它的后端运行在 ECS 上,这使它每天能够处理超过 13 亿个请求。要了解有关他们最近迁移到 ECS 的事宜的更多信息,请阅读他们最近的博客文章,我们已切换到 Amazon ECS,接下来发生的事情让人难以置信旅游公司 Expedia 使用微服务架构设计了他们的后端。随着 Docker 的普及,他们决定采用 Docker 来实现更快的部署和环境可移植性。他们选择使用 ECS 来安排其所有容器,因为它与 AWS 平台完美集成,从 ALB 到 IAM 角色再到 VPC 集成,一应俱全。这使得 ECS 能够非常容易地与他们现有的 AWS 基础设施配合使用。ECS 确实减少了部署和运行容器化应用程序的繁重工作。Expedia 在 ECS 中的 AWS 上运行 75% 的应用程序,这使它每小时能够处理 40 亿个请求。请阅读 Kuldeep Chowhan 的博客文章,Expedia 如何使用 Amazon ECS 在生产环境中运行数以百计的应用程序,以了解更多信息。

Realtor.com 为购房者和卖房者提供当前待售物业的综合数据库。通过迁移到 AWS 和 ECS,他们的业务得以迅速增长,现在每个月的唯一用户数高达 5000 万个,高峰时段每秒可处理 25 万个请求。ECS 帮助他们更快地部署代码,同时提高其云基础设施的利用率。请阅读 Realtor.com 案例研究,以了解有关他们如何使用 ECS、Kinesis 和其他 AWS 服务的更多信息。

Instacart 介绍了他们如何使用 ECS 来为他们的当日杂货配送服务提供支持:Capital One 介绍了他们如何使用 ECS 实现其运营和基础设施管理自动化:Code

Clever 开发人员使用 ECS 作为他们自己工作的基础。例如:

Rack 是一个开源 PaaS (平台即服务)。它专注于基础设施自动化,在隔离的 VPC 中运行,并使用单租户构建服务来实现安全性。

Empire 也是一个开源 PaaS。它提供一个类似 Heroku 的工作流程,针对的是中小型初创公司,重点是微服务。

Cloud Container Cluster Visualizer (c3vis) 有助于直观地显示 ECS 群集中的资源利用率:

请保持关注

ECS 还有许多新功能正在准备阶段,敬请保持关注!

-Jeff

(原文链接:/cn/https://aws.amazon.com/blogs/aws/amazon-ec2-container-service-launch-recap-customer-stories-and-code/