Zero to Corda 5 in 10 minutes or less

April 17, 2023

This post has been last updated on December 19, 2023 after the release of Corda 5.1.

By: David Currie – Principal Software Engineer at R3

With the release of Corda 5, it has never been easier to get Corda up and running on Kubernetes. In doing so, you can see for yourself the new distributed worker architecture covered in James Higgs’ post on high availability in Corda 5. In this blog post, we’ll describe one method that should take less than 10 minutes. This assumes that you already have a Kubernetes cluster but don’t worry if you don’t, we can help you there too. The post will also give you an update on support for ARM that Simon covered in a previous post.

Before we get started though, a reminder that you don’t need to deploy Corda 5 to Kubernetes in order to write and test a CorDapp. The CorDapp Standard Development Environment allows you to run Corda as a single-process JVM (plus Postgres database) for testing your applications. The approach described in this blog is only if you want to see what a multi-process deployment of Corda on Kubernetes looks like.

Photo by Joseph Barrientos on Unsplash

Kubernetes Prerequisites

To start with, we need a Kubernetes cluster to deploy to, and the kubectl and helm command line tools.

The only requirements for the Kubernetes cluster are that it is running Kubernetes 1.23 or later and, for this deployment, has at least 6 CPUs and 8Gi RAM. Beyond that, it could be a single-node cluster running on your laptop (for example Docker Desktop, minikube, k3d, microk8s, or kind), or it could be a multi-node cluster in your favourite cloud provider (we currently test on AWS and Azure).

If you don’t already have a Kubernetes cluster, then minikube is a good option for deployment on your local machine with platform coverage for Linux, Windows, and macOS across both AMD and ARM. Follow the instructions to download/install minikube and then start a cluster as follows:

minikube start --cpus=6 --memory=8G

You’ll also need the Kubernetes CLI, kubectl. You can either follow the install instructions or, if you’re using minikube, you can have it pull the correct version for you by setting up the following alias:

alias kubectl="minikube kubectl --"

Lastly, as covered in a previous blog post, we use the Helm package manager to deploy Corda. Follow the install instructions for the helm CLI if you don’t already have it. You should ensure that you have Helm 3.9.4 or newer:

helm version

You now have an empty Kubernetes cluster and the tools necessary to install Corda and its prerequisites:

Install Postgres and Kafka

Corda 5 uses Postgres (to store state and configuration) and Kafka (as a messaging bus for communication within the cluster). These prerequisites could be met by a managed service, such as RDS for Postgres in AWS, and MSK or Confluent Cloud for Kafka. If you don’t have previous experience running Postgres or Kafka, we’d highly recommend this approach for production deployments. For the purposes of this post though, we’re going to deploy Postgres and Kafka to run on Kubernetes as a universal approach that doesn’t introduce any additional cloud spend.

In his blog post on ARM support, Simon Johnson covered an issue with the Bitnami Helm charts that we were using to deploy Postgres and Kafka. The Docker images they deployed were not built to run on ARM. As a consequence, we created a new Helm chart to deploy a minimal configuration of Postgres and Kafka for development use that runs the official Docker image for Postgres and the Kafka image from Confluent, both of which are built for AMD and ARM. That corda-dev-prereqs Helm chart is packaged up and made available via Docker Hub.

Assuming that your current Kubernetes context is targeting the cluster you wish to deploy to, you can create a namespace called corda and deploy Postgres and Kafka into it using the following command:

helm install prereqs --namespace corda --create-namespace \
  oci://registry-1.docker.io/corda/corda-dev-prereqs \
  --timeout 10m --wait

The ten-minute timeout is only to give it sufficient time to pull down the container images from Docker Hub on a slow connection. Once pulled, it should be nearer to ten seconds for the containers to actually start and reach the ready state.

You now have Kafka and Postgres installed in your Kubernetes cluster:

After we had created this chart, Bitnami announced that they had started building images for ARM. We’re still going to continue using our new corda-dev-prereqs chart for development use as it has a couple of additional benefits: it uses Kafka KRaft so there is no need to run ZooKeeper and it generates credentials for multiple users in a way that they can be directly consumed by the Corda Helm chart.

Install Corda

With the groundwork all in place, installing Corda itself is just a single command:

