首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >本地堆栈Lambda调用在Windows上失败

本地堆栈Lambda调用在Windows上失败
EN

Stack Overflow用户
提问于 2021-05-07 19:09:30
回答 1查看 668关注 0票数 2

我有一个类似于Unable to invoke lambda function from localstack via aws cli的问题,但症状不同。SO中描述的解决方案对我不起作用。

我在Windows10上运行,安装了Docker、Terraform和LocalStack的最新版本(截至2021年4月/5月)。所有命令都将以管理员权限输入到Windows cmd窗口中,并设置为正确的工作文件夹。

我使用下面的docker-compose.yml使用docker-compose up -d启动本地堆栈

代码语言:javascript
复制
version: '3.2'
services:
  localstack:
    image: localstack/localstack-full:latest
    container_name: localstack_serverless1
    ports:
      - '4566:4566'
      - '8055:8080'
    environment:
      # - HOSTNAME_EXTERNAL=localstack
      - COMPOSE_CONVERT_WINDOWS_PATHS=1
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - LAMBDA_EXECUTOR=docker
      - START_WEB=1
      #- DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - './.localstack:/tmp/localstack'
      - '/var/run/docker.sock:/var/run/docker.sock'
      #- './docker.sock:/var/run/docker.sock'

被注释掉的代码行是我尝试过的,但并没有起到什么作用。

然后,我使用以下输入运行terraform initterraform apply

代码语言:javascript
复制
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  access_key                  = "mock_access_key"
  region                      = "us-east-1"
  s3_force_path_style         = true
  secret_key                  = "mock_secret_key"
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  # AWS Provider version held back for this issue:
  # https://github.com/localstack/localstack/issues/1818
  # (localstack's fix not released yet)
  # version = "2.39.0"

  endpoints {
    apigateway     = "http://localhost:4566"
    cloudformation = "http://localhost:4566"
    cloudwatch     = "http://localhost:4566"
    dynamodb       = "http://localhost:4566"
    ec2            = "http://localhost:4566"
    es             = "http://localhost:4566"
    firehose       = "http://localhost:4566"
    iam            = "http://localhost:4566"
    kinesis        = "http://localhost:4566"
    lambda         = "http://localhost:4566"
    route53        = "http://localhost:4566"
    redshift       = "http://localhost:4566"
    s3             = "http://localhost:4566"
    secretsmanager = "http://localhost:4566"
    ses            = "http://localhost:4566"
    sns            = "http://localhost:4566"
    sqs            = "http://localhost:4566"
    ssm            = "http://localhost:4566"
    stepfunctions  = "http://localhost:4566"
    sts            = "http://localhost:4566"
  }
}

resource "aws_s3_bucket" "serverless1_bucket1" {
  bucket = "serverless1-bucket1"
  acl    = "private"
}

resource "aws_s3_bucket_object" "upload_code_lambda1" {
  bucket = "serverless1-bucket1"
  key    = "v1.0.0/lambda1.zip"
  source = "lambda1.zip"
  depends_on = [aws_s3_bucket.serverless1_bucket1]
}

resource "aws_lambda_function" "serverless1_lambda1" {
   function_name = "serverless1-lambda1"

   # The bucket name as created earlier with "aws s3api create-bucket"
   s3_bucket = "serverless1-bucket1"
   s3_key    = "v1.0.0/lambda1.zip"

   # "lambda1" is the filename within the zip file (lambda1.js) and "handler"
   # is the name of the property under which the handler function was
   # exported in that file.
   handler = "lambda1.handler"
   runtime = "nodejs10.x"

   role = aws_iam_role.lambda_exec.arn
   
   # Ant Waters: I have added this to make lambda creation wait until the code has been uploaded.  I'm not sure if it is needed or not.
   depends_on = [aws_s3_bucket_object.upload_code_lambda1]
}

 # IAM role which dictates what other AWS services the Lambda function
 # may access.
resource "aws_iam_role" "lambda_exec" {
   name = "serverless_example_lambda"

   assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_api_gateway_rest_api" "example" {
  name        = "ServerlessExample1"
  description = "Terraform Serverless Application Example"
}


resource "aws_api_gateway_resource" "proxy" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   parent_id   = aws_api_gateway_rest_api.example.root_resource_id
   path_part   = "{proxy+}"
}

resource "aws_api_gateway_method" "proxy" {
   rest_api_id   = aws_api_gateway_rest_api.example.id
   resource_id   = aws_api_gateway_resource.proxy.id
   http_method   = "ANY"
   authorization = "NONE"
}


resource "aws_api_gateway_integration" "lambda" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   resource_id = aws_api_gateway_method.proxy.resource_id
   http_method = aws_api_gateway_method.proxy.http_method

   integration_http_method = "POST"
   type                    = "AWS_PROXY"
   uri                     = aws_lambda_function.serverless1_lambda1.invoke_arn
}


