SQS 发送消息时 Lambda 超时
我设置了一个非常简单的 Lambda 来向 SQS 发送消息。 Lambda位于VPC中,有两个公共子网(我不完全了解aws网络,我刚刚看到连接到子网的路由表有0.0.0.0/0作为路由之一,连接到Internet网关)和一个安全团体。我已经仔细检查了权限,它们工作正常,因为如果我删除 Lambda 上的 VPC 设置,它就会工作。
我尝试按照文章中的建议创建端点: SQS 从 VPC 发送,但 Lambda 超时。
正如SO解决方案链接中所建议的,我尝试在客户端中添加endpoint_url,这也不起作用。
Lambda 代码如下:
#Testing SQS push message.
import botocore
import boto3
def main(event, context):
session = boto3.Session()
sqs_client = session.client(
service_name='sqs',
endpoint_url='https://sqs.eu-west-1.amazonaws.com',
)
sqs_client.send_message(
QueueUrl='https://sqs.eu-west-1.amazonaws.com/***********/tutorial-queue-test',
MessageBody='msg sent from '
)
return {}
恢复我的设置我有:
- VPC 内的 Lambda、2 个子网(公共)、1 个安全组。
- SQS
- VPC 内部的
SQS 端点我无法将 Lambda 保留在 VPC 外部,因为我需要使用 EFS,我将其集成到 Lambda 中。
解决方案: 毕竟我成功正确启动了 Lambda,我猜想这是 Lambda 和 Endpoint 的错误安全组规则的混合,并且 VPC 私有 DNS 名称被禁用。感谢大家的支持。
为了便于阅读,我总结了成功启动 Lambda 的主要解决方案:
- 为 Lambda 添加安全组,该安全组具有 INBOUND RULE(协议:所有 TCP,端口:0 - 65535,源:0.0.0.0/0)和 OUTBOUND RULE(Protocol:All, Ports:All, Destination:0.0.0.0/0)
- 为 Endpoint 添加安全组,该安全组具有 INBOUND规则(IP 版本:–、类型:所有 TCP、协议:TCP、端口:0 - 65535、源:
)和出站规则(IP 版本:IPv4、类型:所有流量、协议:全部、端口:全部,目的地:0.0.0.0/0)。 - 从端点中,选择当前端点->操作->修改私有 DNS 名称->修改私有 DNS 名称。启用私有 DNS 名称。
I set up a very simple Lambda for sending a message to a SQS. Lambda is in a VPC, with two public subnets (I do not fully understand aws networking, I've just seen that the routing table connected to subnets have 0.0.0.0/0 as one the routes, connected to Internet Gateway) and a security group. I've already double-checked Permissions and they work properly, cause if I remove VPC settings on Lambda it works.
I tried to create an Endpoint as suggested in the article: SQS sending from VPC, but the Lambda timed out.
As suggested in SO solution link, I tried to add the endpoint_url in the client, also that's not working.
Lambda code is the following:
#Testing SQS push message.
import botocore
import boto3
def main(event, context):
session = boto3.Session()
sqs_client = session.client(
service_name='sqs',
endpoint_url='https://sqs.eu-west-1.amazonaws.com',
)
sqs_client.send_message(
QueueUrl='https://sqs.eu-west-1.amazonaws.com/***********/tutorial-queue-test',
MessageBody='msg sent from '
)
return {}
Resuming my setup I have:
- Lambda inside a VPC, 2 subnets(public), 1 security group.
- SQS
- SQS Endpoint inside the VPC
I cannot keep the Lambda outside the VPC, cause I'll need to use a EFS, that I will integrate in the Lambda.
SOLUTION:
Afterall I succeded to launch correctly the Lambda, I guess it was a mix of bad security group rules, both for Lambda and Endpoint, and VPC private DNS name disabled. Thanks everyone for the support.
Just for readability purposes I summerise the main solutions that brought me to successfully launch Lambda:
- Add a Security Group for Lambda, which has INBOUND RULE(Protocol:All TCP, Ports:0 - 65535, Source:0.0.0.0/0) and OUTBOUND RULE(Protocol:All, Ports:All, Destination:0.0.0.0/0)
- Add a Security Group for Endpoint, which has INBOUND RULE(IP version: –, Type:All TCP, Protocol:TCP, Ports:0 - 65535, Source: <INSERT_LAMBDA_SECURITY_GROUP>) and OUTBOUND RULE(IP version: IPv4, Type:All traffic, Protocol:All, Ports:All, Destination: 0.0.0.0/0).
- From Endpoints, select the current Endpoint->Actions->Modify private DNS name-> Enable private DNS names.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
放置在公共子网中的 Lambda 没有 Internet 连接,因为它们无法使用 Internet 网关。
因此,第一步是根据最佳实践将 lambda 放置在私有或隔离子网中。
然后,有两个选项:
如果您的 Lambda 需要互联网连接,请添加 NAT 网关并添加从私有子网到该网关的路由。如果您选择此路线,则无需使用 VPC 端点。
如果您想避免使用 NAT 网关,只需将 lambda 放置在隔离子网中,它将使用您创建的 VPC 终端节点。
如果端点启用了私有 DNS,则无需提供自定义
endpoint_url
,boto3 将按原样工作。如果这不起作用,请验证该终端节点是否是在您的 Lambda 正在使用的子网中创建的。另请验证您是否已为端点打开私有 DNS。
另请参阅:为什么 VPC 中公有子网内的 AWS lambda 函数无法连接到互联网?
Lambdas placed in a Public subnet do not have internet connectivity as they cannot use an Internet Gateway.
So the first step is to place the lambda in a Private or Isolated subnet, according to best practices.
Then, there are two options:
If your Lambda requires internet connectivity, add a NAT gateway and add a route to it from the Private subnet. If you go this route, you will not need to use VPC endpoints.
If you want to avoid using a NAT gateway, simply place the lambda in an Isolated subnet and it will use the VPC endpoints you created.
If the endpoints have private DNS enabled, you do not need to provide a custom
endpoint_url
, boto3 will work as is.If this doesn't work, verify that the endpoint is created in the subnet that your Lambda is using. Also verify that you have Private DNS turned on for the endpoint.
See also: Why can't an AWS lambda function inside a public subnet in a VPC connect to the internet?