在docker中将AWS SAM Local与dynamodb连接 [英] connecting AWS SAM Local with dynamodb in docker

查看:77
本文介绍了在docker中将AWS SAM Local与dynamodb连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用AWS sam local设置了一个api网关/ aws lambda对,并确认我可以在运行后成功调用



sam然后,我在docker容器中添加了本地dynamodb实例,并使用aws cli



但是,在将代码添加到lambda以写入dynamodb实例后,我收到了:


2018-02-22T11:13:16.172Z ed9ab38e-fb54-18a4-0852-db7e5b56c8cd错误:
无法写入表:{ message: connect ECONNREFUSED
0.0.0.0 :8000, code: NetworkingError, errno: ECONNREFUSED, syscall: connect, address: 0.0.0.0, port:8000, region: eu -west-2, hostname: 0.0.0.0, retryable:true, time: 2018-02-22T11:13:16.165Z}
来自命令的写入事件:
{ name: test, geolocation: xyz, type: createDestination} END
RequestId:ed9ab38e-fb54-18a4-0852-db7e5b56c8cd


我看到了在线,您可能需要连接到相同的docker网络,所以我创建了一个网络 docker network create lambda-local ,并将启动命令更改为:



sam local start-api --docker-network lambda-local





docker run -v $ PWD:/ dynamodb_local_db -p 8000:8000 --network = lambda-local cnadiminti / dynamodb-local :latest



但仍然收到相同的错误



sam local正在打印 2018/02/22 11:12:51将容器98b19370ab92f3378ce380e9c840177905a49fc986597fef9ef589e624b4eac3连接到本地lambda网络



我正在创建dynamodbclient使用:

  const AWS = require('aws-sdk')
const dynamodbURL = process.env。 dynamodbURL || ‘http://0.0.0.0:8000’
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID || ‘1234567’
const awsAccessKey = process.env.AWS_SECRET_ACCESS_KEY || ‘7654321’
const awsRegion = process.env.AWS_REGION || 'eu-west-2'

console.log(awsRegion,'在区域中初始化dynamodb:')

让dynamoDbClient
const makeClient =()=> ; {
dynamoDbClient =新的AWS.DynamoDB.DocumentClient({
端点:dynamodbURL,
accessKeyId:awsAccessKeyId,
secretAccessKey:awsAccessKey,
区域:awsRegion
})
return dynamoDbClient
}

module.exports = {
connect:()=> dynamoDbClient || makeClient()
}

并检查我的代码正在创建节目的dynamodbclient

  DocumentClient {
选项:
{端点:'http://0.0.0.0:8000',
accessKeyId:'my-key',
secretAccessKey:'my-secret',
地区:'eu-west-2',
attrValue:'S8'},
服务:
服务{
配置:
配置{
凭据:[对象],
凭据提供者:[对象],
区域:'eu-west -2',
记录器:空,
api版本:{},
apiVersion:空,
端点:'http://0.0.0.0:8000',
httpOptions:[Object],
maxRetries:未定义,
maxRedirects:10,
paramValidation:true,
sslEnabled:true,
s3ForcePathStyle:false,
s3BucketEndpoint:假,
s3DisableBodySigning:真,
computeChecksums:真,
convertResponseTypes:true,
correctClockSkew:false,
customUserAgent:null,
dynamoDbCrc32:true,
systemClockOffset:0,
signatureVersion:null,
signatureCache: true,
retryDelayOptions:{},
useAccelerateEndpoint:false,
accessKeyId:'my-key',
secretAccessKey:'my-secret'},
端点:
端点{
协议:'http:',
主机:'0.0.0.0:8000',
端口:8000,
主机名:'0.0.0.0' ,
路径名:'/',
路径:'/',
href:'http://0.0.0.0:8000/'},
_clientId:1},
attrValue:'S8'}

此设置是否可行?我如何让他们彼此交谈?



----编辑----



基于在Twitter对话上,值得一提(也许),我可以在CLI和Web Shell中与dynamodb进行交互



解决方案

非常感谢 Heitor Lessa在Twitter上回答了我并举了一个示例回购



哪个指向我在答案...




  • dynamodb的docker容器位于127.0。从我的
    机器的上下文中获取0.1(这就是为什么我可以与之交互的原因)


  • SAM本地的docker容器r从我的
    机器的上下文中位于127.0.0.1


  • 但从彼此的上下文中它们不在127.0.0.1中




因此: https://github.com/heitorlessa/sam-local-python-hot-reloading/blob/master/users/users.py#L14



将我的连接代码更改为:

  const AWS = require('aws-sdk')
const awsRegion = process.env.AWS_REGION || ‘eu-west-2’

让dynamoDbClient
const makeClient =()=> {
const options = {
地区:awsRegion
}
if(process.env.AWS_SAM_LOCAL){
options.endpoint ='http:// dynamodb:8000 '
}
dynamoDbClient =新的AWS.DynamoDB.DocumentClient(options)
return dynamoDbClient
}

module.exports = {
connect :()=> dynamoDbClient || makeClient()
}

重要行是:

  if(process.env.AWS_SAM_LOCAL){
options.endpoint ='http:// dynamodb:8000'
}

从SAM本地docker容器的上下文中,dynamodb容器通过其名称公开



我的两个启动命令最终显示为:



docker run -d- v $ PWD:/ dynamodb_local_db -p 8000:8000 --network lambda-local --name dynamodb cnadiminti / dynamodb-local





AWS_REGION = eu-west-2 sam local start-api --docker-network lambda-local