resource "aws_api_gateway_method" "proxy_root" {
   rest_api_id   = aws_api_gateway_rest_api.example.id
   resource_id   = aws_api_gateway_rest_api.example.root_resource_id
   http_method   = "ANY"
   authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_root" {
   rest_api_id = aws_api_gateway_rest_api.example.id
   resource_id = aws_api_gateway_method.proxy_root.resource_id
   http_method = aws_api_gateway_method.proxy_root.http_method

   integration_http_method = "POST"
   type                    = "AWS_PROXY"
   uri                     = aws_lambda_function.serverless1_lambda1.invoke_arn
}


resource "aws_api_gateway_deployment" "example" {
   depends_on = [
     aws_api_gateway_integration.lambda,
     aws_api_gateway_integration.lambda_root,
   ]

   rest_api_id = aws_api_gateway_rest_api.example.id
   stage_name  = "test"
}


resource "aws_lambda_permission" "apigw" {
   statement_id  = "AllowAPIGatewayInvoke"
   action        = "lambda:InvokeFunction"
   function_name = aws_lambda_function.serverless1_lambda1.function_name
   principal     = "apigateway.amazonaws.com"

   # The "/*/*" portion grants access from any method on any resource
   # within the API Gateway REST API.
   source_arn = "${aws_api_gateway_rest_api.example.execution_arn}/*/*"
}

output "base_url" {
  value = aws_api_gateway_deployment.example.invoke_url
}

网关的东西是从教程中抄袭过来的,我还不明白。

然后我可以在"https://app.localstack.cloud/resources“和"https://app.localstack.cloud/resources/gateway"”中看到lambda,并且在网关页面上有一个Invoke按钮。但是,当我按下这个按钮时,似乎什么都没有发生,除了CloudWatch中的错误日志:

类似地,我可以看到使用AWS CLI的函数,调用:

代码语言:javascript
复制
aws lambda get-function --function-name "serverless1-lambda1" --endpoint-url=http://localhost:4566

它返回:

代码语言:javascript
复制
{
    "Configuration": {
        "FunctionName": "serverless1-lambda1",
        "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:serverless1-lambda1",
        "Runtime": "nodejs10.x",
        "Role": "arn:aws:iam::000000000000:role/serverless_example_lambda",
        "Handler": "lambda1.handler",
        "CodeSize": 342,
        "Description": "",
        "Timeout": 3,
        "MemorySize": 128,
        "LastModified": "2021-05-07T10:17:32.305+0000",
        "CodeSha256": "qoP7ORF4AUC8VJWLR0bGGRRKGtNrQwRj2hCa1n+3wk4=",
        "Version": "$LATEST",
        "VpcConfig": {},
        "TracingConfig": {
            "Mode": "PassThrough"
        },
        "RevisionId": "ea163f0f-81ce-4b3a-a0d1-7b44379c6492",
        "State": "Active",
        "LastUpdateStatus": "Successful",
        "PackageType": "Zip"
    },
    "Code": {
        "Location": "http://localhost:4566/2015-03-31/functions/serverless1-lambda1/code"
    },
    "Tags": {}
}

但是,当我尝试使用以下命令调用它时:

代码语言:javascript
复制
aws --endpoint-url=http://localhost:4566 lambda invoke --function-name "serverless1-lambda1" output.json

结果是:

代码语言:javascript
复制
{
  "errorMessage": "Lambda process returned error status code: 1. Result: . Output:\nUnable to find image 'lambci/lambda:nodejs10.x' locally\nError response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)\nmust specify at least one container source\njson: cannot unmarshal array into Go value of type types.ContainerJSON",
  "errorType": "InvocationException",
  "stackTrace": [
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_api.py\", line 602, in run_lambda\n    result = LAMBDA_EXECUTOR.execute(func_arn, func_details, event, context=context,\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 176, in execute\n    return do_execute()\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 168, in do_execute\n    return _run(func_arn=func_arn)\n",
    "  File \"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 149, in wrapped\n    raise e\n",
    "  File \"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 145, in wrapped\n    result = func(*args, **kwargs)\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 159, in _run\n    raise e\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 147, in _run\n    result = self._execute(func_arn, func_details, event, context, version)\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 325, in _execute\n    result = self.run_lambda_executor(cmd, stdin, env_vars=environment, func_details=func_details)\n",
    "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 231, in run_lambda_executor\n    raise InvocationException('Lambda process returned error status code: %s. Result: %s. Output:\\n%s' %\n"
  ]
}

Docker窗口跟踪显示:

