亚马逊AWS官方博客

高盛如何通过 AWS PrivateLink 构建起接入 Amazon MSK 集群的跨账户连接体系

Original URL: https://aws.amazon.com/cn/blogs/big-data/how-goldman-sachs-builds-cross-account-connectivity-to-their-amazon-msk-clusters-with-aws-privatelink/

 

本篇客座文章介绍如何使用AWS PrivateLink在您的AWS账户或Amazon Virtual Private Cloud(Amazon VPC)边界上访问Amazon Managed Streaming for Apache Kafka集群。此外,文章还探讨了高盛交易银行团队如何选择跨账户访问模式,其中做出的权衡与考量,以及如何满足Amazon MSK的安全要求。本文以高盛的实现用例为基础,向大家呈现实现Amazon MSK环境时可以借鉴的通行指导建议。

概述

Amazon MSK是一项全托管服务,可帮助用户轻松构建并运行由Apache Kafka处理流数据的应用程序。在创建MSK集群时,集群内的资源可供处于同一Amazon VPC的各参与方使用。以此为基础,我们可以在VPC的特定子网当中启动集群,将其与安全组关联起来,并通过弹性网络接口(ENI)附加由VPC地址空间提供的IP地址。客户端与集群之间的网络流量皆保持在AWS网络之内,集群默认不接受任何来自互联网的访问请求。

大家可能需要允许客户端访问同一或者不同AWS账户内位于不同VPC中的MSK集群。在这方面,VPC提供对等或传输网关等选项,可以使两个VPC中的资源相互通信,使用感受类似于位于同一网络当中。关于访问选项的更多信息,请参阅访问Amazon MSK集群

除了上述选项之外,本文将重点介绍另一种AWS PrivateLink使用方法。在深入讨论实际模式之前,我们先来简要介绍如何将AWS PrivateLink作为理想的跨账户与跨VPC访问策略加以使用。

如下图所示,VPC对等网络是两个VPC之间的双向网络连接,用户可以使用专用IPv4地址或者IPv6地址在它们之间实现通信路由。

VPC对等网络更适用于VPC对等各方之间高度信任的运行环境。这是因为在建立起VPC对等连接之后,两个VPC即可彼此进行广泛访问,且两个VPC内的资源都可以启动通信连接。所以,我们需要通过安全组机制建立起细粒度网络访问控制,以确保对等VPC之间只能面向对方访问需要访问的特定资源。

我们只能在CIDR不重叠的VPC之间建立起VPC对等连接。如果CIDR有所重叠(例如跨不同组织间的账户进行对等连接),建立VPC对等连接可能比较困难。

此外,如果需要规模化运行,大家可以建立起数百个Amazon VPC,并将单一Amazon VPC所能接纳的VPC对等连接数量上限设定为125个。大家也可以使用传输网关等网络hub工具;但需要注意的是,这类hub虽然具有极高的可扩展性,足以支持成千上万个Amazon VPC,但其与常规的VPC对等连接一样要求保证双向信任加非重叠CIDR。

相比之下,AWS PrivateLink会在默认情况下对VPC中的特定资源(注意,不是所有资源)提供细粒度网络访问控制,因此更适用于低信任度环境,能够显著降低风险面。下图所示为服务提供程序VPC,相关服务运行在Amazon Elastic Compute Cloud(Amazon EC2)实例之上,并位于网络负载均衡器(NLB)之后。服务提供程序在VPC中创建指向该NLB的VPC端点服务配置。大家可以与其他Amazon VPC(即服务使用程序VPC)共享此端点服务,并由后者使用AWS PrivateLink支持的接口VPC端点接入该服务。服务使用程序将利用此接口端点直接接入最终应用程序或服务。

AWS PrivateLink能够保证指向一组特定网络资源的连接具备单向性——即连接只能从服务使用程序VPC流入服务提供程序VPC,而不可反向传输。除接口端点能够支持的网络资源之外,服务提供程序VPC中的其他一切其他资源都不会公开。AWS PrivateLink还允许VPC CIDR范围重叠并提供相对更好的扩展能力,以保证成千上万Amazon VPC能够彼此消费对方提供的服务。

可以看到,VPC对等连接与AWS PrivateLink属于适用于不同信任模型与用例的两种差异化连接选项。

交易银行的微账户策略

AWS账户代表着一种强大的隔离边界,能够有效控制由部署错误或配置错误引发的问题,并将“爆炸半径”控制在一定范围以内。之所以能够实现如此强大的隔离性,是因为我们需要主动配置跨越账户边界的数据流。高盛交易银行(TxB)设计出一项策略,能够将每个系统转移至其对应的AWS账户,这些账户被称为TxB微账户。通过这种策略,高盛交易银行能够尽可能降低错误配置给多个系统造成影响的几率。关于TxB微账户的更多详细信息,请参阅YouTube视频AWS re:Invent 2018: 在AWS上以规模化方式实现策略验证与强制执行

