为 Lambda 配置自托管式 Apache Kafka 事件源 - AWS Lambda

为 Lambda 配置自托管式 Apache Kafka 事件源

在为自托管式 Apache Kafka 集群创建事件源映射之前,必须确保集群及其所在的 VPC 配置正确。您还要确保 Lambda 函数的执行角色具有必要的 IAM 权限。

按照以下各节中的说明配置自托管式 Apache Kafka 集群和 Lambda 函数。要了解如何创建事件源映射,请参阅将 Kafka 集群添加为事件源

Kafka 集群身份验证

Lambda 支持多种方法来使用自行管理的 Apache Kafka 集群进行身份验证。请确保将 Kafka 集群配置为使用支持的下列身份验证方法之一:有关 Kafka 安全的更多信息,请参阅 Kafka 文档的安全部分。

VPC 访问

如果仅 VPC 中的 Kafka 用户访问 Kafka 代理,则必须为 Amazon Virtual Private Cloud (Amazon VPC) 访问配置 Kafka 事件源。

SASL/SCRAM 身份验证

Lambda 支持使用传输层安全性协议(TLS)加密 (SASL_SSL) 进行简单身份验证和安全层/加盐质疑应答身份验证机制(SASL/SCRAM)身份验证。Lambda 发送已加密凭据以使用集群进行身份验证。Lambda 不支持使用明文 (SASL_PLAINTEXT) 的 SASL/SCRAM。有关 SASL/SCRAM 身份验证的更多信息,请参阅 RFC 5802

Lambda 还支持 SASL/PLAIN 身份验证。由于此机制使用明文凭证,因此与服务器的连接必须使用 TLS 加密以确保凭证受到保护。

为了 SASL 身份验证,需要将登录凭证作为密钥存储在 AWS Secrets Manager 中。有关使用 Secrets Manager 的更多信息,请参阅 AWS Secrets Manager 用户指南中的教程:创建和检索密钥

重要

要使用 Secrets Manager 进行身份验证,密钥必须存储在 Lambda 函数所在的同一 AWS 区域中。

双向 TLS 身份验证

双向 TLS(mTLS)在客户端和服务器之间提供双向身份验证。客户端向服务器发送证书以便服务器验证客户端,而服务器又向客户端发送证书以便客户端验证服务器。

在自行托管的 Apache Kafka 中,Lambda 充当客户端。您可以配置客户端证书(作为 Secrets Manager 中的密钥),以使用 Kafka 代理对 Lambda 进行身份验证。客户端证书必须由服务器信任存储中的 CA 签名。

Kafka 集群向 Lambda 发送服务器证书,以便使用 Lambda 对 Kafka 代理进行身份验证。服务器证书可以是公有 CA 证书。也可以是私有 CA/自签名证书。公有 CA 证书必须由 Lambda 信任存储中的证书颁发机构(CA)签名。对于私有 CA /自签名证书,您可以配置服务器根 CA 证书(作为 Secrets Manager 中的密钥)。Lambda 使用根证书来验证 Kafka 代理。

有关 mTLS 的更多信息,请参阅为作为事件源的 Amazon MSK 引入双向 TLS 身份验证

配置客户端证书密钥

CLIENT_CERTIFICATE_TLS_AUTH 密钥需要证书字段和私有密钥字段。对于加密的私有密钥,密钥需要私有密钥密码。证书和私有密钥必须采用 PEM 格式。

注意

Lambda 支持 PBES1(而不是 PBES2)私有密钥加密算法。

证书字段必须包含证书列表,首先是客户端证书,然后是任何中间证书,最后是根证书。每个证书都必须按照以下结构在新行中启动:

-----BEGIN CERTIFICATE----- <certificate contents> -----END CERTIFICATE-----

Secrets Manager 支持最多包含 65536 字节的密钥,这为长证书链提供了充足的空间。

私有密钥必须采用 PKCS #8 格式,并具有以下结构:

-----BEGIN PRIVATE KEY----- <private key contents> -----END PRIVATE KEY-----

对于加密的私有密钥,请使用以下结构:

-----BEGIN ENCRYPTED PRIVATE KEY----- <private key contents> -----END ENCRYPTED PRIVATE KEY-----