代码语言:javascript
复制
localstack_serverless1 | 2021-05-07T10:59:50:WARNING:localstack.services.awslambda.lambda_executors: Empty event body specified for invocation of Lambda "arn:aws:lambda:us-east-1:000000000000:function:serverless1-lambda1"
localstack_serverless1 | 2021-05-07T10:59:50:INFO:localstack.services.awslambda.lambda_executors: Running lambda cmd: CONTAINER_ID="$(docker create -i   -e AWS_REGION="$AWS_REGION" -e DOCKER_LAMBDA_USE_STDIN="$DOCKER_LAMBDA_USE_STDIN" -e LOCALSTACK_HOSTNAME="$LOCALSTACK_HOSTNAME" -e EDGE_PORT="$EDGE_PORT" -e _HANDLER="$_HANDLER" -e AWS_LAMBDA_FUNCTION_TIMEOUT="$AWS_LAMBDA_FUNCTION_TIMEOUT" -e AWS_LAMBDA_FUNCTION_NAME="$AWS_LAMBDA_FUNCTION_NAME" -e AWS_LAMBDA_FUNCTION_VERSION="$AWS_LAMBDA_FUNCTION_VERSION" -e AWS_LAMBDA_FUNCTION_INVOKED_ARN="$AWS_LAMBDA_FUNCTION_INVOKED_ARN" -e AWS_LAMBDA_COGNITO_IDENTITY="$AWS_LAMBDA_COGNITO_IDENTITY" -e NODE_TLS_REJECT_UNAUTHORIZED="$NODE_TLS_REJECT_UNAUTHORIZED"   --rm "lambci/lambda:nodejs10.x" "lambda1.handler")";docker cp "/tmp/localstack/zipfile.9cb3ff88/." "$CONTAINER_ID:/var/task"; docker start -ai "$CONTAINER_ID";
localstack_serverless1 | 2021-05-07T11:00:05:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:us-east-1:000000000000:function:serverless1-lambda1 result / log output:
localstack_serverless1 | 
localstack_serverless1 | > Unable to find image 'lambci/lambda:nodejs10.x' locally
localstack_serverless1 | > Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
localstack_serverless1 | > must specify at least one container source
localstack_serverless1 | > json: cannot unmarshal array into Go value of type types.ContainerJSON
localstack_serverless1 | 2021-05-07T11:00:05:INFO:localstack.services.awslambda.lambda_api: Error executing Lambda function arn:aws:lambda:us-east-1:000000000000:function:serverless1-lambda1: Lambda process returned error status code: 1. Result: . Output:
localstack_serverless1 | Unable to find image 'lambci/lambda:nodejs10.x' locally
localstack_serverless1 | Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
localstack_serverless1 | must specify at least one container source
localstack_serverless1 | json: cannot unmarshal array into Go value of type types.ContainerJSON Traceback (most recent call last):
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_api.py", line 602, in run_lambda
localstack_serverless1 |     result = LAMBDA_EXECUTOR.execute(func_arn, func_details, event, context=context,
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 176, in execute
localstack_serverless1 |     return do_execute()
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 168, in do_execute
localstack_serverless1 |     return _run(func_arn=func_arn)
localstack_serverless1 |   File "/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py", line 149, in wrapped
localstack_serverless1 |     raise e
localstack_serverless1 |   File "/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py", line 145, in wrapped
localstack_serverless1 |     result = func(*args, **kwargs)
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 159, in _run
localstack_serverless1 |     raise e
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 147, in _run
localstack_serverless1 |     result = self._execute(func_arn, func_details, event, context, version)
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 325, in _execute
localstack_serverless1 |     result = self.run_lambda_executor(cmd, stdin, env_vars=environment, func_details=func_details)
localstack_serverless1 |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 231, in run_lambda_executor
localstack_serverless1 |     raise InvocationException('Lambda process returned error status code: %s. Result: %s. Output:\n%s' %
localstack_serverless1 | localstack.services.awslambda.lambda_executors.InvocationException: Lambda process returned error status code: 1. Result: . Output:
localstack_serverless1 | Unable to find image 'lambci/lambda:nodejs10.x' locally
localstack_serverless1 | Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
localstack_serverless1 | must specify at least one container source
localstack_serverless1 | json: cannot unmarshal array into Go value of type types.ContainerJSON
localstack_serverless1 | 
EN

回答 1

Stack Overflow用户

发布于 2021-06-17 15:26:41

我通过将docker-compose.yml更改为以下代码来实现此功能:

代码语言:javascript
复制
version: '3.2'
services:
  localstack:
    image: localstack/localstack-full:latest
    container_name: localstack_serverless1
    ports:
      - '4566:4566'
      - '4571:4571'
      - '8055:8080'
    environment:
      # - HOSTNAME_EXTERNAL=localstack
      - COMPOSE_CONVERT_WINDOWS_PATHS=1
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - LAMBDA_EXECUTOR=docker
      - START_WEB=1
      
      - DOCKER_HOST=unix:///var/run/docker.sock
      - HOST_TMP_FOLDER=./.localstack
    volumes:
      - './.localstack:/tmp/localstack'
      - '/var/run/docker.sock:/var/run/docker.sock'     # I don't understand what this corresponds to on my PC? But it is the only option I can get to work!

最后一行非常奇怪,因为我不明白它在我的windows PC上映射到了什么?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67433861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档