为了进一步巩固TxB微账户细分带来的优势,高盛方面还选择AWS PrivateLink实现系统中的跨账户与跨VPC访问。AWS PrivateLink允许TxB服务提供程序将其服务以终端服务的形式公开,并配合白名单来明确配置其他哪些AWS账户可以针对这些服务创建接口端点。如此一来,每一项服务都将拥有对应的细粒度访问模式控制能力。端点服务定义只允许访问请求接入NLB资源,帮助运营人员更轻松地理解整体访问范围。而从服务使用程序到服务提供程序的单向连接,则可保证所有连接都基于点对点形式接受控制。此外,AWS PrivateLink还允许VPC的CIDR地址块在不同TxB微账户之间重叠,这相当于将TxB指定为默认设置中的一部分,保证后续随着业务增长,成千上万TxB微账户VPC仍能根据运行情况在必要时使用每一种服务。

使用AWS PrivateLink的MSK代理访问模式

作为微账户策略中的一部分,高盛方面在自己的专用AWS账户中运行MSK集群,而与此集群交互的客户端则位于各自的微账户内。考虑到这种设置方式以及使用AWS PrivateLink进行跨账户连接的实际情况,高盛在实现跨账户代理访问方面认真考量了以下两种实现模式:

模式1:在各MSK代理之前使用唯一的专用接口端点

在此模式中,各个MSK代理在托管在MSK集群之上的TxB MSK账户中都拥有一个唯一的专用NLB。TxB MSK账户中包含各个NLB的端点服务,并与其他客户账户进行共享。客户账户包含与该端点服务相对应的接口端点。最后,与代理DNS名称相同的DNS条目指向相应的接口端点。下图所示,为部署在美国东部(俄亥俄州)区域内的这种架构模式。

流程概要

在设置完成之后,客户端将使用自己的预配置默认DNS名称通过自有账户与代理进行对话,具体过程如下所述:

  1. 客户端将代理DNS名称解析为客户端VPC内的接口端点IP地址。
  2. 客户端通过端口9094启动与接口端点IP的TCP连接。
  3. 使用AWS PrivateLink,此TCP连接将被路由至专用 NLB,以供各代理在TxB MSK账户内的同一端口上进行监听。
  4. NLB将该连接路由至在TCP端口9094上注册的同一代理IP处。

设置概要

本节中的整个设置过程,主要适用于美国东部(俄亥俄州)区域。如果要使用其他AWS区域,请进行对应修改。在TxB MSK账户中,完成以下操作步骤:

  1. 创建一个目标组,其中的目标类型为IP、协议TCP、端口9094,且位于MSK集群所在的同一VPC当中。
    • 使用IP地址将MSK代理注册为目标。
  2. 使用TCP端口9094的监听器创建一个NLB,并将其转发至上一步中创建完成的目标组。
    • 请保证NLB与其对应MSK代理处于同一可用区及子网当中。
  3. 为每一个需要接受及授予客户账户许可的NLB创建一个端点服务配置,借此使其能够建立指向此端点服务的连接。

在客户账户中,完成以下操作步骤:

  1. 在客户端所处的同一VPC当中创建一个接口端点(只接受TxB MSK账户内的连接请求)。
  2. 创建一个Route 53私有托管区,域名设置为kafka.us-east-2.amazonaws.com,而后将其与客户端所在的VPC关联起来。
  3. 创建与代理DNS名称相同的A-Alias别名记录,避免发生TLS握手失败,并将其指向相应代理的接口端点。

模式2:位于所有MSK代理之前,并配合单一共享接口端点

在第二种模式下,集群中的所有代理都将位于启用跨可用区负载均衡选项的同一NLB之前。通过修改各MSK代理中的advertised.listeners 配置以发布唯一端口,我们即可实现这样的架构设计。我们需要为每个代理创建一个唯一的NLB listener-target group对,再为所有代理设计一个唯一的共享listener-target group对。接下来,我们为该NLB创建一项端点服务配置,并将其与客户账户进行共享。在客户账户当中,我们创建一个与该端点服务相对应的接口端点。最后,我们为指向同一接口的各代理DNS名称创建对应的DNS条目。下图所示,为部署在美国东部(俄亥俄州)区域内的模式架构。

流程概要

