DEV Community

Thang Chung
Thang Chung

Posted on

Deploying Distributed Apps (Spin + Dapr) on SpinKube (AKS)

Introduction

In the last part, we walk through the journey of how to build and run Spin Apps in a local environment with the support of .NET Aspire. If you haven't read it, I recommend you to check it out at Part 1: Orchestrating Distributed Apps (Spin/Rust and .NET/C#) with .NET Aspire/Dapr.

In this part, we will continue to deploy the apps in the previous part using SpinKube (Azure Kubernetes Service - AKS). To make it more easy to follow, I draw the deployment model below.

Deployment model

Source code: https://github.com/thangchung/dapr-labs/tree/main/aspire

Prerequisites

az version

{
  "azure-cli": "2.67.0",
  "azure-cli-core": "2.67.0",
  "azure-cli-telemetry": "1.1.0",
  "extensions": {}
}
Enter fullscreen mode Exit fullscreen mode
dapr version

CLI version: 1.14.1
Runtime version: 1.14.4
Enter fullscreen mode Exit fullscreen mode
cargo --version
cargo 1.83.0 (5ffbef321 2024-10-29)

spin --version
spin 3.1.1 (aa919ce 2024-12-20)
Enter fullscreen mode Exit fullscreen mode
  • .NET 9 CLI
dotnet --list-sdks
9.0.100 [C:\Program Files\dotnet\sdk]
Enter fullscreen mode Exit fullscreen mode
kubectl version

Client Version: v1.32.0
Kustomize Version: v5.5.0
Enter fullscreen mode Exit fullscreen mode
  • helm CLI
helm version

version.BuildInfo{Version:"v3.16.1", GitCommit:"5a5449dc42be07001fd5771d56429132984ab3ab", GitTreeState:"clean", GoVersion:"go1.22.7"}
Enter fullscreen mode Exit fullscreen mode

Provisioning AKS cluster

Follow the guidance at Deploy an Azure Kubernetes Service (AKS) cluster using Azure CLI to create the AKS cluster. Let's say its name is spinkube-azure-globalazure24

Provisioning SpinKube components

In the past, to make Spin work on the AKS cluster, we needed to install several components and did that manually. Its work might be hard and error-prone. Now, the Fermyon team has introduced SpinKube-Azure, it wraps every component into just one Helm chart, so we can run only 1 command to install those components into AKS as below.

git clone git@github.com:spinframework/azure.git
cd azure
helm install --wait spinkube .
Enter fullscreen mode Exit fullscreen mode

Let's wait a second, then we are ready to go.

Provisioning Dapr components

If you remember in the previous part, we used RabbitMQ for Dapr's pub/sub. So let's work on it on AKS.

RabbitMQ cluster provisioning

helm install rabbit --set service.type=NodePort stable/rabbitmq

# Because of the demo, then we get it password and use it for the next step, not store it in the KeyVault.
echo $(kubectl get secret --namespace rabbit mu-rabbit-rabbitmq -o jsonpath="{.data.rabbitmq-password}" | base64 --decode)
Enter fullscreen mode Exit fullscreen mode

Ref: https://gist.github.com/enesusta/e2ac956104dc0fa4130c795e7270bfc2

Dapr's RabbitMQ pubsub component

Create a Dapr's pub-sub component with the RabbitMQ configuration above.

kubectl apply -f - <<EOF
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
  namespace: default
spec:
  type: pubsub.rabbitmq
  version: v1
  metadata:
  - name: protocol
    value: amqp
  - name: hostname
    value: rabbit-rabbitmq
  - name: username
    value: user
  - name: password
    value: <password above step>
EOF
Enter fullscreen mode Exit fullscreen mode

Scaffolding SpinApp and .NET app

  • Spin App
spin registry push ttl.sh/thangchung-test-spin:1h --build
Enter fullscreen mode Exit fullscreen mode
  • .NET App
dotnet publish ./WebApp/WebApp.csproj --os linux --arch x64 /t:PublishContainer -c Release
Enter fullscreen mode Exit fullscreen mode

Deploy our apps into AKS

kubectl apply -f - <<EOF
apiVersion: core.spinkube.dev/v1alpha1
kind: SpinApp
metadata:
  name: test-spin
spec:
  image: "ttl.sh/thangchung-test-spin:1h"
  executor: containerd-shim-spin
  replicas: 1
  podAnnotations:
    dapr.io/enabled: "true"
    dapr.io/app-id: "test-spin"
    dapr.io/app-port: "80"
    dapr.io/enable-api-logging: "true"
  variables:
  - name: dapr_url
    value: http://localhost:3500
  - name: loglevel
    value: info
EOF
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "webapp"
        dapr.io/app-port: "8080"
        dapr.io/enable-api-logging: "true"
    spec:
      containers:
      - name: webapp
        image: ttl.sh/thangchung-webapp:1h
        imagePullPolicy: Always
        env:
        - name: TestSpinApp
          value: "test-spin"
        resources:
          # limit the resources to 128Mi of memory and 100m of CPU
          limits:
            cpu: 100m
            memory: 128Mi
          requests:
            cpu: 100m
            memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 8080
  selector:
    app: webapp
EOF
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: store-front
spec:
  ingressClassName: webapprouting.kubernetes.azure.com
  rules:
  - http:
      paths:
      - backend:
          service:
            name: webapp
            port:
              number: 5000
        path: /
        pathType: Prefix
EOF
Enter fullscreen mode Exit fullscreen mode

Notes: Make sure you enable approuting in AKS, by using:

az aks approuting enable --resource-group globalazure24 --name spinkube-azure-globalazure24

AKS Dashboard

AKS dashboard

Running the distributed apps

  1. Port forward the web-app
kubectl port-forward services/webapp 5000:5000 -n default
Enter fullscreen mode Exit fullscreen mode

Notes: if you use the ingress setup above, then you can curl directly into the public IP:

kubectl get ingress # it will show the public IP
  1. Create some traffic
curl http://localhost:5000/item-types
curl -d '{}' http://localhost:5000/ping
Enter fullscreen mode Exit fullscreen mode
  1. Tail the test-spin-app logs

test-spin app logs

  1. Tail the web app logs

webapp logs

Conclusion

This post shows you that we can deploy and run hybrid apps (Spin App and .NET App) with Dapr in place. It is a good start to build up more complex apps in the next posts which I will work on. Thanks for reading it through. Happy deploying ^_^

Top comments (0)