One of the most exciting frameworks I have ran into into recent years is Dapr (dapr.io) – distributed application runtime. Dapr is a cross technology runtime framework that supports applications in many and
The Dapr docs describe how to install Dapr locally and on a Kubernetes cluster. The documentation explicitly links to Azure, AWS and GCP documentation but fails to mention OKE on OCI. So in this article I will show how to get going with Dapr on OKE. In total honesty: Dapr is Kubernetes enabled – but not specifically prepared for AKS, EKS or GCKE so installation on OKE is exactly the same as installation on any other Kubernetes cluster instance.
To first get an OKE instance – if you do not have one yet – you could use my article on that subject:Getting started (again) with Kubernetes on Oracle Cloud.
Once the OKE cluster is up and running,and my local Kubectl context is set to right cluster instance:
installing Dapr on the cluster is as simple as:
1. install Dapr locally (see: Install Dapr CLI)
2. Run dapr init –k
It will take a few minutes to get all K8S resources set up on the cluster; the default namespace is dapr-system. Once the CLI tells us about success, we can inspect the resources that are created for Dapr:
and in the Dashboard:
The fun starts of course when I deploy “a workload” – one or more Pods with contains that use the Dapr facilities.
Rollout the Distributed Calculator Daprized Microservice Application
The distributed calculator application consists of five independent micro services – in five different technologies – that together produce a user experience around basic arithmetic. None of the micro services know about the others and even the UI (the React application) has no endpoint details for any of the services.
In order to deploy this Dapr=ized application to my OKE cluster that has Dapr enabled, I go through these steps:
1. Git Clone the repository at https://github.com/dapr/quickstarts
2. Install Helm (instructions for installing Helm)
and follow these instructions to set up Redis (state store) using Helm: https://docs.dapr.io/getting-started/configure-state-pubsub/
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install redis bitnami/redis
This creates an instance of a Redis Cache.
Create the yaml files as specified in the Dapr quickstart docs and apply to create the Dapr components – both pubsub and state-store.
3. Navigate to the deploy directory in directory: cd quickstarts/distributed-calculator/deploy
Apply all manifest files in thus directory – using: kubectl apply –f .
It takes a fairly short time (in my case) for the resources to be created:
creating Dapr resources implicitly means creating Kubernetes resources – such as Pods, Deployments, Servcies and more. In the K8S Dashboard, my initial results look pretty good:
Each Pod as expected consists of two Containers – one for the App itself and one for the Dapr Sidecar, the personal assistant for the App.
For example the Pod for MultiplyApp – with the container for the Python application that does the multiplication and the Dapr sidecar that represents it – in outbound and inbound direction
If you take a look at the yaml file for the deployment of the multiplyapp what might strike you is that no service is defined in the deployment.
Yet after deployment there is a service all the same, as a result of the side car injector. This service accepts and intercepts requests targeted at the multiply-app Pod. These requests typically come in from other Dapr side cars. (my people talk to your people) :
See details about the Dapr side car on Kubernetes.
Note that for the Calculator Frontend App Pod there will be two services – the one defined for the App itself and the service injected by the Dapr injector.
I have started the dapr dashboard: dapr dashboard –k. The dashboard – still using the kubectl proxcy command that allows me to run the Kubernetes Dashboard – can be opened locally in my browser at: http://localhost:8080/.
Two Dapr components have been configured – components of types pubsub and statestore, both implemented using redis:
I can find the same information through the CLI:
Now to access the React web application, I can use the Public IP that the calculator-front-end service was assigned (because of its type LoadBalancer):
or I can use Port Forwarding in my local terminal leveraging the kubeconfig context for the OKE instance on OCI:
kubectl port-forward service/calculator-front-end 8000:80
and access the calculator locally on port 8000: localhost:8000.
even though it is still very much running on OKE.
When I open the Browser Console Window I can see a log of the services invoked:
I also see an indication of state being persisted (in the state store i.e. in Redis). When I refresh the browser or open a new browser window, I will get that state rehydrated and 72 will show up once more.
I can also access the individual Daprized applications running on OKE, using the CLI:
curl -s http://localhost:8000/calculate/divide -H Content-Type:application/json –data ‘{“operandOne”:34, “operandTwo”:26}’
curl -s http://localhost:8000/calculate/multiply -H Content-Type:application/json –data ‘{“operandOne”:34, “operandTwo”:26}’
Using curl -s http://localhost:8000/state on the local command line (with port forwarding still active) I can inspect the contents of the state store:
To open a command line terminal on the application container for the calculator front end Pod:
kubectl exec –stdin –tty calculator-front-end-5bb947dfcf-w8hfm — /bin/sh
Once inside this container, I can inspect for example the hosts file and the environment variable DAPR_HTTP_PORT that the side car injection has set up in the container:
Using wget I can make an HTTP Post request to the Dapr side car running at port 3500. Note that I only know the Dapr side car’s port as well as the app id for the services I want to invoke and of course the name of the method (add) and the expected payload:
wget localhost:3500/v1.0/invoke/addapp/method/add –post-data='{“OperandOne”:”34″, “OperandTwo”:”12″}’
Also using wget I can inspect the contents of the statestore :
wget http://localhost:3500/v1.0/state/statestore/calculatorState
where calculatorState is the key used by the Calculation application to store its state. See the Dapr Docs for more examples of invoking the Dapr APIs.
Using wget http://localhost:3500/v1.0/state/statestore –post-data ‘[{“key”:”calculatorState”, “value”: {“total”: “42”}}]’ –S I can manipulate the contents of the statestore.
If I now open the front end again in a new browser window, I would expect the initial content – value 42 – to be retrieved from the cache:
Resources
Blog article – Initialize an OKE cluster instance – Getting started (again) with Kubernetes on Oracle Cloud
Dapr Docs – install Dapr locally (see: Install Dapr CLI)
Dapr docs – Deploy Dapr on a Kubernetes cluster – https://docs.dapr.io/operations/hosting/kubernetes/kubernetes-deploy/
Quickstart – Distrbuted Calculator (combine React with Go, Python, .NET, Node) – https://github.com/dapr/quickstarts/tree/v1.5.0/distributed-calculator
Dapr Dashboard – https://github.com/dapr/dashboard
Maarten Mulders on Dapr State Store – https://maarten.mulders.it/2021/09/getting-to-know-dapr/
Kubernetes – get shell into running container – https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/
Docs for wget – http://www.gnu.org/software/wget/manual/html_node/index.html#SEC_Contents
Dapr Docs – invoking Dapr APIs
Ambassador Pattern – https://docs.microsoft.com/en-us/azure/architecture/patterns/ambassador
Dapr Docs – details about the Dapr side car on Kubernetes.