写点什么

Service Broker 在 AWS 中国区的落地

  • 2019 年 11 月 27 日
  • 本文字数:8598 字

    阅读完需:约 28 分钟

Service Broker 在 AWS 中国区的落地

红帽OpenShift是全球领先的企业级 Kubernetes 容器平台。目前 OpenShift 拥有大量客户(全球超过 1000 个),跨越行业垂直市场,并部署大量部署在私有云和公有云上。OpenShift 与 AWS 的集成是所有云平台集成最好的。



图 1 AWS 和 OpenShift 的集成


OpenShift 运行在 AWS 上,除了支持动态创建 EBS 卷、调用 ELB 等基础功能外,还可以通过 Service Broker 直接创建 AWS 原生服务,并提供给 OpenShift 中的容器化应用使用。


本文就针对 OpenShift 3.11 在 AWS 中国区如何使用 Service Broker 进行详细说明。


1. Service Broker 简介

1.1 AWS Service Broker 介绍

AWS ServiceBroker 是一个开源项目,它可以将 AWS 上的原生服务公开给应用平台,并提供与运行中的应用程序无缝集成,OpenShift 支持通过这种方式为应用提供集成 AWS 服务的能力。


AWS ServiceBroker 是基于 Open Service Broker API 实现的。在 OpenShift 平台上,使用 Kubernetes Service Catalog 作为中间层,允许用户使用资源文件和 OpenShift 界面部署服务。如下图所示:



图 2 OpenShift 中的 AWS Service


目前 AWS ServiceBroker 支持一部分 AWS 服务,包括 Amazon 关系数据库服务 (Amazon RDS)、Amazon EMR、Amazon DynamoDB、Amazon S3 和 Amazon 简单队列服务 (Amazon SQS)等,有关完整列表,请参阅 AWS ServiceBroker 社区https://github.com/awslabs/aws-servicebroker/tree/master/templates。这些 ServiceBroker 包括管理基础架构、资源和构建逻辑的 CloudFormation 模板。这些模板包含一些规范和可自定义的参数,这些参数可以为生产、测试和开发环境提供了最佳实践。


应用程序可以通过一组值 (如访问地址和认证信息) 来使用创建好的 AWS 服务,这些值被保存在 Secret 对象中,通过执行绑定的过程挂载到应用程序中。这使得开发人员在不了解或深入了解基础资源的情况下创建使用 AWS 服务,并与 OpenShift 上应用交互。大致的流程图如下图所示:



图 3 AWS Service Broker 的工作流程


从图中可以看出大致的流程:


  • 在 OpenShift 中,开发人员通过 Service Catalog 选择想要的 AWS 服务,填写必要的参数后点击创建。

  • OpenShift 中的 aws-servicebroker 接受请求,向 AWS 发起创建 CloudFormation Stack,CloudFormation 把需要的 AWS 服务创建完成后,将一些必要的信息返回,如连接地址、认证信息等。

  • 在 OpenShift 中,创建 Secret 对象保存传回的 AWS 服务信息。

  • 开发人员在 OpenShift 的 Provisioned Services 界面,完成 AWS 服务和 OpenShift 应用的绑定,应用中完成 AWS 服务消费。


1.2 AWS Service Broker 运行规划

AWS ServiceBroker 运行在 OpenShift 上,运行方式规划如下:


  • AWS ServiceBroker 以独立的容器运行在单独的 OpenShift namespace 中,例如 aws-sb。

  • AWS ServiceBroker 需要使用一个 IAM Role 或者 AK/SK 来操作 AWS 资源,优先推荐使用 IAM Role。IAM Role 需要具备创建 Service Broker 支持的 AWS 服务的权限。

  • AWS ServiceBroker 创建的服务运行在独立账户下的 VPC 中,VPC 需要提前创建。

  • AWS ServiceBroker 所需要的模版文件存放在宁夏区的 S3 桶中。


2.AWS Service Broker 的安装

AWS ServiceBroker 的安装也比较简单,使用官方提供的模版在 aws-sb 项目中启动 AWS ServiceBroker 容器即可。在中国区安装需要同步模版到自定义的 S3 桶中。


安装所需要的文件存放在 Github 中,在安装之前同步仓库。


Bash