这里唯一的变化是给dynamodb容器起一个名字


I've set up an api gateway/aws lambda pair using AWS sam local and confirmed I can call it successfully after running

sam local start-api

I've then added a local dynamodb instance in a docker container and created a table on it using the aws cli

But, having added the code to the lambda to write to the dynamodb instance I receive:

2018-02-22T11:13:16.172Z ed9ab38e-fb54-18a4-0852-db7e5b56c8cd error: could not write to table: {"message":"connect ECONNREFUSED 0.0.0.0:8000","code":"NetworkingError","errno":"ECONNREFUSED","syscall":"connect","address":"0.0.0.0","port":8000,"region":"eu-west-2","hostname":"0.0.0.0","retryable":true,"time":"2018-02-22T11:13:16.165Z"} writing event from command: {"name":"test","geolocation":"xyz","type":"createDestination"} END RequestId: ed9ab38e-fb54-18a4-0852-db7e5b56c8cd

I saw online that you might need to connect to the same docker network so I created a network docker network create lambda-local and have changed my start commands to:

sam local start-api --docker-network lambda-local

and

docker run -v "$PWD":/dynamodb_local_db -p 8000:8000 --network=lambda-local cnadiminti/dynamodb-local:latest

but still receive the same error

sam local is printing out 2018/02/22 11:12:51 Connecting container 98b19370ab92f3378ce380e9c840177905a49fc986597fef9ef589e624b4eac3 to network lambda-local

I'm creating the dynamodbclient using:

const AWS = require('aws-sdk')
const dynamodbURL = process.env.dynamodbURL || 'http://0.0.0.0:8000'
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID || '1234567'
const awsAccessKey = process.env.AWS_SECRET_ACCESS_KEY || '7654321'
const awsRegion = process.env.AWS_REGION || 'eu-west-2'

console.log(awsRegion, 'initialising dynamodb in region: ')

let dynamoDbClient
const makeClient = () => {
  dynamoDbClient = new AWS.DynamoDB.DocumentClient({
    endpoint: dynamodbURL,
    accessKeyId: awsAccessKeyId,
    secretAccessKey: awsAccessKey,
    region: awsRegion
  })
  return dynamoDbClient
}

module.exports = {
  connect: () => dynamoDbClient || makeClient()
}

and inspecting the dynamodbclient my code is creating shows

DocumentClient {
  options:
   { endpoint: 'http://0.0.0.0:8000',
     accessKeyId: 'my-key',
     secretAccessKey: 'my-secret',
     region: 'eu-west-2',
     attrValue: 'S8' },
  service:
   Service {
     config:
      Config {
        credentials: [Object],
        credentialProvider: [Object],
        region: 'eu-west-2',
        logger: null,
        apiVersions: {},
        apiVersion: null,
        endpoint: 'http://0.0.0.0:8000',
        httpOptions: [Object],
        maxRetries: undefined,
        maxRedirects: 10,
        paramValidation: true,
        sslEnabled: true,
        s3ForcePathStyle: false,
        s3BucketEndpoint: false,
        s3DisableBodySigning: true,
        computeChecksums: true,
        convertResponseTypes: true,
        correctClockSkew: false,
        customUserAgent: null,
        dynamoDbCrc32: true,
        systemClockOffset: 0,
        signatureVersion: null,
        signatureCache: true,
        retryDelayOptions: {},
        useAccelerateEndpoint: false,
        accessKeyId: 'my-key',
        secretAccessKey: 'my-secret' },
     endpoint:
      Endpoint {
        protocol: 'http:',
        host: '0.0.0.0:8000',
        port: 8000,
        hostname: '0.0.0.0',
        pathname: '/',
        path: '/',
        href: 'http://0.0.0.0:8000/' },
     _clientId: 1 },
  attrValue: 'S8' }

Should this setup work? How do I get them talking to each other?

---- edit ----

Based on a twitter conversation it's worth mentioning (maybe) that I can interact with dynamodb at the CLI and in the web shell

解决方案

Many thanks to Heitor Lessa who answered me on Twitter with an example repo

Which pointed me at the answer...

  • dynamodb's docker container is on 127.0.0.1 from the context of my machine (which is why I could interact with it)

  • SAM local's docker container is on 127.0.0.1 from the context of my machine

  • But they aren't on 127.0.0.1 from each other's context

So: https://github.com/heitorlessa/sam-local-python-hot-reloading/blob/master/users/users.py#L14

Pointed me at changing my connection code to:

const AWS = require('aws-sdk')
const awsRegion = process.env.AWS_REGION || 'eu-west-2'

let dynamoDbClient
const makeClient = () => {
  const options = {
    region: awsRegion
  }
  if(process.env.AWS_SAM_LOCAL) {
    options.endpoint = 'http://dynamodb:8000'
  }
  dynamoDbClient = new AWS.DynamoDB.DocumentClient(options)
  return dynamoDbClient
}

module.exports = {
  connect: () => dynamoDbClient || makeClient()
}

with the important lines being:

if(process.env.AWS_SAM_LOCAL) {
  options.endpoint = 'http://dynamodb:8000'
}

from the context of the SAM local docker container the dynamodb container is exposed via its name

My two startup commands ended up as:

docker run -d -v "$PWD":/dynamodb_local_db -p 8000:8000 --network lambda-local --name dynamodb cnadiminti/dynamodb-local

and

AWS_REGION=eu-west-2 sam local start-api --docker-network lambda-local

with the only change here being to give the dynamodb container a name

这篇关于在docker中将AWS SAM Local与dynamodb连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