以下示例显示使用加密私有密钥进行 mTLS 身份验证的密钥内容。对于加密的私有密钥,可以在密钥中包含私有密钥密码。

{"privateKeyPassword":"testpassword", "certificate":"-----BEGIN CERTIFICATE----- MIIE5DCCAsygAwIBAgIRAPJdwaFaNRrytHBto0j5BA0wDQYJKoZIhvcNAQELBQAw ... j0Lh4/+1HfgyE2KlmII36dg4IMzNjAFEBZiCRoPimO40s1cRqtFHXoal0QQbIlxk cmUuiAii9R0= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFgjCCA2qgAwIBAgIQdjNZd6uFf9hbNC5RdfmHrzANBgkqhkiG9w0BAQsFADBb ... rQoiowbbk5wXCheYSANQIfTZ6weQTgiCHCCbuuMKNVS95FkXm0vqVD/YpXKwA/no c8PH3PSoAaRwMMgOSA2ALJvbRz8mpg== -----END CERTIFICATE-----", "privateKey":"-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUiAFcK5hT/X7Kjmgp ... QrSekqF+kWzmB6nAfSzgO9IaoAaytLvNgGTckWeUkWn/V0Ck+LdGUXzAC4RxZnoQ zp2mwJn2NYB7AZ7+imp0azDZb+8YG2aUCiyqb6PnnA== -----END ENCRYPTED PRIVATE KEY-----" }

配置服务器根 CA 证书密钥

如果您的 Kafka 代理使用 TLS 加密(具有由私有 CA 签名的证书),则创建此密钥。您可以将 TLS 加密用于 VPC、SASL/SCRAM、SASL/PLAIN 或 mTLS 身份验证。

服务器根 CA 证书密钥需要一个字段,其中包含 PEM 格式的 Kafka 代理的根 CA 证书。以下示例显示密钥的结构。

{"certificate":"-----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dG... -----END CERTIFICATE-----" }

网络配置

为了让 Lambda 将 Kafka 集群用作事件源,需要访问集群所在的 Amazon VPC。建议为 Lambda 部署 AWS PrivateLink VPC 端点。为 Lambda 和 AWS Security Token Service(AWS STS)部署端点。如果代理使用身份验证,则还需要为 Secrets Manager 部署 VPC 端点。如果您配置了故障目标,则还要为该目标服务部署 VPC 端点。

或者,请确保与 Kafka 集群关联的 VPC 在每个公有子网中包含一个 NAT 网关。有关更多信息,请参阅 为连接到 VPC 的 Lambda 函数启用互联网访问权限

如果您使用 VPC 端点,则还必须将其配置为启用私有 DNS 名称

在为自行管理的 Apache Kafka 集群创建事件源映射时,Lambda 会检查集群 VPC 的子网和安全组是否已经存在弹性网络接口(ENI)。如果 Lambda 发现现有 ENI,则会尝试重用这些 ENI。否则,Lambda 会创建新的 ENI 来连接到事件源并调用函数。

注意

Lambda 函数始终在 Lambda 服务拥有的 Amazon VPC 中运行。这些 VPC 由服务自动维护,对客户不可见。您也可以将函数连接到 Amazon VPC。无论是哪种情况,函数的 VPC 配置都不会影响事件源映射。只有事件源 VPC 的配置才能决定 Lambda 连接到事件源的方式。

有关配置网络的更多信息,请参阅AWS计算博客上的使用 Apache Kafka 集群在 VPC 中设置 AWS Lambda

VPC 安全组规则

使用以下规则配置包含集群的 Amazon VPC 安全组(最低要求):

  • 入站规则 – 允许 Kafka 代理端口上为事件源指定的安全组的所有流量。预设情况下,Kafka 使用端口 9092。

  • 出站规则 – 允许所有目标的端口 443 上的所有流量传输。允许 Kafka 代理端口上为事件源指定的安全组的所有流量。预设情况下,Kafka 使用端口 9092。

  • 如果您使用的是 VPC 端点而不是 NAT 网关,则与 VPC 端点关联的安全组必须允许来自事件源安全组的端口 443 上的所有入站流量。

使用 VPC 端点

