Skip to main content

Section A: Installing Kratix

This is Part 1 of a series illustrating how Kratix works.
๐Ÿ‘‰๐Ÿพ Next: Install a Kratix Promise


In this tutorial, you will

What is Kratix?โ€‹

Kratix is a framework used by platform teams to build custom platforms tailored to their organisation.

Using Kratix to build your platform allows you toโ€‹

  • use GitOps workflows and familiar Kubernetes-native constructs.
  • co-create capabilities by providing a clear contract between application and platform teams through the definition and creation of โ€œPromisesโ€. This tutorial will talk more about Kratix Promises in the next step.
  • create a flexible platform by providing your own paved paths as Promises.
  • evolve your platform easily as your business needs change.
  • start small on a laptop and expand to multi-team, multi-cluster, multi-region, and multi-cloud with a consistent API everywhere.

Providing a Kratix-built platform allows your users toโ€‹

  • discover available services that are already fit-for-purpose.
  • consume services on demand using standard Kubernetes APIs.
  • move focus away from infrastructure toward adding product value into your platform.

Hands on: Installing Kratixโ€‹

Before continuing, be sure to go back to the prerequisites and follow the guide if you haven't done so already.

You should also make sure you are currently in the kratix directory and have the following environment variables set:

export PLATFORM="kind-platform"
export WORKER="kind-worker"

This guide will go through the following steps:

  1. Installing Kratix
  2. Create the Kratix State Store

Install Kratixโ€‹

To install Kratix, all you need is the Kratix distribution file.

Run the command below to deploy Kratix on the platform cluster:

kubectl --context $PLATFORM apply --filename https://github.com/syntasso/kratix/releases/latest/download/kratix.yaml

This command will create a Kratix deployment (in the kratix-platform-system namespace). It will also install all the APIs (as Kubernetes CRDs) that Kratix needs.

Verify that the Kratix CRDs are available:

kubectl --context $PLATFORM get crds | grep kratix

The above command will give an output similar to:

bucketstatestores.platform.kratix.io   2023-01-22T11:53:15Z
destinations.platform.kratix.io 2023-01-22T11:53:15Z
gitstatestores.platform.kratix.io 2023-01-22T11:53:15Z
promisereleases.platform.kratix.io 2023-01-22T11:53:15Z
promises.platform.kratix.io 2023-01-22T11:53:15Z
workplacements.platform.kratix.io 2023-01-22T11:53:15Z
works.platform.kratix.io 2023-01-22T11:53:15Z
What are CRDs?

A Custom Resource (CR) is an extension of the Kubernetes API that is not necessarily available in a default Kubernetes installation. It represents a customisation of a particular Kubernetes installation.

A Custom Resource Definition (CRD) is the object you create to teach your Kubernetes cluster about this new API.

Kratix comes with multiple API extensions (CRDs), as you see above.

Check the Kubernetes documentation for further details on Custom Resources and Custom Resources Definition.

Verify the Kratix deployment:

kubectl --context $PLATFORM get deployments --namespace kratix-platform-system

The above command will give an output similar to:

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
kratix-platform-controller-manager 1/1 1 1 1h

You can now tell Kratix which repositories it will use to deploy and manage the workloads.

Create the Kratix State Storeโ€‹

The State Store represents the various backing storage options to which Kratix can write. When registering a worker cluster with Kratix, you will need to specify the state store you intend to use. Kratix will then write to the specified state store when scheduling workloads for deployment on that cluster.

Create a new State Store that points to the MinIO bucket created in the prerequisites:

cat << EOF | kubectl --context $PLATFORM apply -f -
apiVersion: platform.kratix.io/v1alpha1
kind: BucketStateStore
metadata:
name: default
spec:
endpoint: minio.kratix-platform-system.svc.cluster.local
insecure: true
bucketName: kratix
secretRef:
name: minio-credentials
namespace: default
EOF

The above command will give an output similar to:

bucketstatestore.platform.kratix.io/default created
More on the Kratix State Store

The State Store document contains the configuration needed to access the actual backing storage.

In the example above, you created a new BucketStateStore as a MinIO bucket has been provisioned for storage, but you could use any other S3-compatible storage like Amazon S3 and Google Cloud Storage.

The spec includes the details needed to access that specific kind of State Store. On the example above, you configured the endpoint to the cluster address of the MinIO server you deployed on the platform cluster. Since MinIO is running in-cluster and without TLS enabled, it is necessary to set insecure to true.

You can see the MinIO service on the kratix-platform-system:

kubectl --context $PLATFORM --namespace kratix-platform-system get service minio

The above command will give an output similar to:

NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
minio NodePort 10.96.96.166 <none> 80:31337/TCP 17h

bucketName refers to the actual bucket on the MinIO server. The bucket needs to exist prior to Kratix trying to use it. As a part of setting up MinIO you ran a Job to create the base kratix bucket.

Finally, secretRef points to a secret, in the same namespace as the State Store, containing the credentials to access the store. For BucketStateStore, Kratix expects to find an accessKeyID and a secretAccessKey when resolving the secret. As part of the MinIO deployment, you also created the necessary secret:

kubectl --context $PLATFORM describe secret minio-credentials

The above command will give an output similar to:

Name:         minio-credentials
Namespace: default
Labels: <none>
Annotations: <none>

Type: Opaque

Data
====
accessKeyID: 10 bytes
secretAccessKey: 10 bytes

For further details on State Stores, check the State Store documentation page

At this point, your environment looks like this (with a few components omitted for clarity):

Deployed resources with State Store
Current environment: with Bucket State Store

Although Kratix now knows about the State Store, it's not currently aware of any place that the workloads can actually run: there's no Destination registered with the platform cluster.

Register the Worker cluster as a Destinationโ€‹

In Kratix terms, a Destination is any system converging on the state declared by Kratix.

You have already created a worker cluster as part of the prerequisites. You will now register this cluster as a Destination.

info

Note that the order of operations here is not important; you could have registered the worker as a Destination first, and then created the worker cluster. Kratix would have scheduled to the State Store path representing the worker cluster, and the state would eventually be applied to a worker.

It's important to note that Kratix makes no assumptions about the Destinations themselves. Although Destinations are often Kubernetes clusters, they may be any system that can interpret whatever state is being declared as desired.

For example, you may write a Promise that tells Kratix to declare Terraform plans as desired state, and a Destination may be a system applying these plans as they are written to the State Store.

To register the worker cluster, create a Destination object on your platform cluster:

cat <<EOF | kubectl --context $PLATFORM apply --filename -
apiVersion: platform.kratix.io/v1alpha1
kind: Destination
metadata:
name: worker-cluster
labels:
environment: dev
spec:
stateStoreRef:
name: default
kind: BucketStateStore
EOF

The above command will give an output similar to:

destinations.platform.kratix.io/worker-cluster created
Destinations in detail

The Kratix Destination resource is the representation of a system where workloads can be scheduled to. Those systems are usually other Kubernetes clusters, but can be any system that can interpret the declared state.

The only required field is spec.stateStoreRef, which contains a reference to a State Store present in the platform. In this example, it points to the default object you created on the previous step. The spec.StateStoreRef.kind specifies the kind of State Store being used by this Destination.

This means that different Destinations can use different backing storage. For example, you can have a set of Destinations backed by Git, while another set of Destinations can be backed by a Bucket. Further configuration options pertaining to paths are also available both in the State Store and the Destination object.

With the Destinations registered, Kratix now has a place where it can run workloads!

In fact, as soon as a new Destination is registered, Kratix writes a test document to the State Store. You can use this test to validate that the entire system is wired up correctly.

First, check the MinIO kratix bucket:

mc ls -r kind

The above command will give an output similar to:

[2024-01-01 15:00:00 GMT]   116B STANDARD kratix/worker-cluster/dependencies/kratix-canary-namespace.yaml
[2024-01-01 15:00:00 GMT] 206B STANDARD kratix/worker-cluster/resources/kratix-canary-configmap.yaml

You can also inspect the contents of the test documents. For example, take the kratix-canary-namespace.yaml:

mc cat kind/kratix/worker-cluster/dependencies/kratix-canary-namespace.yaml

The above command will give an output similar to:

apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: kratix-worker-system
spec: {}
status: {}

Since your worker cluster is already listening to this path within the bucket, you should see Flux automatically creating the namespace on the worker cluster as soon as it detects the change:

kubectl --context $WORKER get namespace kratix-worker-system

It may take a few minutes, but the above command will give an output similar to:

NAME                   STATUS   AGE
kratix-worker-system Active 1m

You environment now looks like this:

Deployed resources with Destination
Flux reconciled and created the test resources

Register the platform as a Destinationโ€‹

To register the platform cluster as an available Destination, you will run through similar steps you ran during the worker cluster Destination registration:

  • Install and configure Flux
  • Register the cluster as a Destination with Kratix

There's a script in the kratix directory that will do exactly that. This script includes the same Destination setup steps you performed previously. Run:

./scripts/register-destination --name platform-cluster --context $PLATFORM --state-store default --strict-match-labels --with-label environment=platform

The platform cluster should now be registered with Kratix and ready to receive the workloads. Verify:

kubectl --context $PLATFORM get destinations

The above command will give an output similar to:

NAME               AGE
platform-cluster 1m
worker-cluster 1h

Similar to when you registered the worker cluster, you should also see a kratix-worker-system namespace, indicating that Flux is correctly configured. Verify with:

kubectl --context $PLATFORM get namespaces --watch

The above command will give an output similar to:

NAME                     STATUS   AGE
...
kratix-platform-system Active 1h
kratix-worker-system Active 1m
...

Once you see kratix-worker-system on the output, press Ctrl+C to exit the watch mode.

Kratix is now fully installed and configured, and can start deploying Promises and resources to your clusters.

Summaryโ€‹

Your platform is ready to receive Promises! Well done!

To recap the steps you took:

  1. โœ…ย ย Installed Kratix on the platform cluster
  2. โœ…ย ย Told Kratix about the MinIO bucket, as a Bucket State Store
  3. โœ…ย ย Told Kratix about the worker and platform clusters, as Destinations

๐ŸŽ‰ Congratulationsโ€‹

โœ… Kratix is now installed and configured!
๐Ÿ‘‰๐Ÿพ Next you will deploy your first Promise.