Local Kubernetes Development with Tilt

In my last post I detailed how to setup a local Kubernetes development cluster using kind. This post shows how to leverage this new cluster when developing a system or application that relies on multiple microservices using tilt. If you haven’t setup your local environment with kind yet, refer back to my last post before continuing on.

Installing Tilt

You can install the tilt binary using Homebrew or through curl and an installation script:

1
$ brew install tilt-dev/tap/tilt

or

1
$ curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash

Tilt Up

To check that tilt is working, you can get started by running the tilt up command. This will list a few options. Press space to open the tilt dashboard in your browser

1
2
3
4
5
6
7
8
$ tilt up
Tilt started on http://localhost:10350/
v0.17.6, built 2020-09-29

(space) to open the browser
(s) to stream logs (--stream=true)
(t) to open legacy terminal mode (--legacy=true)
(ctrl-c) to exit

Connecting Tilt to the local Docker registry

Tilt depends on a Tiltfile that declares the set of resources required to build your application. We can start this file by just printing Hello World!:

1
$ echo "print('Hello Tiltfile')" >> Tiltfile

If you still have Tilt running, it will automatically pick up the presence of a Tiltfile and re-load your configuration. The UI will show you a warning message about connecting the local Docker registry we’ve setup with Kind to tilt:

1
2
3
Tilt can use the local registry to speed up builds.
Instructions: https://github.com/tilt-dev/kind-local
Beginning Tiltfile execution

To fix this warning, we can annotate our Kubernetes nodes to mark the registry the local registry that we are using. This annotation is then available to local tooling like tilt by inspecting the cluster through the Kubernetes API. The following script annotates all nodes with the Docker registry we deployed at localhost:5000:

1
2
3
for node in $(kind get nodes); do
  kubectl annotate node "${node}" "kind.x-k8s.io/registry=localhost:5000";
done

Running your project with tilt

It is easiest to get started by using tilt on an existing project that uses Kubernetes. If you don’t have a project, you can grab one from kubernetes/examples. For the rest of this tutorial I will use one of those the guestbook-go project to get up and running with tilt.

1
$ git clone https://github.com/kubernetes/examples.git && cd guestbook-go

This project is made up of several Kubernetes resources spread over multiple JSON files. To use these resources with tilt, we add them using the k8s_yaml function:

1
k8s_yaml(['frontend-deployment.yaml', 'frontend-service.yaml', 'redis-master-deployment.yaml', 'redis-master-service.yaml', 'redis-slave-deployment.yaml', 'redis-slave-service.yaml'])

Running tilt up with this basic configuration will deploy all the Kubernetes resources you declared and present a refined UI allowing you to browse the logs for each resource and a quick status check showing any errors.

Responding to Code Changes

As we develop locally, we will want any changes we make to our application to be reflected with minimal overhead. We can do that by declaring how to build any Docker files we have in our local directory by adding the docker_build function to our Tiltfile. This function takes the Docker image tag we want to use as the first parameter to the function, and the folder on the file system where the Dockerfile for this service exists.

1
docker_build('localhost:5000/frontend:0.1', 'php-redis')

After you make this change, don’t forget to reference the same image in frontend-deployment.yaml by changing

1
2
- name: php-redis
  image: gcr.io/google-samples/gb-frontend:v4

to

1
2
- name: php-redis
  image: localhost:5000/frontend:0.1

With this setup, any changes you make to the frontend application are automatically rebuilt and pushed to your local development cluster. You can test this out by making any change the frontend application code in php-redis/guestbook and see how Tilt reloads builds and deploys the application on your behalf.

Connecting to localhost

The last step we have is connecting your running application to your localhost network using port forwarding. Tilt handles this on our behalf using the k8s_resource function. Tilt creates Kubernetes resources automatically based on the Yaml files used for deployment. The k8s_resource function allows you to configure these resources. The only thing we need to do is configure which port to forward between localhost and our Kubernetes service using the port_forwards parameter.

Add the following line to your Tiltfile.

1
k8s_resource('frontend', port_forwards=8080)

And navigate to localhost:8080 to see your application up and running.

Tightening the Inner Loop of Development

This article showed how to set up tilt.dev with an example project that automates all the steps from a code change to a new deliverable: watching files, building container images, and bringing your environment up-to-date. I’ve found tilt useful at tightening up the “inner loop” of development for multi-service Kubernetes projects by streamlining the process between making a change to a file and seeing the results on screen.

See also

comments powered by Disqus