在设置完成之后,客户端会使用自己预配置的默认DNS名称通过自己的账户与代理进行对话,具体过程如下:

  1. 客户端将代理DNS名称解析为客户端VPC内的接口端点IP地址。
  2. 客户端通过端口9094启动与接口端点IP的TCP连接。
  3. TxB MSK账户中的NLB监听器在端口9094上接收此连接。
  4. NLB监听器所对应的目标组将请求负载均衡至经过注册的某一代理中(Broker 1)。相应的,Broker 1将把其DNS名称与端口(9001)通告至客户端。
  5. 客户端再次将代理端点地址解析为扩音器端点IP,并通过TCP端口9001发起指向同一接口端点的连接。
  6. 此连接将被路由至NLB监听器上的TCP端口9001处。
  7. 根据配置,NLB监听器所对应的目标组会在TCP端口9094上接收流量,将该端口上的请求转发至唯一经过注册的目标,即Broker 1。

设置概要

本节中的整个设置过程,主要适用于美国东部(俄亥俄州)区域。如果要使用其他AWS区域,请进行对应修改。在TxB MSK账户中,完成以下操作步骤:

  1. 通过各个运行中的代理运行以下命令,用以修改MSK代理当前正在通告的端口。以下示例命令,为如何将特定代理b-1上的通告端口变更为9001。对于运行以下命令的各个代理,请大家对其中的bootstrap-serverentity-nameCLIENT_SECUREREPLICATION 以及 REPLICATION_SECURE部分做出对应调整。请注意,在修改REPLICATION 与 REPLICATION_SECURE的值时,必须在代理名称后附加-internal ;另外,请不要调整以下展示部分中的端口9093与9095。
    ./kafka-configs.sh \
    --bootstrap-server b-1.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9094 \
    --entity-type brokers \
    --entity-name 1 \
    --alter \
    --command-config kafka_2.12-2.2.1/bin/client.properties \
    --add-config advertised.listeners=[\
    CLIENT_SECURE://b-1.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9001,\
    REPLICATION://b-1-internal.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9093,\
    REPLICATION_SECURE://b-1-internal.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9095]
  2. 创建一个目标组,其目标类型为IP、协议TCP、端口9094,且与MSK集群位于同一VPC当中。上图将此目标组表示为B-ALL
    • 根据IP地址,将所有MSK代理以目标的形式注册至B-ALL
  3. 使用与B-ALL相同的属性创建专用于各代理(B1B2)的对应目标组。
    • 通过其IP地址向各个目标组注册对应的MSK代理。
  4. 如果需要,在其他代理上执行相同的操作步骤,并为每个代理创建与通告端口相对应的唯一listener-target group
  5. 创建一个与MSK代理处于同一子网中的有效NLB,并启用其中的跨可用区负载均衡选项。
    • 为各代理的通告端口(9001,9002)创建一个TCP监听器,负责指向之前创建的对应目标组(B1B2)的转发操作。
    • 创建一个特殊的TCP监听器9094,负责指向B-ALL 目标组的转发操作。
  6. 为该NLB创建一项端点服务配置,配置负责接受并授权必要的客户账户权限以创建指向此端点服务的连接。

在客户账户中,完成以下操作步骤:

  1. 在客户端所处的同一VPC当中创建一个接口端点(只接受TxB MSK账户内的连接请求)。
  2. 创建一个Route 53私有托管区,域名设置为kafka.us-east-2.amazonaws.com,而后将其与客户端所在的VPC关联起来。
  3. 在托管区内创建与代理DNS名称相同的A-Alias别名记录,避免发生TLS握手失败,并将其指向相应代理的接口端点。

本文所提到的这两种模式,都使用TLS在TCP端口9094上与MSK代理进行对话。如果大家的安全状况允许客户端与代理之间使用明文形式通信,则可直接配合TCP端口9092使用以上模式。

在这两种模式之下,一旦Amazon MSK检测到代理故障,则将使用新的代理替换故障代理,借此保证业务的正常运行。此外,新的MSK代理将沿用相同的IP地址以及Kafka属性(例如经过修改的advertised.listener配置等)。

Amazon MSK允许客户端在TCP端口9092、9094与2181上与服务进行通信。作为在模式2中修改的副产品,客户端会被自动要求与通告端口上的代理进行对话。如果客户端需要与Amazon MSK处于同一账户内才能访问各代理,大家应该在Amazon MSK账户内创建一个新的Route 53托管区,并使用与NLB DNS名称相同的代理DNS名称。该Route 53记录会设定对MSK代理DNS进行覆盖,并允许NLB放行所有指向该代理的流量。

交易银行的MSK代理访问模式

为了跨TxB微账户访问代理,高盛方面选择了模式1,其中各个代理都将向客户账户开放一个接口端点。TxB通过自动创建TxB MSK账户内的端点服务与客户账户内接口端点的形式,显著简化了整个通信流程,且无需任何手动干预。

在创建集群时,我们可以调用Amazon MSK API以检索引导代理配置,并将结果存储在客户账户的AWS Systems Manager参数当中,以便应用程序启动时进行快速检索。如此一来,客户就能轻松在其他账户当中随时使用Kafka代理的DNS名称。

TxB之所以选择模式1,一大关键因素在于其避免了对代理属性(例如通告端口)进行修改的繁琐操作。为了保证新的代理不会重复使用同一端口,模式2要求TxB跟踪目前哪个代理正在向哪个端口发布通告。这不仅会在新代理启动过程中带来不必要的通告端口修改与跟踪成本,同时还要求我们为代理创建相应的listener-target group对。通过选择模式1,TxB有效避免了这一额外开销。

但模式1也有自己的问题——当向集群中添加大量代理时,模式1需要创建更多的专用NLB及接口端点连接。TxB虽然通过自动化操作控制住这一管理开销,但这仍带来了额外的工程技术负担。

另外,模式1的使用成本也比模式2更高,这是因为集群中的每个代理都拥有一个专用NLB外加一个接口端点。对于单一代理而言,其保持端到端连接的基础架构每月成本为37.80美元。下面来看月度连接服务成本详情:

  • NLB运行成本——1 NLB x 0.0225美元 x 720小时/月 = 16.20美元/月
  • 跨越3个可用区的1 VPC端点——1 VPC x 3 ENI x 0.01美元 x 720小时/月 = 21.60美元/月

使用NLB容量以及处理AWS PrivateLink数据还会产生额外的费用。关于计费标准的更多详细信息,请参阅Elastic Load Balancing费率AWS PrivateLink费率

总而言之,模式1比较适合以下使用场景:

  • 希望最大程度减少由代理属性修改(例如通告端口)相关的管理开销。
  • 已经拥有自动化功能,可以在创建或撤销新代理时自动添加或删除对应的基础设施。
  • 主要强调简单且统一的部署体系,成本的影响因素相对较低。

交易银行对Amazon MSK的安全要求

TxB微账户提供强大的应用程序隔离边界,而使用模式1中的AWS PrivateLink进行MSK代理访问,能够严格控制各TxB微账户之间的连接流。TxB还进一步通过Amazon MSK中的其他基础设施与数据保护控制功能巩固安全水平。关于更多详细信息,请参阅 在Amazon Managed Streaming for Apache Kafka中实现安全保护

以下是TxB内部安全团队在使用Amazon MSK时所提出的核心安全原则:

  • 使用客户主密钥(CMK)进行静态加密——TxB使用Amazon MSK提供的托管静态加密产品。Amazon MSK与AWS Key Management Service(AWS KMS)相集成,能够提供透明的服务器端加密功能,保证始终对静态数据进行加密。在创建MSK集群时,大家可以指定AWS KMS负责生成用于加密静态数据的AWS KMS CMK密钥。关于更多详细信息,请参阅使用CMK与数据密钥
  • 传输数据加密——Amazon SK使用TLS 1.2对传输数据进行加密。TxB强制各客户端代理对往来于各MSK代理间的数据进行加密。
  • TLS客户端身份验证——Amazon MSK使用AWS Certificate Manager私有证书颁发机构(ACM PCA)进行客户端身份验证。ACM PCA既可由根证书颁发机构(CA)充当,也可以由从属CA充当。如果由根CA充当,则需要安装自签名证书。如果为从属CA,则可选择其父CA作为ACM PCA根、从属CA或者外部CA。其中外部CA可以是用户自己的证书颁发CA,其将在ACM PCA证书安装过程中成为证书链中的组成部分。TxB选择的就是最后一种方法,并通过由ACM PCA签名的证书对客户端请求进行授权。
  • 使用Kafka访问控制列表(ACL)——Amazon MSK允许用户使用客户端TLS证书的专有名称作为Kafka ACL的主体,对客户端请求进行授权。要启用Kafka ACL,大家需要首先指定由TLS进行客户端身份验证。TxB使用Kafka Admin API,通过部署在各消费方与生产方客户端实例上的证书与证书名称为各主题创建Kafka ACL。关于更多详细信息,请参阅Apache Kafka ACLs

结论

本文介绍了高盛集团旗下交易银行团队如何通过TxB微账户策略建立起应用程序隔离边界,又如何使用AWS PrivateLink对策略做出进一步补充。此外,本文还讨论了TxB团队如何跨各微账户建立起与MSK集群的网络连接,又如何通过Amazon MSK在满足核心安全要求的同时摆脱沉重的运营负担。在建立Amazon MSK环境时,大家不妨参考文章中介绍的构建方法。

 

本篇作者

Robert L. Cossin

纽约高盛集团副总裁。Rob于2004年加入高盛公司,曾参与公司现金及证券流量管理等诸多项目。最近,Rob出任交易银行团队技术架构师,专注于云技术支持与安全性方面的研究工作。

Harsha W. Sharma

纽约AWS分部解决方案架构师。Harsha于2016年加入AWS,负责与全球金融服务客户合作在AWS上设计并开发业务架构,致力于支持客户的云探索之旅。