helm install corda oci://registry-1.docker.io/corda/corda \ 
--version 5.1.0 --namespace corda \ 
--values https://gist.githubusercontent.com/davidcurrie/e9c090bdee99ea0a8412fc228218a0e0/raw/723a4ad8886853b07339288c85b86ef8fcb57c1e/corda-prereqs.yaml \ 
--timeout 10m –-wait

This installs the latest version of Corda that was available at the time of writing: 5.0.1 We extend the default timeout again as this time not only do we have to pull the Docker images, but the installation also sets up the Kafka topics and the Postgres schema/tables before starting the Corda workers and performs some final configuration of the Corda RBAC roles.

If everything worked successfully, you should see three completed jobs and a set of Corda workers in ready state, for example:

$ kubectl get pods --namespace corda
NAME                                            READY   STATUS      RESTARTS   AGE
corda-create-topics-x8smj                       0/1     Completed   0          8m32s
corda-crypto-worker-57957445cc-fzdww            1/1     Running     0          6m13s
corda-db-worker-7b559745dd-mhngn                1/1     Running     0          6m13s
corda-flow-mapper-worker-584f487884-cgf9t       1/1     Running     0          6m12s
corda-flow-worker-747757676c-h44xh              1/1     Running     0          6m13s
corda-membership-worker-5bb76bb9fd-sglm4        1/1     Running     0          6m13s
corda-p2p-gateway-worker-74875f9cdb-zmmwg       1/1     Running     0          6m13s
corda-p2p-link-manager-worker-98df99b66-wxnxv   1/1     Running     0          6m13s
corda-persistence-worker-9fd9798c6-ksb7x        1/1     Running     0          6m13s
corda-preinstall-checks-bdlkj                   0/1     Completed   0          10m
corda-rest-worker-65bd5477fb-xcq6c              1/1     Running     0          6m12s
corda-setup-db-v5q77                            0/1     Completed   0          8m11s
corda-setup-rbac-gcftc                          0/1     Completed   0          16s
corda-token-selection-worker-8d6f76d48-mpdf9    1/1     Running     0          6m12s
corda-uniqueness-worker-944bdfdd4-wpfhp         1/1     Running     0          6m13s
corda-verification-worker-87bbdc68b-xn6gh       1/1     Running     0          6m13s
prereqs-kafka-0                                 1/1     Running     0          15m
prereqs-postgres-7f94fcc4c4-s26f6               1/1     Running     0          15m

If you don’t see the Corda workers running, take a look at the Cluster Health section of the Corda documentation for suggestions on how to troubleshoot common problems.

For those interested in the details, the corda-prereqs.yaml gist contains the information needed to tie together the Corda installation with the Kafka and Postgres installation in the previous step. For example, the server addresses for Kafka and Postgres, along with the details of the secrets containing the credentials and certificates. Given that we’ve only configured a single Kafka broker, it also ensures Corda only attempts to create a single replica for each topic. Lastly, it switches the default JSON format logging to text format which is more readable if you’re not pushing the logs into a logging stack. For an overview of some of the more commonly used overrides, see the documentation.

You now have Corda up and running on Kubernetes, using Kafka and Postgres instances also deployed to the same Kubernetes cluster:

Verify Access to the Corda REST API

At this point, you have a fully functional Corda cluster and can go on to use the Corda REST API to install CorDapps, create virtual nodes, set up networks, and even peer together multiple clusters. That’s all beyond the scope of this post but, just to give you a warm fuzzy feeling that we have a working REST API, here’s a small snippet to test it out:

kubectl port-forward --namespace corda deployment/corda-rest-worker 8888 &
CORDA_USERNAME=$(kubectl get secret corda-rest-api-admin \
  --namespace corda -o go-template='{{ .data.username | base64decode }}')
CORDA_PASSWORD=$(kubectl get secret corda-rest-api-admin \
  --namespace corda -o go-template='{{ .data.password | base64decode }}')
curl -k -u $CORDA_USERNAME:$CORDA_PASSWORD -X POST \
  https://localhost:8888/api/v1/hello\?addressee\=World

If you get Hello World! (from admin) back, congratulations, you have a working cluster! You’re good to start exploring the other operations available to you in the Corda documentation.

Wrapping Up

Finally, when you’re all done trying it out, because we installed everything into a single Kubernetes namespace, you can remove it all with a single command:

kubectl delete namespace corda

There was a lot of text above but getting to a running Corda really did just involve running two commands: one to install Postgres and Kafka, the other to install Corda and, even if it took you more than ten minutes the first time through, I’m positive it will be less on the second attempt!

Share: