Localstack Lambda无法连接http://localhost:4566,Spyder运行正常
问题描述
我配置了默认Localstack环境,在PowerShell中设置以下AWS环境变量:
$env:AWS_ACCESS_KEY_ID="dummy" $env:AWS_SECRET_ACCESS_KEY="dummy" $env:AWS_DEFAULT_REGION="us-east-1" $env:AWS_ENDPOINT_URL="http://localhost:4566"
我的Lambda功能是在已存在的S3桶bucket1中创建名为prueba的目录,代码如下:
import boto3 def lambda_handler(event, context): # Nombre del bucket de S3 bucket_name = 'bucket1' # Nombre del directorio que deseas crear en el bucket directory_name = 'prueba' # Crea el directorio en el bucket s3_client = boto3.client('s3', endpoint_url='http://localhost:4566') try: s3_client.put_object(Bucket=bucket_name, Key=directory_name) print("El archivo '{file}' se ha subido al bucket '{bucket_name}'") variable=1 except Exception as e: return { 'statusCode': 0, # Código de estado de error 'body': str(e) # Mensaje de error como cadena } return { 'statusCode': variable }
该代码在Spyder(Python3.8)中调用可成功创建目录,但在Localstack的Lambda中执行时,返回异常:
{"statusCode": 0, "body": "Could not connect to the endpoint URL: \"http://localhost:4566/bucket1/prueba\""}
目标S3桶已存在,我已为Lambda配置了允许相关操作的IAM角色策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:*", "Resource": "*" }, { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bucket1/*" }, { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket1/*" } ] }
通过以下命令创建Lambda函数:
aws --endpoint-url=http://localhost:4566 lambda create-function --function-name Test --runtime python3.8 --handler test.lambda_handler --role arn:aws:iam::000000000000:role/RolLambda --zip-file fileb://./test.zip --timeout 1000
解决方案
1. 修正Lambda内部的Endpoint地址
Localstack的Lambda运行在独立容器中,代码里的localhost指向的是Lambda容器本身,而非Localstack主容器。需要替换为以下地址之一:
- Docker内部主机名(适用于Docker Compose部署):
s3_client = boto3.client('s3', endpoint_url='http://localstack:4566') - 宿主机IP/特殊域名(适用于直接运行Localstack):
替换为你的Windows宿主机IP(比如192.168.1.100),或者使用Docker提供的host.docker.internal(Windows/macOS通用):s3_client = boto3.client('s3', endpoint_url='http://host.docker.internal:4566')
2. 通过环境变量传递Endpoint(推荐)
避免硬编码地址,创建Lambda时传入环境变量:
aws --endpoint-url=http://localhost:4566 lambda create-function --function-name Test --runtime python3.8 --handler test.lambda_handler --role arn:aws:iam::000000000000:role/RolLambda --zip-file fileb://./test.zip --timeout 1000 --environment Variables={AWS_ENDPOINT_URL=http://host.docker.internal:4566}
然后修改代码读取环境变量:
import os import boto3 def lambda_handler(event, context): bucket_name = 'bucket1' directory_name = 'prueba/' # 注意添加斜杠,模拟S3目录 s3_client = boto3.client('s3', endpoint_url=os.environ.get('AWS_ENDPOINT_URL')) # 后续代码保持不变
3. 验证S3服务状态
执行以下命令确认Localstack的S3服务正常,且bucket1存在:
aws --endpoint-url=http://localhost:4566 s3 ls s3://bucket1
如果无法列出内容,重启Localstack服务后重试。
4. 修正S3目录的Key格式
S3中没有真正的目录,所谓“目录”是通过带斜杠/的键实现的。将代码中的directory_name = 'prueba'改为directory_name = 'prueba/',确保创建的是符合预期的目录结构。
内容的提问来源于stack exchange,提问作者Angel Sanchez
相关产品推荐
相关产品推荐

