【问题标题】:Lambda in VPC cannot connect to AWS servicesVPC 中的 Lambda 无法连接到 AWS 服务
【发布时间】:2020-03-02 04:06:45
【问题描述】:

我在 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,然后将其分配给端点。

【问题讨论】:

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


    【解决方案1】:

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

    据我所知,VPC Endpoint 可用于数据流,但不能用于视频。

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

    如果是这样,那么您需要在公共子网中启动 NAT 网关,并相应地更新路由表。然后 Lambda 函数将能够访问 Kinesis。

    【讨论】:

    • 谢谢,路由表应该怎么配置?我尝试使用我的 Lambda 子网创建一个新的 NAT 网关。然后我创建了新的路由表,将 0.0.0.0/0 路由到我的 NAT 网关的 id。我还将子网关联添加到路由表中的 lambda 子网。我在这里关注了:medium.com/@philippholly/…
    • 听起来不错!对你起作用吗?要检查的主要内容是 Lambda 函数是否与 private 子网关联,Route Table 将 0.0.0.0/0 发送到 NAT Gateway,并且 NAT Gateway 在 public子网。然后,您可以使用 import urllib.request \ print(urllib.request.urlopen('https://wikipedia.com').read()) 之类的短函数测试 Lambda 是否具有 Internet 连接。
    • 成功了,谢谢!我在创建 NAT 网关时不小心选择了错误的子网!
    【解决方案2】:

    当 AWS Lambda 函数连接到 VPC 时,它可以完全访问 Internet。

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

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

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

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

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

    【讨论】:

    • 您好,感谢您的回复。我刚刚试过这个。我在 VPC 中的 Lambda 有一个具有所有出站权限的 SG。然后我创建了一个从 VPC SG 入站的新 SG,然后将其分配给端点。好像没用。
    【解决方案3】:

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

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

    您是否在附加到您的 lambda 的安全组中配置了出站?

    【讨论】:

    • 是的,您说您“确保使用与我的 lambda 相同的 VPC、子网和安全组”,但作为同一安全组的一部分并不能保证连接性。您需要一个允许 VPC 终端节点从 Lambda 接收流量的入站规则。
    猜你喜欢
    • 2021-01-07
    • 2017-10-12
    • 2018-10-20
    • 2019-11-02
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    相关资源
    最近更新 更多