Lambda上传至S3时无限挂起,本地服务器上传正常问题排查
问题描述
我的Lambda位于公有子网(public subnet),对应的S3存储桶为公开状态。该Lambda已配置FullS3Access IAM角色,我尝试在VPC中创建S3端点但未解决问题。存储桶仅有的自定义权限为允许所有人获取对象。
相关代码片段如下:
s3 = boto3.client( "s3", region_name=variables.secrets.AWS_REGION_NAME, aws_access_key_id=variables.secrets.AWS_ACCESS_KEY_ID, aws_secret_access_key=variables.secrets.AWS_SECRET_ACCESS_KEY, ) logger.debug("Connected to boto client") bucket_name = "user-images" file_name = f"public_{uuid4()}.{image.filename.split('.')[-1]}" try: logger.debug("Uploading file to s3...") s3.upload_fileobj( image.file, bucket_name, file_name, ExtraArgs={ "ContentType": image.content_type, }, ) logger.debug("File uploaded to s3") except Exception as e: logger.error(str(e)) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e), )
日志最后输出“Uploading file to s3...”后程序无限挂起,文件仅60KB,已排除带宽或硬件问题。本地服务器运行相同代码可正常上传,求问题原因及解决办法。
问题原因及解决方案
核心原因
- 公有子网无有效公网出口:Lambda部署在公有子网时,若子网路由表未配置指向互联网网关(IGW)的路由,Lambda无法访问公网S3服务,导致请求挂起。
- S3端点配置无效:
- S3仅支持网关类型端点(Gateway endpoint),若创建的是接口端点则完全无效;
- 即使创建了网关端点,若未将其关联到Lambda所在子网的路由表,或路由表未添加S3前缀列表的路由,端点也无法生效。
- 硬编码凭证冲突:代码中硬编码的AWS密钥与Lambda执行角色的临时凭证产生冲突,同时VPC环境下硬编码密钥可能导致请求签名或路由异常。
解决步骤
- 修复公有子网路由:
进入AWS控制台,找到Lambda所在公有子网的路由表,添加一条路由规则:目标为0.0.0.0/0,下一跳选择对应的互联网网关(IGW),确保Lambda能访问公网。 - 正确配置S3网关端点:
- 创建S3网关端点时,关联Lambda所在的VPC,并勾选对应公有子网的路由表;
- 检查路由表是否自动添加了S3服务前缀的路由(目标为
pl-xxxxxx前缀列表,下一跳为S3端点),若未添加则手动补充。
- 移除硬编码凭证:
Lambda运行在AWS环境中会自动获取执行角色的临时凭证,无需硬编码密钥。修改boto3客户端初始化代码:s3 = boto3.client( "s3", region_name=variables.secrets.AWS_REGION_NAME ) - 验证权限:
确认FullS3Access角色包含S3写入权限(该策略默认已包含),存储桶的自定义权限不影响上传(上传依赖IAM角色权限,而非桶的公有获取权限)。
内容的提问来源于stack exchange,提问作者Nikolaisyl
相关产品推荐
相关产品推荐

