简体   繁体   English

VPC 中的 Lambda 无法连接到 AWS 服务

[英]Lambda in VPC cannot connect to AWS services

I have a lambda in a VPC because it needs to access a database.我在 VPC 中有一个 lambda,因为它需要访问数据库。 Now this lambda will also have to be able to use Firehose Kinesis Video streams ( https://aws.amazon.com/kinesis/video-streams/ ).现在这个 lambda 还必须能够使用 Firehose Kinesis 视频流 ( https://aws.amazon.com/kinesis/video-streams/ )。 My lambda is built in Python and this is my code for creating a kinesis video client:我的 lambda 内置于 Python 中,这是我创建 kinesis 视频客户端的代码:

client = boto3.client('kinesisvideo')
def create_stream(stream_name):
    response = client.create_stream(
        DeviceName='BE',
        StreamName=stream_name,
        MediaType='video/h264',
        DataRetentionInHours=1,
        Tags={
            'string': 'Livestream'
        }
    )
    stream_ARN = response['StreamARN']
    print('Printing ARN: ', stream_ARN)
    return stream_ARN

Now when I call create_stream('TEST'), my lambda times out after 90 seconds:现在,当我调用 create_stream('TEST') 时,我的 lambda 会在 90 秒后超时:

[DEBUG] 2019-11-05T15:02:47.66Z 2e094ebe-8a92-4a10-ab6c-433cf223cb5b retry needed, retryable exception caught: Connect timeout on endpoint URL: "https://kinesisvideo.eu-west-1.amazonaws.com/createStream"
Traceback (most recent call last):
File "/var/runtime/urllib3/connection.py", line 160, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw)
File "/var/runtime/urllib3/util/connection.py", line 80, in create_connection
raise err
File "/var/runtime/urllib3/util/connection.py", line 70, in create_connection
sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/var/runtime/botocore/httpsession.py", line 262, in send
chunked=self._chunked(request.headers),
File "/var/runtime/urllib3/connectionpool.py", line 641, in urlopen
_stacktrace=sys.exc_info()[2])
File "/var/runtime/urllib3/util/retry.py", line 344, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/var/runtime/urllib3/packages/six.py", line 686, in reraise
raise value
File "/var/runtime/urllib3/connectionpool.py", line 603, in urlopen
chunked=chunked)
File "/var/runtime/urllib3/connectionpool.py", line 344, in _make_request
self._validate_conn(conn)
File "/var/runtime/urllib3/connectionpool.py", line 843, in _validate_conn
conn.connect()
File "/var/runtime/urllib3/connection.py", line 316, in connect
conn = self._new_conn()
File "/var/runtime/urllib3/connection.py", line 165, in _new_conn
(self.host, self.timeout))
urllib3.exceptions.ConnectTimeoutError: (<botocore.awsrequest.AWSHTTPSConnection object at 0x7fcf62a7e128>, 'Connection to kinesisvideo.eu-west-1.amazonaws.com timed out. (connect timeout=60)')

Of what I understand, my lambda fails to connect to https://kinesisvideo.eu-west-1.amazonaws.com/createStream because its in a VPC.据我了解,我的 lambda 无法连接到https://kinesisvideo.eu-west-1.amazonaws.com/createStream因为它位于 VPC 中。 To test this, I created a new temporary lambda outside my VPC and it worked perfectly fine, it could connect to Kinesis Video Stream without problems.为了测试这一点,我在我的 VPC 外部创建了一个新的临时 lambda,它工作得非常好,它可以毫无问题地连接到 Kinesis Video Stream。

