Reputation: 99
I set up a DynamoDB table on a Kubernetes pod using LocalStack, which is exposed via a Kubernetes service. I'm trying to make a PutItem
request to this table using a service configured with the following DynamoDB client setup:
var client *dynamodb.Client
var err error
httpClient := awshttp.NewBuildableClient().WithTransportOptions(
func(tr *http.Transport) {
tr.IdleConnTimeout = cfg.DDB.IdleConnTimeout
}).WithTimeout(cfg.DDB.ReqTimeout)
ddbClientConfig, err = awsconfig.LoadDefaultConfig(
context.Background(),
awsconfig.WithRetryer(func() aws.Retryer {
return retry.NewStandard(func(options *retry.StandardOptions) {
options.MaxAttempts = cfg.DDB.MaxRetryCount
options.MaxBackoff = cfg.DDB.MaxBackoffDelay
})
}),
awsconfig.WithHTTPClient(httpClient),
)
ddbClient = dynamodb.NewFromConfig(clientCfg, func(o *dynamodb.Options) {
o.BaseEndpoint = "http://<localstack-service-name>.<kubernetes-namespace-name>.svc.cluster.local:91"
})
However, when making a PutItem
request using this DynamoDB client, I encounter the following error:
operation error DynamoDB: PutItem, exceeded maximum number of attempts, 3, https response error StatusCode: 503, RequestID: , api error UnknownError: UnknownError
I have explored several solutions, including:
aws-sdk-go-v2/dynamodb
version used in the client application.Despite making these changes, the issue persists. The table was set up in LocalStack with the following command:
awslocal dynamodb create-table \
--endpoint-url http://localhost:4566 \ # The Kubernetes service directs this localhost 4566 port to expose port 91
--region us-east-1 \
--table-name transaction-data \
--attribute-definitions \
AttributeName=key1,AttributeType=S \
AttributeName=key2,AttributeType=S \
--key-schema AttributeName=key1,KeyType=HASH \
AttributeName=key2,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
Interestingly, I am able to successfully execute a curl
request from the client pod to the LocalStack pod to put an item into the table. However, the PutItem
request made from the client application using the Go AWS SDK results in the error mentioned above.
I also attempted using the --sharedDb
parameter when starting the LocalStack container in my Dockerfile, and also setting it in my kubernetes deployment help chart but without success:
FROM localstack/localstack:latest
# Set environment variables for test AWS credentials
ENV AWS_ACCESS_KEY_ID=test_key_id
ENV AWS_SECRET_ACCESS_KEY=test_key
ENV AWS_REGION=us-east-1
COPY /execute-scripts/scripts/ /etc/localstack/init/ready.d/
RUN chmod +x /etc/localstack/init/ready.d/executeScript.sh
# Starting localstack process with --shareDb parameter
CMD ["localstack", "start", "--sharedDb"]
Can anyone help identify potential reasons for this error and suggest solutions?
UPDATE :
I also am passing in the --sharedDb flag to localstack container as env variables my kubernetes deployment helm chart, but I still see the DDB service in the localstack container is setting --sharedDb to false. Am I using --sharedDb parameter incorrectly?
env:
- name: JAVA_OPTS
value: "-Xms512m -Xmx512m"
- name: SERVICES
value: "dynamodb,s3,sqs"
- name: DEBUG
value: "1"
- name: LOG_LEVEL
value: "TRACE"
- name: LOG_FORMAT
value: "json"
args: ["start","-sharedDb","--async-response-enabled", "true", "--async-response-threads", "30", "--no-request-journal", "--jetty-acceptor-threads","10"]
localstack container logs
Initializing DynamoDB Local with the following configuration:
Port: 54919
InMemory: false
Version: 2.5.4
SharedDb: false
Update 2
I updated my application's DDB client to use the same access key values which the localstack docker container is using. This also did not help with the issue
client = dynamodb.NewFromConfig(clientCfg, func(o *dynamodb.Options) {
o.BaseEndpoint = &cfg.LocalStackEndpoint
o.Credentials = awsCredentials.NewStaticCredentialsProvider("test_key_id", "test_key", "")
})
Upvotes: 0
Views: 44
Reputation: 19873
When you create DynamoDB local pass the table -sharedDb
parameter which you can also set as an env variable for local stack.
Because you create the tables using CLI which has different access keys it creates a different database file to the one from your code. shareDb uses a shared database file so you can access it from any local code.
If you use the -sharedDb option, DynamoDB creates a single database file named shared-local-instance.db. Every program that connects to DynamoDB accesses this file. If you delete the file, you lose any data that you have stored in it.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html
In localstack that translates to the following:
DYNAMODB_SHARE_DB=1
CMD ["DYNAMODB_SHARE_DB=1","localstack", "start"]
Upvotes: 1