Kind で KEDA + Localstack(SQS) が可能になっていた
概要
EKS 上で動く、API からキューに情報を積み、SQS をトリガーとしてコンテナを起動させる非同期処理を開発していたのですが、ローカルで完結する環境の構築をしました。
これを実現するために KEDA を利用していたのですが、v2.8 までは LocalStack へアクセスする方法がなく、やむなく AWS 上に作成した SQS を利用していました。
しかし、ローカルで完結しないことに違和感を感じていた中、ふと調べてみると LocalStack を利用可能な変更が マージ されていたので、さっそく試してみました。
LocalStack の起動
Docker Compose を利用しました。手軽にまずは起動したかったためです。
version: '3.8'
services:
localstack:
image: localstack/localstack:1.3.1
environment:
- SERVICES=sqs,s3
- DEFAULT_REGION=ap-northeast-1
volumes:
- ./docker-entrypoint-init.d:/docker-entrypoint-initaws.d
- localstack-data:/var/lib/localstack:delegated
ports:
- 4566:4566
volumes:
localstack-data:
起動時に Queue も作成したかったため初期化スクリプトを利用しています。
#!/bin/bash
awslocal sqs create-queue --queue-name localstack.fifo --attributes FifoQueue=true,ContentBasedDeduplication=true
Queue の名前は http://{LocalStack の参照名}:4566/000000000000/localstack.fifo
となります。
API から Enqueue
Go で実装しました。
func Enqueue() () {
sess, err := session.NewSession(&aws.Config{
// ホストマシーンの場合は http://localhost:4566
// Kind の場合は http://host.docker.internal:4566
// Docker Compose の場合は下記
Endpoint: "http://localstack:4566",
})
if err != nil {
// do something
}
svc := sqs.New(sess)
_, err = svc.SendMessage(&sqs.SendMessageInput{
QueueUrl: aws.String("http://localstack:4566/000000000000/localstack.fifo")
// ...
})
if err != nil {
// do something
}
}
コンテナの実行環境でダミーの認証情報を環境変数をセットすれば良いだけなので、AWS 上の SQS を参照するより複雑さがなくなります。
export AWS_ACCESS_KEY_ID="dummy"
export AWS_SECRET_ACCESS_KEY="dummy"
export AWS_SESSION_TOKEN="dummy"
KEDA でポーリング
ScaledJob の定義をします。ScaledObject でも設定は大きく変わらないと思います。
apiVersion: v1
kind: Secret
metadata:
name: aws-secrets
data:
AWS_ACCESS_KEY_ID: ZHVtbXk= # dummy
AWS_SECRET_ACCESS_KEY: ZHVtbXk= # dummy
AWS_DEFAULT_REGION: YXAtbm9ydGhlYXN0LTE= # ap-northeast-1
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-trigger-auth-aws-credentials
spec:
secretTargetRef:
- parameter: awsAccessKeyID
name: aws-secrets
key: AWS_ACCESS_KEY_ID
- parameter: awsSecretAccessKey
name: aws-secrets
key: AWS_SECRET_ACCESS_KEY
---
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: scaled-job
labels:
keda: sqs
spec:
jobTargetRef:
completions: 1
backoffLimit: 2
template:
metadata:
labels:
keda: sqs
spec:
containers:
- name: job
image: job:latest
envFrom:
- secretRef:
name: job
restartPolicy: Never
pollingInterval: 30
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
triggers:
- type: aws-sqs-queue
authenticationRef:
name: keda-trigger-auth-aws-credentials
metadata:
queueURL: http://host.docker.internal:4566/000000000000/localstack.fifo
queueLength: "5"
awsRegion: "ap-northeast-1"
awsEndpoint: "http://host.docker.internal:4566"
KEDA のデプロイは Kustomize でさくっとできます。
KEDA によりスケールされたコンテナで SQS から Dequeue や Delete ができるように、secretGenerator
で認証情報を作成しコンテナの環境変数にセットします。
resources:
- https://github.com/kedacore/keda/releases/download/v2.9.3/keda-2.9.3.yaml
- scalejob.yaml
secretGenerator:
- literals:
- AWS_ACCESS_KEY_ID=dummy
- AWS_SECRET_ACCESS_KEY=dummy
- AWS_SESSION_TOKEN=dummy
name: job
ExternalName で LocalStack の CNAME を作成すると http://localstack:4566
で名前解決できるので統一感がでます。
apiVersion: v1
kind: Service
metadata:
name: localstack
spec:
externalName: host.docker.internal
type: ExternalName
まとめ
ローカル環境で動作確認が完結するので良い感じです!
AWS 上に SQS を構築すると費用も発生しますし、保守の手間や複数名での開発でのコンフリクトに煩わされる可能性がありますが、その懸念も払拭できます!
ぜひお試しを!
Discussion