在使用 VPC 端点时,调用函数的 API 调用会使用 ENI 通过这些端点进行路由。Lambda 服务主体需要针对使用这些 ENI 的任何角色和函数调用 sts:AssumeRolelambda:InvokeFunction

默认情况下,VPC 端点的 IAM 策略处于开放状态。最佳做法是,将这些策略限制为仅允许特定主体使用该端点执行所需操作。为确保事件源映射能够调用 Lambda 函数,VPC 端点策略必须允许 Lambda 服务主体调用 sts:AssumeRolelambda:InvokeFunction。将 VPC 端点策略限制为仅允许来自组织内部的 API 调用,会导致事件源映射无法正常运行。

以下 VPC 端点策略示例展示了如何向 AWS STS 的 Lambda 服务主体和 Lambda 端点授予所需的访问权限。

例 VPC 端点策略 – AWS STS 端点
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Resource": "*" } ] }
例 VPC 端点策略 – Lambda 端点
{ "Statement": [ { "Action": "lambda:InvokeFunction", "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Resource": "*" } ] }

如果 Kafka 代理使用身份验证,您还可以限制 Secrets Manager 端点的 VPC 端点策略。要调用 Secrets Manager API,Lambda 会使用函数角色而非 Lambda 服务主体。以下示例展示了 Secrets Manager 端点策略。

例 VPC 端点策略 – Secrets Manager 端点
{ "Statement": [ { "Action": "secretsmanager:GetSecretValue", "Effect": "Allow", "Principal": { "AWS": [ "customer_function_execution_role_arn" ] }, "Resource": "customer_secret_arn" } ] }

如果配置了失败时的目标,Lambda 还会利用 Lambda 托管的 ENI 通过函数角色来调用 s3:PutObjectsns:Publishsqs:sendMessage

API 访问和 Lambda 函数权限

除了访问自行托管的 Kafka 集群外,您的 Lambda 函数还需要执行各种 API 操作的权限。您可以为函数的执行角色添加这些权限。如果您的用户需要访问任何 API 操作,请将所需权限添加到 AWS Identity and Access Management(IAM)用户或角色的身份策略中。

所需的 Lambda 函数权限

要在 Amazon CloudWatch Logs 中创建日志并将日志存储到日志组,Lambda 函数必须在它的执行角色中具有以下权限:

可选的 Lambda 函数权限

您的 Lambda 函数还可能需要权限来:

  • 描述您的 Secrets Manager 密钥。

  • 访问 AWS Key Management Service(AWS KMS)客户管理的密钥。

  • 访问 Amazon VPC。

  • 将失败调用的记录发送到目标。

Secrets Manager 和 AWS KMS 权限

根据您为 Kafka 代理配置的访问控制类型,Lambda 函数可能需要访问您的 Secrets Manager 密钥或解密 AWS KMS 客户管理的密钥的权限。要连接到这些资源,函数的执行角色必须具有以下权限:

VPC 权限

如果只有 VPC 内的用户才能访问您自行托管的 Apache Kafka 集群,则 Lambda 函数必须具有访问 Amazon VPC 资源的权限。这些资源包括您的 VPC、子网、安全组和网络接口。要连接到这些资源,函数的执行角色必须具有以下权限:

向执行角色添加权限

要访问自行管理的 Apache Kafka 集群使用的其他AWS服务,Lambda 需使用您在 Lambda 函数执行角色中定义的权限策略。

默认情况下,Lambda 无权为自行管理的 Apache Kafka 集群执行必需或可选操作。您必须在 IAM 信任策略中创建和定义这些操作,然后将策略附加到执行角色。此示例演示了如何创建允许 Lambda 访问您的 Amazon VPC 资源的策略。

{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "ec2:CreateNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DescribeVpcs", "ec2:DeleteNetworkInterface", "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups" ], "Resource":"*" } ] }

有关在 IAM 控制台上创建 JSON 策略文档的信息,请参阅 IAM 用户指南中的在 JSON 选项卡上创建策略

使用 IAM 策略授予用户访问权限

默认情况下,用户和角色无权执行事件源 API 操作。要向组织或账户中的用户授予访问权限,您可以创建或更新基于身份的策略。有关更多信息,请参阅 IAM 用户指南中的使用策略控制对AWS资源的访问权限