Доступ к DynamoDB в задании Golang Fargate - PullRequest
1 голос
/ 02 октября 2019

Я пытаюсь получить доступ к DynamoDB из моей задачи Fargate, которая написана на golang. И все, что я получаю, это тайм-аут. Чего мне не хватает?

Я использую шаблоны Cloudformation от AWS Labs (здесь) плюс роль задачи, которая обеспечивает полный доступ к DynamoDB. Это самый простой шаблон общедоступной подсети плюс Fargate.

Я пытался добавить конечную точку VPC, но это не имело никакого значения.

Запуск задачи на моей машине работает. Выполнение задачи Python (Flask), которая выполняет (более или менее) одно и то же, работает как локально, так и в AWS. Это та же самая установка, я только что изменил образ задачи.

Это код:

package main

import (
    "context"
    "fmt"
    "github.com/aws/aws-sdk-go-v2/aws/endpoints"
    "github.com/aws/aws-sdk-go-v2/aws/external"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/gin-gonic/gin"
    "time"
)

var db *dynamodb.Client

func init() {
    cfg, err := external.LoadDefaultAWSConfig()
    if err != nil {
        panic("unable to load SDK config, " + err.Error())
    }
    cfg.Region = endpoints.UsEast2RegionID
    db = dynamodb.New(cfg)
}

func main() {
    fmt.Println("go!")
    router := gin.New()
    router.Use(gin.Recovery())
    router.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"msg": "pong"}) })
    router.GET("/pong", func(c *gin.Context) {
        req := db.ListTablesRequest(&dynamodb.ListTablesInput{})
        ctx := context.Background()
        ctx, cancelFn := context.WithTimeout(ctx, time.Second*5)
        defer cancelFn()
        res, err := req.Send(ctx)
        if err != nil {
            c.JSON(400, gin.H{"msg": "Fail", "error": err.Error()})
            return
        }
        c.JSON(200, gin.H{"msg": fmt.Sprint(res)})
        return
    })
    router.Run()
}

Время ожидания:

helles:v2> curl  xyz.us-east-2.elb.amazonaws.com/pong
{"error":"RequestCanceled: request context canceled\ncaused by: context deadline exceeded","msg":"Fail"}

Ожидаемое:

helles:v2> curl 127.0.0.1:8080/pong
{"msg":"{\n  TableNames: [\"OneTable\",\"OtherTable\"]\n}"}

Python для сравнения:

#!/usr/bin/env python3
from flask import Flask
import boto3

dynamodb = boto3.client("dynamodb")
app = Flask(__name__)

@app.route("/ping")
def index():
    return "pong"

@app.route("/pong")
def pong():
    return dynamodb.list_tables()

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=8080)

Результат немного другой, с добавленными метаданными, но имена таблиц есть.

Спасибо

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Отвечая на мой собственный вопрос.

Проблема была с базовым образом Docker, который я использовал. Мой Dockerfile был:

FROM scratch
ADD ./build/api/api /
EXPOSE 8080
ENTRYPOINT ["/api"]

со статически связанным исполняемым файлом.

Изменение FROM scratch на FROM gcr.io/distroless/base заставило его работать.

Я предполагаю, что приложение /Клиент Dynamodb не смог разрешить адрес службы без отсутствующих частей из базового образа.

Спасибо @ Dude0001.

0 голосов
/ 02 октября 2019

Тайм-аут часто является проблемой сети. Вы проверили группы безопасности, используемые как задачей ECS, так и Dynamo DB. Необходимо убедиться, что у вас настроены правила для выхода из ECS и входа в DynamoDB на правильных портах.

Вы сказали, что настроили конечную точку для Dynamo в VPC. Из вашего OP не ясно, пытаетесь ли вы подключиться к частной конечной точке в частном VPC или пытаетесь подключиться к общедоступному Интернету. Если вы пытаетесь подключиться к общедоступному интернету, вам также необходимо убедиться, что ваша задача ECS находится в VPC, который имеет NAT-шлюз в общедоступный интернет. Похоже, вы пытаетесь подключиться через 127.0.0.1 или ELB DNS, чтобы подключиться к службе DynamoDB, что для меня не имеет смысла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...