Using a key value store
Categories:
Spin applications can utilize a standardized API for persisting data in a key value store. The default key value store in Spin is an SQLite database, which is great for quickly utilizing non-relational local storage without any infrastructure set-up. However, this solution may not be preferable for an app running in the context of SpinKube, where apps are often scaled beyond just one replica.
Thankfully, Spin supports configuring an application with an external key value provider. External providers include Redis or Valkey and Azure Cosmos DB.
Prerequisites
To follow along with this tutorial, you’ll need:
- A Kubernetes cluster running SpinKube. See the Installation guides for more information.
- The kubectl CLI
- The spin CLI
Build and publish the Spin application
For this tutorial, we’ll use a Spin key/value application written with the Go SDK. The application serves a CRUD (Create, Read, Update, Delete) API for managing key/value pairs.
First, clone the repository locally and navigate to the examples/key-value
directory:
git clone git@github.com:fermyon/spin-go-sdk.git
cd examples/key-value
Now, build and push the application to a registry you have access to. Here we’ll use ttl.sh:
export IMAGE_NAME=ttl.sh/$(uuidgen):1h
spin build
spin registry push ${IMAGE_NAME}
Configure an external key value provider
Since we have access to a Kubernetes cluster already running SpinKube, we’ll choose
Valkey for our key value provider and install this provider via Bitnami’s
Valkey Helm chart. Valkey is swappable
for Redis in Spin, though note we do need to supply a URL using the redis://
protocol rather than
valkey://
.
helm install valkey --namespace valkey --create-namespace oci://registry-1.docker.io/bitnamicharts/valkey
As mentioned in the notes shown after successful installation, be sure to capture the valkey password for use later:
export VALKEY_PASSWORD=$(kubectl get secret --namespace valkey valkey -o jsonpath="{.data.valkey-password}" | base64 -d)
Create a Kubernetes Secret for the Valkey URL
The runtime configuration will require the Valkey URL so that it can connect to this provider. As this URL contains the sensitive password string, we will create it as a Secret resource in Kubernetes:
kubectl create secret generic kv-secret --from-literal=valkey-url="redis://:${VALKEY_PASSWORD}@valkey-master.valkey.svc.cluster.local:6379"
Prepare the SpinApp manifest
You’re now ready to assemble the SpinApp custom resource manifest for this application.
- All of the key value config is set under
spec.runtimeConfig.keyValueStores
. See the keyValueStores reference guide for more details. - Here we configure the
default
store to use theredis
provider type and underoptions
supply the Valkey URL (via its Kubernetes secret)
Plug the $IMAGE_NAME
and $DB_URL
values into the manifest below and save as spinapp.yaml
:
apiVersion: core.spinkube.dev/v1alpha1
kind: SpinApp
metadata:
name: kv-app
spec:
image: "$IMAGE_NAME"
replicas: 1
executor: containerd-shim-spin
runtimeConfig:
keyValueStores:
- name: "default"
type: "redis"
options:
- name: "url"
valueFrom:
secretKeyRef:
name: "kv-secret"
key: "valkey-url"
Create the SpinApp
Apply the resource manifest to your Kubernetes cluster:
kubectl apply -f spinapp.yaml
The Spin Operator will handle the creation of the underlying Kubernetes resources on your behalf.
Test the application
Now you are ready to test the application and verify connectivity and key value storage to the configured provider.
Configure port forwarding from your local machine to the corresponding Kubernetes Service
:
kubectl port-forward services/kv-app 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
When port forwarding is established, you can send HTTP requests to the application from within an additional terminal session. Here are a few examples to get you started.
Create a test
key with value ok!
:
$ curl -i -X POST -d "ok!" localhost:8080/test
HTTP/1.1 200 OK
content-length: 0
date: Mon, 29 Jul 2024 19:58:14 GMT
Get the value for the test
key:
$ curl -i -X GET localhost:8080/test
HTTP/1.1 200 OK
content-length: 3
date: Mon, 29 Jul 2024 19:58:39 GMT
ok!
Delete the value for the test
key:
$ curl -i -X DELETE localhost:8080/test
HTTP/1.1 200 OK
content-length: 0
date: Mon, 29 Jul 2024 19:59:18 GMT
Attempt to get the value for the test
key:
$ curl -i -X GET localhost:8080/test
HTTP/1.1 500 Internal Server Error
content-type: text/plain; charset=utf-8
x-content-type-options: nosniff
content-length: 12
date: Mon, 29 Jul 2024 19:59:44 GMT
no such key
Feedback
Was this page helpful?
Glad to hear it!
Sorry to hear that. Please tell us how we can improve.