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

时间:2019-11-05 18:12:52

标签: python amazon-web-services endpoint amazon-vpc amazon-kinesis-firehose

我在VPC中有一个lambda,因为它需要访问数据库。现在,此lambda还必须能够使用Firehose Kinesis视频流(https://aws.amazon.com/kinesis/video-streams/)。我的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

现在,当我调用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)')

据我了解,我的Lambda无法连接到https://kinesisvideo.eu-west-1.amazonaws.com/createStream,因为它在VPC中。为了测试这一点,我在VPC外部创建了一个新的临时lambda,它工作得很好,它可以毫无问题地连接到Kinesis Video Stream。

要解决此问题,我了解我必须创建一个端点,以便VPC中的lambda可以访问AWS服务(例如Kinesis Video Streaming)。我转到VPC端点控制台并创建了一个新端点。我选择了“ com.amazonaws.eu-west-1.kinesis-streams”服务,并确保使用与lambda相同的VPC,子网和安全组。创建端点后,我尝试再次调用create_stream。不幸的是,尝试连接时,我得到了相同的结果,超时。

所以我的问题是:从VPC到AWS服务完全可行吗?如果可以,怎么办?

更新

作为对答案的回应,我现在尝试了以下操作,但仍然出现相同的错误:

我在VPC中的Lambda具有一个具有“所有出站”权限的SG。然后,我创建了一个从VPC SG入站的新SG,然后将其分配给端点。

3 个答案:

答案 0 :(得分:1)

是的,很有可能通过部署在vpc中的lambda调用其他服务。

如上所述,需要已配置的端点。在这种情况下,问题似乎出在出站端口上。

您是否已在Lambda附加的安全组中配置出站?

答案 1 :(得分:1)

当AWS Lambda函数连接到VPC时,它具有对Internet的完全访问权限。

将AWS Lambda函数 连接到VPC时,将直接访问Internet。要授予此类访问权限,您将需要:

  • 公共子网中的 NAT网关,具有匹配的路由表
  • VPC中用于所需服务的 VPC端点

如果使用VPC端点,请按以下方式配置安全组:

  • 为Lambda函数创建安全组Lambda-SG
    • 授予默认的“所有出站”权限
    • 不需要入站规则
  • 为VPC端点创建安全组Endpoint-SG
      Lambda-SG 授予
    • 入站访问权限

也就是说,Endpoint-SG在入站规则中专门引用了Lambda-SG。这将允许Lambda函数访问VPC端点。

答案 2 :(得分:0)

我只是更仔细地查看了您的代码。看来您正在使用 Amazon Kinesis Video ,这与 Amazon Kinesis Data Streams 不同。

据我所见,VPC端点可用于数据流,但无视频。

这就是为什么它无法到达kinesisvideo.eu-west-1.amazonaws.com端点的原因。

如果是这样,则需要在公共子网中启动 NAT网关,并相应地更新路由表。然后,Lambda函数将可以到达Kinesis。