python - VPC 中的 Lambda 无法连接到 AWS 服务
问题描述
我在 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,然后将其分配给端点。
解决方案
当 AWS Lambda 函数未连接到 VPC 时,它可以完全访问 Internet。
当 AWS Lambda 函数连接到 VPC 时,它将无法直接访问 Internet。要授予此类访问权限,您将需要:
- 公共子网中的NAT 网关,具有匹配的路由表,或
- VPC中用于所需服务的VPC 终端节点
如果使用 VPC Endpoint,请按如下方式配置安全组:
- 为 Lambda 函数创建安全组(
Lambda-SG
)- 授予默认“所有出站”权限
- 不需要入站规则
- 为 VPC Endpoint创建安全组(
Endpoint-SG
)- 授予来自的入站访问权限
Lambda-SG
- 授予来自的入站访问权限
即入站规则中的Endpoint-SG
具体引用。Lambda-SG
这将允许 Lambda 函数访问 VPC 端点。
推荐阅读
- sparql - 选择缺少属性或属性值低于某个限制的实体
- javascript - 如何串联?字符串 + 数学 谢谢
- sqlite - SQL 查询中本地时间的 18 位时间戳
- angular - 替换app文件夹后编译错误
- angular - Angular 2+:如何使用默认值使下拉菜单只读(或禁用)并在没有默认值的情况下添加表单验证错误
- testing - 用于服务/集成测试的 SignalR 服务模拟实现
- c++ - 从 Thingsboard 到 Arduino (ESP32) 的 RPC 调用问题
- excel-formula - 行值和列标题连接以获取 Excel 中的老员工总数
- node.js - NodeJS MongoDB 返回十分钟前的数据
- python - 使用 to_csv 的 for 循环,只循环一次