# git clone https://github.com/awslabs/aws-servicebroker.git
复制代码


2.1 创建 DynamoDB

AWS ServiceBroker 使用 DynamoDB 记录从 S3 桶中发现模版的元数据。可以通过多种方式创建所需要的 DynamoDB 的表。这里我们使用社区提供的 CloudFormation 模版完成创建,因为模版无法直接在中国区使用,需要进行少量的修改。修改后的模版文件内容如下。


Bash


# cd setup
# vi prerequisites.yaml
复制代码


YAML


AWSTemplateFormatVersion: "2010-09-09"Description: >  Creates the prerequisites for the AWS Service Broker -  https://github.com/awslabs/aws-servicebroker/blob/master/docs/install_prereqs.mdResources:  BrokerTable:    Type: "AWS::DynamoDB::Table"    Properties:      AttributeDefinitions:      - AttributeName: id        AttributeType: S      - AttributeName: userid        AttributeType: S      - AttributeName: type        AttributeType: S      KeySchema:      - AttributeName: id        KeyType: HASH      - AttributeName: userid        KeyType: RANGE      ProvisionedThroughput:        ReadCapacityUnits: 5        WriteCapacityUnits: 5      TableName: "awssb"      GlobalSecondaryIndexes:      - IndexName: "type-userid-index"        KeySchema:        - AttributeName: type          KeyType: HASH        - AttributeName: userid          KeyType: RANGE        Projection:          ProjectionType: INCLUDE          NonKeyAttributes: [ id, userid, type, locked ]        ProvisionedThroughput:          ReadCapacityUnits: 5          WriteCapacityUnits: 5  BrokerUser:    Type: "AWS::IAM::User"    Properties:      Policies:      - PolicyName: AwsServiceBrokerPolicy        PolicyDocument:          Version: "2012-10-17"          Statement:          - Action: [ "s3:GetObject", "s3:ListBucket" ]            Resource: [ "arn:aws-cn:s3:::myawsservicebroker/templates/*", "arn:aws-cn:s3:::myawsservicebroker" ]            Effect: "Allow"          - Action: [ "dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:DeleteItem" ]            Resource: !Sub "arn:aws-cn:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BrokerTable}"            Effect: "Allow"          - Action: [ "ssm:GetParameter", "ssm:GetParameters" ]            Resource:            - !Sub "arn:aws-cn:ssm:${AWS::Region}:${AWS::AccountId}:parameter/asb-*"            - !Sub "arn:aws-cn:ssm:${AWS::Region}:${AWS::AccountId}:parameter/Asb*"            Effect: "Allow"      - PolicyName: AwsServiceBrokerProvisioningPolicy        PolicyDocument:          Version: "2012-10-17"          Statement:          - Action: [ "ssm:PutParameter", "ssm:GetParameter", "ssm:GetParameters" ]            Resource:            - !Sub "arn:aws-cn:ssm:${AWS::Region}:${AWS::AccountId}:parameter/asb-*"            - !Sub "arn:aws-cn:ssm:${AWS::Region}:${AWS::AccountId}:parameter/Asb*"            Effect: "Allow"          - Action: "s3:GetObject"            Resource: "arn:aws-cn:s3:::myawsservicebroker/templates/*"            Effect: "Allow"          - Action:            - "cloudformation:CreateStack"            - "cloudformation:DeleteStack"            - "cloudformation:DescribeStacks"            - "cloudformation:DescribeStackEvents"            - "cloudformation:UpdateStack"            - "cloudformation:CancelUpdateStack"            Resource: !Sub "arn:aws-cn:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/aws-service-broker-*/*"            Effect: "Allow"          - Action: [ "athena:*", "dynamodb:*", "kms:*", "elasticache:*", "elasticmapreduce:*", "kinesis:*", "rds:*",                      "redshift:*", "route53:*", "s3:*", "sns:*", "sns:*", "sqs:*", "ec2:*", "iam:*", "lambda:*" ]            Resource: "*"            Effect: "Allow"Outputs:  IAMUser:    Value: !Ref BrokerUser
复制代码


上述 CloudFormation 文件中主要会创建两个资源对象 DynamoDB 和 IAM user,以及赋予 IAM 一些 Policy。