To fix this issue, I understand that I have to create an Endpoint so that my lambda in my VPC can access a AWS service such as Kinesis Video Streaming.要解决此问题,我知道我必须创建一个终端节点,以便我的 VPC 中的 lambda 可以访问 AWS 服务,例如 Kinesis Video Streaming。 I went to the VPC endpoint console and created a new endpoint.我去了 VPC 终端节点控制台并创建了一个新终端节点。 I selected the "com.amazonaws.eu-west-1.kinesis-streams" service and made sure to use the same VPC, subnets and Security group as my lambda.我选择了“com.amazonaws.eu-west-1.kinesis-streams”服务,并确保使用与我的 lambda 相同的 VPC、子网和安全组。 Once the endpoint was created, I tried calling create_stream again.创建端点后,我尝试再次调用 create_stream。 Unfortunatly, I get the same result, a timeout when trying to connect.不幸的是,我得到了相同的结果,尝试连接时超时。

So my question is: Is it possible at all to a AWS service from an VPC?所以我的问题是:是否有可能从 VPC 提供 AWS 服务? If so, how?如果是这样,怎么做?

UPDATE更新

As a response to answers I have now tried the following but I still get the same error:作为对答案的回应,我现在尝试了以下方法,但仍然遇到相同的错误:

My Lambda in VPC has a SG with All outbound permission.我在 VPC 中的 Lambda 具有具有所有出站权限的 SG。 Then I created a new SG that has inbound from the VPC SG and then assigned it to the endpoint.然后我创建了一个从 VPC SG 入站的新 SG,然后将其分配给端点。

When an AWS Lambda function is not connected to a VPC, it has full access to the Internet.当 AWS Lambda function连接到 VPC 时,它可以完全访问 Internet。

When an AWS Lambda function is connected to a VPC, it will not have direct access to the Internet.当 AWS Lambda function连接到 VPC 时,它将无法直接访问 Internet。 To grant such access, you will need either:要授予此类访问权限,您将需要:

  • A NAT Gateway in a public subnet, with matching Route tables, or公共子网中的NAT 网关,具有匹配的路由表,
  • A VPC Endpoint in the VPC for the desired service VPC 中用于所需服务的VPC 终端节点

If using a VPC Endpoint, configure the security groups as follows:如果使用 VPC Endpoint,请按如下方式配置安全组:

  • Create a security group for the Lambda function ( Lambda-SG )为 Lambda function ( Lambda-SG ) 创建一个安全组
    • Grant default "All Outbound" permission授予默认“所有出站”权限
    • There is no need for an Inbound rule不需要入站规则
  • Create a security group for the VPC Endpoint ( Endpoint-SG )为 VPC Endpoint ( Endpoint-SG ) 创建安全组
    • Grant Inbound access from Lambda-SGLambda-SG授予入站访问权限

That is, the Endpoint-SG specifically references Lambda-SG in the Inbound rules.也就是说, Endpoint-SG Lambda-SG This will permit the Lambda function to access the VPC Endpoint.这将允许 Lambda function 访问 VPC 端点。

Yes, it is very much possible to call other services via a lambda deployed into the vpc.是的,很可能通过部署到 vpc 中的 lambda 调用其他服务。

As mentioned endpoint is needed which you have already configured.如前所述,需要您已经配置的端点。 In this case the issue seems to be with the outbound ports.在这种情况下,问题似乎与出站端口有关。

Have you configured the outbound in the security group attached to your lambda?您是否在连接到您的 lambda 的安全组中配置了出站?

I just looked more closely at your code.我只是更仔细地查看了您的代码。 It appears that you are using Amazon Kinesis Video , which is different to Amazon Kinesis Data Streams .您似乎正在使用Amazon Kinesis Video ,这与Amazon Kinesis Data Streams不同。

From what I can see, the VPC Endpoint is available for Data streams, but no Video.据我所知,VPC Endpoint 可用于数据流,但不能用于视频。

That's why it can't reach the kinesisvideo.eu-west-1.amazonaws.com endpoint.这就是它无法到达kinesisvideo.eu-west-1.amazonaws.com端点的原因。

If so, then you'll need to launch a NAT Gateway in the public subnet, and update Route Tables accordingly.如果是这样,那么您需要在公共子网中启动NAT 网关,并相应地更新路由表。 The Lambda function will then be able to reach Kinesis.然后 Lambda function 将能够到达 Kinesis。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM