arrow Back to all posts

Develop on a branch of your remote cluster with Tilt and Kardinal

Develop on a branch of your remote cluster with Tilt and Kardinal

Tilt is a powerful tool for microservice development, automating many steps including watching files, building images, and keeping an up to date environment. However, its effectiveness is often limited to local Kubernetes clusters. For stacks that require remote development clusters, the operational overhead with using Tilt can become a significant hurdle.

Enter Kardinal, an open-source solution for spinning up extremely lightweight ephemeral development environments within a shared Kubernetes cluster. By leveraging request-level routing, Kardinal maximizes the reuse of microservices and databases while maintaining isolation. An environment in Kardinal is like a “branch” of a deployed application on Kubernetes. You only deploy what you need, streamlining overhead and reducing cloud costs by over 90%—especially beneficial for larger teams and complex microservice architectures.

Screen Shot 2024-10-04 at 1.00.15 PM.png

In this tutorial, we'll combine the strengths of developing on Tilt, and the efficient service routing of Kardinal. You'll learn how to effectively deploy your applications, manage resources, and build containers while ensuring a smooth and efficient development experience.

Curious to dive deeper? Check out our GitHub repo for more info on Kardinal, and don’t miss the Tiltfile in the Kardinal Boutique demo app for a hands-on experience.

Ready to transform your development process? Let’s get started.

Prerequisites

Before we dive in, make sure you have the following set up first:

  • Kardinal CLI
  • Tilt
  • A local Kubernetes (K8s) cluster (you can use Minikube or Docker Desktop)
    • ⛳ flag: If you’re new to Kardinal, we suggest trying it locally first, before using it with your remote clusters.
  • Istio
    • 💡flag: It’s not important that your cluster uses Istio. Kardinal will manage everything related to Istio on your development cluster.
  • Distributed tracing on your application
    • For a full list of supported distributed tracing systems, check out our docs here.

Setting up Kardinal for your application

Getting started with Kardinal involves deploying Kardinal Manager to your cluster, and annotating your kubernetes manifest. Don’t worry, this should only take few minutes!

  • If you haven’t installed Kardinal yet, run the following command:
curl get.kardinal.dev -sL | sh
  • Lets set up a local development cluster for testing first. All you need is a cluster with Istio installed, with kubectl pointing to your cluster. If you don’t have one handy, not to worry!We can get set up by installing the below on your machine:Then running the following:
    - Docker
    - Minikube
    - Kubectl
    - Istio
minikube start --driver=docker --cpus=10 --memory 8192 --disk-size 32g
minikube addons enable ingress
minikube addons enable metrics-server
istioctl install --set profile=default -y
  • This is normally when you would deploy Kardinal Manager to your cluster, however in this case, we’ll be using Tilt for this so you can skip for now.
  • We’ll then get started by having Kardinal recognize your application’s entrypoint. Kardinal supports managing access to your services either through the Kubernetes Ingress API or the Gateway API.All you need is to add the kardinal.dev.service/ingress or kardinal.dev.service/gateway annotations to your Ingress or Gateway manifest to mark this entrypoint.You can find more information and example annotations in our docs here.

You’re all set! Now to move onto the fun part.

Deploy your application

Option 1: deploy your current Kardinal topology

If you've already deployed your application's manifest using the kardinal deploy command, your cluster topology is ready for deployment with Tilt. If you haven’t, check out our getting started docs here.

Run the command:

sudo tilt up

Create a Tiltfile with the following content:

kardinal_topology_yaml = local(['kardinal', 'topology', 'print-manifest', '--add-trace-router'], quiet=True)
kardinal_topology_yaml_str = str(kardinal_topology_yaml)

if kardinal_topology_yaml_str != '':
    k8s_yaml(kardinal_topology_yaml, allow_duplicates=True)

local_resource(
    name='ingress-gateway-port-forward',
    serve_cmd=['kubectl', 'port-forward', 'service/istio-ingressgateway', '80:80', '-n', 'istio-system']
)

In this setup, the first local call retrieves the cluster topology from Kardinal Kontrol using the kardinal topology command. This generates a multi-resource manifest that Tilt applies with the k8s_yaml command. The local_resource function then executes the port forwarding command, allowing the Ingress Gateway to handle browser requests on port 80.

Option 2: deploy your manifest file with Kardinal annotations

You can also incorporate the kardinal deploy command within Tilt to manage the deployment flow seamlessly. Here’s how:

Run the command:


sudo tilt up

Create a Tiltfile like this, replacing the placeholder data:

python
Copy code
local(['kardinal', 'deploy', '-k', '{your-kardinal-manifest-yaml-filepath}'])

kardinal_topology_yaml = local(['kardinal', 'topology', 'print-manifest', '--add-trace-router'], quiet=True)
kardinal_topology_yaml_str = str(kardinal_topology_yaml)

if kardinal_topology_yaml_str != '':
    k8s_yaml(kardinal_topology_yaml, allow_duplicates=True)

local_resource(
    name='ingress-gateway-port-forward',
    serve_cmd=['kubectl', 'port-forward', 'service/istio-ingressgateway', '80:80', '-n', 'istio-system']
)

In this example, the kardinal deploy command is used at the beginning to deploy your multi-resource manifest file directly to Kardinal Kontrol.

Build and deploy your application

Integrate Kardinal with Tilt to build your application containers and set up workflows that automatically reflect changes when you save your files. Follow these steps:

Run the command:

sudo tilt up

Create a Tiltfile like this, replacing the placeholder data:

local(['kardinal', 'deploy', '-k', '{your-kardinal-manifest-yaml-filepath}'])

local(['kardinal', 'flow', 'create', '{service}', '{service-dev-image}'])

docker_build(
    '{service-dev-image}',
    context='{./src/}',
    dockerfile='{./src/Dockerfile}',
)

kardinal_topology_yaml = local(['kardinal', 'topology', 'print-manifest', '--add-trace-router'], quiet=True)
kardinal_topology_yaml_str = str(kardinal_topology_yaml)

if kardinal_topology_yaml_str != '':
    k8s_yaml(kardinal_topology_yaml, allow_duplicates=True)

local_resource(
    name='tunnel',
    serve_cmd=['minikube', 'tunnel']
)

In this setup, we introduce two new elements: the kardinal flow local execution for creating the development flow and the docker_build function to link the container being built with the service in the development flow. This setup triggers Tilt's hot reload mechanism whenever changes are made to files within the specified context.

Accessing PROD and DEV flows

Once your Tiltfile execution is complete, you’ll see URLs for both the prod and dev applications printed in the logs. Click on these links to access the respective flows in your browser.

Cleanup

After finishing your development cycle, you can remove all created resources from the cluster by running the following command:

tilt down --delete-namespaces

The --delete-namespaces flag will remove your application’s namespace, but it won’t affect the default namespace.

Once you feel comfortable with running this setup locally, you can deploy to remote clusters as needed, enjoying the benefits of both Tilt’s devex and Kardinal’s efficient dev flows.

Helpful resources

If you want to learn more about Kardinal, get additional support, or test it out without installing anything-here are some helpful links:

Happy coding! 💻