重要参数及修改参数说明:


  • TableName:创建 DynamoDB 的名称,默认为 awssb。

  • BrokerUser:用于创建名为 BrokerUser 的 User,可以用于安装 servicebroker 时使用。强烈建议使用 IAM Role,并赋予 BrokerUser 所拥有的权限,而不是使用 AK/SK。

  • Resource:Policy 中的所有 Resource 字段必须修改 arn:aws:xxx 为 arn:aws-cn:xxx。

  • 对于 S3 的权限需要修改为自定义存放模版的 Bucket,该 Bucket 为中国区创建的 S3 桶,如示例中的 myawsservicebroker。


如:


Resource: [ “arn:aws-cn:s3:::myawsservicebroker/templates/*”, “arn:aws-cn:s3:::myawsservicebroker” ]


Resource: “arn:aws-cn:s3:::myawsservicebroker/templates/*”


将 prerequisites.yaml 中相应的参数修改完成后,在 AWS 控制台创建 CloudFormation Stack。Stack 创建完成后,会自动创建 Dynamodb 的 Table,默认名称为 awssb。同时会创建一个用于 AWS ServiceBroker 的 IAM User,并且设置合适的权限。但是默认不会为创建 IAM 用户生成 AK 和 SK,我们强烈建议创建独立的 IAM Role 实现认证。


如果使用命令行创建 Dynamodb 和 IAM Role,请参见 GitHub 说明。


2.2 创建保存模版的 S3 bucket

社区提供的模版在存放在 AWS Global 区的 S3 桶 awsservicebroker 中,在中国区安装需要创建一个自定义的 S3 bucket 来保存模版,本文档 Bucket 示例为 myawsservicebroker,需要在中国区 AWS Console 或者命令行预先创建。S3 桶不要开启 Public access。


然后同步 us-west-2 区域的 S3 bucket awsservicebroker。


Bash


# export AWS_ACCESS_KEY_ID=xxxxx
# export AWS_SECRET_ACCESS_KEY=xxxxxxx
# export AWS_DEFAULT_REGION=us-east-2
# mkdir awsservicebroker
# aws s3 sync s3://awsservicebroker ./awsservicebroker
复制代码


同步 awsservicebroker 内容到中国区创建的 s3 桶 myawsservicebroker 中


Bash


# export AWS_DEFAULT_REGION=cn-northwest-1
# export AWS_ACCESS_KEY_ID=xxxxxx
# export AWS_SECRET_ACCESS_KEY=xxxxx
# cd awsservicebroker
# aws s3 sync ./ s3://myawsservicebroker/
复制代码


2.3 OpenShift 部署 ServiceCatalog

AWS ServiceBroker 的使用需要依赖于 OpenShift 的 ServiceCatalog 和 template-service-broker,需要执行如下步骤完成部署。


在安装 OpenShift 集群的 Ansible Server 上执行。修改安装 OpenShift 的 inventory 文件,添加如下参数:


openshift_enable_service_catalog=true


template_service_broker_install=true


ansible_service_broker_install=false


service_catalog 和 template_service_broker 必须安装,ansible_service_broker_install 可以选择不安装。


修改完成之后,执行如下命令安装:


Bash


# cd /usr/share/ansible/openshift-ansible/
# ansible-playbook -vv playbooks/openshift-service-catalog/config.yml
复制代码


如果使用离线安装,则保证 servicecatalog 和 template-service-broker 需要的镜像 registry.access.redhat.com/openshift3/ose-service-catalog:v<ocp_version>和 registry.access.redhat.com/openshift3/ose-template-service-broker: v<ocp_version>在私有镜像仓库中存在。


2.4 部署 AWS ServiceBroker

在 OpenShift 任意一个 Master 节点操作。


Bash


# mkdir awssb
# cd awssb
复制代码


下载安装所需要的文件,目前发布的最新版本为 v1.0.1。


Bash


# wget https://raw.githubusercontent.com/awslabs/aws-servicebroker/release-v1.0.1/packaging/openshift/deploy.sh
# wget https://raw.githubusercontent.com/awslabs/aws-servicebroker/release-v1.0.1/packaging/openshift/aws-servicebroker.yaml
# wget https://raw.githubusercontent.com/awslabs/aws-servicebroker/release-v1.0.1/packaging/openshift/parameters.env
# chmod +x deploy.sh
复制代码


修改参数文件:


Bash


# vi parameters.env
TARGETACCOUNTID=xxx
TARGETROLENAME=xxx
VPCID=vpc-xxx
REGION=cn-northwest-1
IMAGE=awsservicebroker/aws-servicebroker:1.0.1
IMAGEPULLPOLICY=IfNotPresent
S3BUCKET=myawsservicebroker
S3KEY=templates/latest
S3REGION=cn-northwest-1
TABLENAME=awssb
VERBOSITY=10
BROKERID=awsservicebroker
PRESCRIBE_OVERRIDES=true
复制代码


重要参数说明:


  • TARGETACCOUNTID:必填项,部署 awssb 的用户的 accountID,为 12 位数字。

  • TARGETROLENAME:可选项,强烈建议使用 IAMRole 实现认证,不要使用 AK/SK。

  • VPCID:必填项,选择部署 AWS 服务所在的 VPC。

  • REGION:必填项,选择部署 AWS 服务所在的区域。

  • IMAGE:必填项,选择 aws-service-broker 使用的镜像,如果是私有仓库,则需要修改镜像地址,默认使用 docker.io。

  • IMAGEPULLPOLICY:必填项,选择拉取 aws-servicebroker 镜像的策略。

  • S3BUCKET:中国区必填项,如果在国外,则可以直接使用默认值,在中国需要填写自定义的 S3 Bucket。

  • S3KEY:默认值即可,用于过滤检测已经发布的的 ServiceBroker 模版。

  • S3REGION:如果使用自定义的 S3 Bucket,则必须匹配自定义 Bucket 所在的 REGION。

  • TABLENAME:必填项,Dynamodb 的 table 名称,必须与前面创建的 table 名一致。

  • VERBOSITY:可选项,ServiceBroker 容器的日志级别

  • BROKERID:必填项,设定创建的 Broker 的名称。也就是在同一个集群中可以创建多个 ServiceBroker 实例。

  • PRESCRIBE_OVERRIDES:可选项,是否支持参数覆盖,默认为 true。


参数文件修改完成后,以 IAM Role 实现认证,则执行如下部署脚本:


Bash


# ./deploy.sh
复制代码


部署脚本会在 OpenShift 创建项目 aws-sb,并实例化 OpenShift 模版 aws-servicebroker.yaml,并通过环境变量引用参数。


2.5 部署后检测

在任意 Master 节点执行操作。


Bash


# oc project aws-sb
# oc get pods | grep aws-servicebroker
# oc logs <aws-servicebroker-pod-name>
复制代码


检查 log 中没有任何报错,并且有发现 service broker 的日志,如下所示:


……


I0718 04:42:01.033560 1 util.go:91] “awsservicebroker_all_all_all_VpcId”=”vpc-0859afa78994bff49”


I0718 04:42:01.033566 1 util.go:91] “awsservicebroker_all_all_all_target_account_id”=”180996712413”


I0718 04:42:01.033595 1 awsbroker.go:174] Listing objects bucket: myawsservicebroker region: cn-northwest-1 prefix: templates/latest


I0718 04:42:01.118989 1 awsbroker.go:193] Found 18 objects


I0718 04:42:01.119134 1 awsbroker.go:168] Updating listings cache with


登录 OpenShift WebConsole 查看是否已经有部署 AWS 服务的模版,如下图所示。



图 4 OpenShift Console 中的 AWS 服务模版


在 AWS 的 DynamoDB 中可以看到发现的 ServiceBroker 元数据信息,如下图所示:



图 5 DynamoDB 中的 ServiceBroker 列表


这些模版虽然已经在 DynamoDB 和 OpenShift 中展现出来,但是在 OpenShift 中依然无法完成创建 AWS 服务。主要原因在与默认官方提供的 Broker 模版无法在国内创建。


3. AWS ServiceBroker 自定义模版

默认社区提供的 CloudFromation 模版无法直接在中国区使用,所有的模版需要进行修改才能使用。本章节我们就说明修改模版的方法。


OpenShift 界面显示的 AWS 服务的模版是通过 aws-servicebroker 在 S3 中发现,并更新信息到 DynamoDB 中。如果要删除某个模版,需要同时在 S3 和 dynamodb 中删除对应的条目,识别的 ServiceBroker 模版在定义的 S3 桶 myawsservicebroker 中的 template/latest 中,修改模版就是修改这个目录下的 yaml 文件。


S3 桶 template/latest 下存放的是所有的 ServiceBroker 模版,只是在原本的 CloudFormation 模版中添加了 ServiceBroker 相关的元数据,以 S3 为例的 Metadata 字段。


Bash


# cat s3-main.yaml
复制代码


YAML


AWSTemplateFormatVersion: 2010-09-09Description: 'AWS Service Broker - Amazon S3 (qs-1nt0fs937)'Metadata:  'AWS::ServiceBroker::Specification':    Version: 1.0    Tags:      - AWS      - S3      - Object Storage    Name: s3    DisplayName: Amazon S3    LongDescription: Amazon Simple Storage Service (Amazon S3) is storage for the      Internet. You can use Amazon S3 to store and retrieve any amount of data at      any time, from anywhere on the web. You can accomplish these tasks using the      simple and intuitive web interface of the AWS Management Console.    ImageUrl: https://s3.amazonaws.com/thp-aws-icons-dev/Storage_AmazonS3_LARGE.png    DocumentationUrl: https://aws.amazon.com/documentation/s3/'    ProviderDisplayName: "Amazon Web Services"    Bindings:      IAM:        AddKeypair: True        Policies:          - PolicyDocument: {            "Version": "2012-10-17",            "Statement": [            {              "Action": [                "s3:AbortMultipartUpload",                "s3:DeleteObject",                "s3:GetObject",                "s3:GetObjectAcl",                "s3:GetObjectTagging",                "s3:GetObjectTorrent",                "s3:GetObjectVersion",                "s3:GetObjectVersionAcl",                "s3:GetObjectVersionTagging",                "s3:GetObjectVersionTorrent",                "s3:ListBucketMultipartUploads",                "s3:ListMultipartUploadParts",                "s3:PutObject",                "s3:PutObjectAcl",                "s3:PutObjectTagging"              ],              "Effect": "Allow",              "Resource": !If [ RetainBucket, !Sub "${S3BucketRetain.Arn}/*", !Sub "${S3BucketDelete.Arn}/*" ]            },            {              "Action": [                "s3:ListBucket"              ],              "Resource": !If [ RetainBucket, !GetAtt S3BucketRetain.Arn, !GetAtt S3BucketDelete.Arn ],              "Effect": "Allow"            }            ]          }    ServicePlans:      production:        DisplayName: "Production"        Description: 'S3 Bucket pre-configured with production best practices'        LongDescription: "Amazon Simple Storage Service (Amazon S3) is storage for the Internet. You can use Amazon S3 to store and retrieve any amount of data at any time, from anywhere on the web. You can accomplish these tasks using the simple and intuitive web interface of the AWS Management Console."        Cost: "https://aws.amazon.com/s3/pricing/"        ParameterValues:          BucketName: "Auto"          LoggingPrefix: S3AccessLogs          # TODO: add glacier lifecycle for previous versions          EnableGlacierLifeCycle: "False"          GlacierLifeCycleTransitionInDays: "30"          LifeCyclePrefix: Archive          EnableVersioning: "True"          BucketAccessControl: Private          EnableLogging: "True"          PreventDeletion: "True"      custom:        DisplayName: "Custom"        Description: 'S3 Bucket pre-configured with custom configuration'        LongDescription: "Amazon Simple Storage Service (Amazon S3) is storage for the Internet. You can use Amazon S3 to store and retrieve any amount of data at any time, from anywhere on the web. You can accomplish these tasks using the simple and intuitive web interface of the AWS Management Console."        Cost: "https://aws.amazon.com/s3/pricing/"  'AWS::CloudFormation::Interface':    ParameterGroups:  ……CloudFormation模版的内容 ……
复制代码


如果是修改现有的社区模版以适配中国区使用的话,则直接更新现有的模版内容,实现在中国区创建。


如果是新建 ServiceBroker 模版,则需要在测试通过的 Cloudformation 模版添加 ServcieBroker 相关的元数据,然后上传到 S3 桶中。元数据生成可以使用社区提供的工具https://github.com/ndrest-amzn/ServiceBrokerMetaGen生成。


更新的模版需要稍等几分钟,会更新 DynamoDB 中元数据,然后在 OpenShift 界面创建服务测试更新的模版。


4. 结语

本文介绍了在中国区的 OpenShift 中部署 AWS Service Broker,赋予容器平台新的魔法,真正意义上解决了开发人员自服务方式创建 AWS 原生服务,大大加快了业务开发需要基础环境的创建周期。


如果您需要关于容器的专业的服务和指导,欢迎联系 AWS ProServe 专业服务团队。


作者介绍:


!



### [](https://amazonaws-china.com/cn/blogs/china/tag/%E9%83%AD%E8%B7%83%E5%86%9B/)
亚马逊 AWS 专业服务团队云架构咨询顾问。擅长PaaS 建设运维、 DevOps 以及微服务改造迁移等有丰富的经验。负责企业级客户的云架构设计和优化、云上自动化运维、容器化平台设计咨询等,对云原生技术有深入的研究和热情。
复制代码


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/service-broker-landing-in-aws-china/


2019 年 11 月 27 日 08:00393

评论

发布
暂无评论
发现更多内容

filter、interceptor、aspect不知如何选择,移动应用开发案例教程

android 程序员 移动开发

Flutter Android 端 FlutterInjector 及依赖流程源码分析

android 程序员 移动开发

Flutter Candies 一桶天下,kotlin编程软件

android 程序员 移动开发

Flutter 中的 JSON 解析(1),androidsdk环境配置

android 程序员 移动开发

Flutter中http请求抓包解决方案,揭秘今年Android春招面试必问问题有哪些

android 程序员 移动开发

Flutter之撸一个漂亮的登录界面的总结,Android性能优化之启动优化实战篇

android 程序员 移动开发

Flutter 仿掘金微信图片滑动退出页面效果,写给程序员的Flutter详细教程

android 程序员 移动开发

Flutter 入门与实战(十三),安卓framework层开发

android 程序员 移动开发

web技术分享| 一人一天一个可移植的实时聊天系统

anyRTC开发者

大前端 Web 音视频 实时通信 实时聊天

如何打造实时性的弹窗?

神策技术社区

UI sdk Android;

EventBus核心原理其实保存这三张图就可以弄懂了,收藏一下

android 程序员 移动开发

Flutter _ 日志还能这么打印,太秀了!,android移动应用基础教程

android 程序员 移动开发

Flutter-系列(四)基础UI实践,从外包月薪5K到阿里月薪15K

android 程序员 移动开发

Flutter之FutureBuilder的学习和使用,Android2021面试题

android 程序员 移动开发

架构实战营 模块三作业

felix

架构实战营

DateUtils(一个日期工具类),androidauto百度地图

android 程序员 移动开发

DialogFragment探索与实现,音视频编解码技术

android 程序员 移动开发

Flutter 与 Compose怎么选?小孩子才做选择,kotlinwindows桌面开发

android 程序员 移动开发

Flutter 官方尝试放只“鸽子”来简化Native插件开发,复习指南

android 程序员 移动开发

Flutter 跨平台框架应用实战-2019极光开发者大会,音视频开发面试

android 程序员 移动开发

Flutter RichText支持图片显示和自定义图片效果,经典Android开发教程

android 程序员 移动开发

华云大咖说 | 安超DCM运维场景解决方案

华云数据

Flutter 仿掘金推特点赞按钮,kotlin中文版

android 程序员 移动开发

下一代信息技术论坛云操作系统介绍

阿里云情报局

架构 操作系统

Flutter 入门与实战(九),android软件开发前景

android 程序员 移动开发

Flutter之全埋点思考与实现,精心整理

android 程序员 移动开发

Dart 层如何 兼容 Android 和iOS平台特性 (1),Android开发面试技巧

android 程序员 移动开发

Flutter Android 工程结构及应用层编译源码深入分析,Android面试题及答案2020

android 程序员 移动开发

Flutter 中的 JSON 解析,事件分发机制Android

android 程序员 移动开发

FART:ART环境下基于主动调用的自动化脱壳方案,androidndk开发教程

android 程序员 移动开发

Flutter 如何发布安卓应用?,flutter文档发布组件

android 程序员 移动开发

Service Broker 在 AWS 中国区的落地_文化 & 方法_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章