Using Kubernetes with Juju

Juju is an Open Source Charmed Operator Framework. It helps you move from configuration management to application management and has two main components:

  • Charmed Operator Lifecycle Manager (OLM) - a hybrid-cloud application management and orchestration system that helps you from Day 0 to Day 2. Deploy, configure, scale, integrate, maintain and manage Kubernetes native, container-native and VM-native applications – and the relations between them.

    • Charmed Operators, packaged as “Charms”, are software that encapsulate a single application and all the code and know-how it takes to operate it on Kubernetes or machines.
  • Charmed Operator SDK - a guide to help you build Charmed Operators for use with the Charmed OLM.

Kubernetes – also known as K8s – provides a flexible architecture for Cloud Native applications at scale. The Juju Charmed OLM manages multi-container workloads on K8s. This guide takes you through the registration steps necessary to connect the two systems.

You don’t need to have previous knowledge of Juju or Charmed Operators to follow this guide.

This page covers the following topics:

Prerequisites
Useful tools to manage Juju and Kubernetes
A. Install Juju CLI Allows you to configure and manage other Juju components.
B. Install Kubectl CLI Allows you to run commands against Kubernetes clusters.
C. Gain access to a Kubernetes cluster If you don’t have a cluster, we will go through the process of creating one.
Connecting Juju to your Kubernetes cluster
Register your cluster with Juju
1. Register the cluster with Juju Make your cluster known to Juju.
2. Create a Juju controller Bootstrap the Juju controller to your cluster
Deploy workloads
Deploy and integrate applications
3. Add a model Create a model to wrap your infrastructure.
4. Deploy workloads Deploy applications using universal operators from charmhub.io
5. Relate your applications Use juju relate to integrate your applications.

Prerequisites

I. Installing Juju

Juju is a single binary executable that is published and supported on multiple operating systems and CPU architectures.

OS Method
Linux snap install --classic juju
macOS brew install juju
Windows Download the signed Juju installer, md5, signature

Alternative installations:
You can find instructions on installing development releases or building from the source in the Juju installation page.

II. Installing Kubectl

Kubectl is a command-line tool that allows you to run commands against Kubernetes clusters. If you have access to a cluster, you might already have it installed. If not, you can follow these instructions to download and install the binary.

III. Gaining access to a Kubernetes cluster

Juju supports a variety of Kubernetes distributions running on your laptop, private infrastructure, or public cloud. You can connect Juju to your existing K8s cluster or get one based on the recommendations below. If you are new to Kubernetes, we recommend following this guide with MicroK8s.

Use Case Recommended Action
Local development, testing and experimentation Install MicroK8s
Multi-node testing/production on a private cloud Install Charmed Kubernetes
Multi-node testing/production on the public cloud Install Charmed Kubernetes with the relevant integrator charm
Use a hosted Kubernetes distribution Enable the service via the provider

We also have guides for creating clusters on the following Kubernetes distributions:

If your distribution is not listed above, you are still able to use Juju on any cluster to which you have sufficient access privileges, recorded in a kubeconfig entry.

Connecting Juju to your Kubernetes cluster

1. Register the cluster with Juju

Juju will look for the kube configuration files to find the cloud definition.

You can see what clouds Juju has found by running:
bash juju clouds

If for any reason that can’t be done automatically, you can manually point Juju to the cluster’s configuration file.

Manually exposing the cluster's configuration file

Copy the cluster’s configuration file from the master node to your local machine and save it as $HOME/.kube/config, then run

juju add-k8s

If Juju can see your cluster (juju clouds), move on to 2. Create a Juju controller.

Some clouds will require extra steps configure the cluster to work with Juju:

a. When running MicroK8s

The cluster is registered with Juju automatically, but we have to enable the storage and dns addons.

microk8s enable storage dns

Then move on to 2. Create a Juju controller.

b. When you’re already able to interact with your cluster via kubectl

Juju will automatically look in the standard kube configuration file.

Then move on to 2. Create a Juju controller.

c. When you have used Juju to deploy Charmed Kubernetes
mkdir ~/.kube
juju scp kubernetes-master/0:/home/ubuntu/config ~/.kube/config
juju add-k8s

Then move on to 2. Create a Juju controller.

2. Create a Juju controller

The Juju controller is a central software agent that oversees applications managed with Juju. It is created via the juju bootstrap command.

juju bootstrap <cloud-name> <controller-name>

Cloud name is microk8s or <cloud-name> specified previously.

Config file:
The command above assumes that the config file is located at $HOME/.kube/config (or it has been loaded manually) and you can communicate to your cluster via kubectl.

To check that you have configured kubectl correctly, execute the command:
kubectl get nodes

Then move on to 3. Add a model.

Deploy workloads

3. Add a model

Before deploying applications with universal operators, Juju users create a “model”. In the Kubernetes context, models are [namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/).

A model is a canvas on a particular cloud/k8s-cluster. The model is used to group applications that are being operated together for a common purpose on a common substrate. The model will capture the applications, their integration, configuration, and resource allocation.

Since each model is on a single substrate, and the service as a whole may span multiple clouds/k8s-clusters, it may require several models to provide the canvases for all the different applications in the service.

The model is a workspace for inter-related applications. It is an abstraction over applications, machines hosting them and other components such as persistent storage.

To add a model, use the juju add-model command:

juju add-model <cloud-name>

Inside the cluster, adding a Juju model creates a Kubernetes namespace with the same name. The namespace hosts all of the pods and other resources, except global resources.

4. Deploy workloads

The fundamental purpose of Juju is to deploy and manage software applications in a way that is easy and repeatable. All this is done with the help of universal operators , which are bits of code that contain all the necessary intelligence to do these things. Universal operators can exist online (in the Charm Store) or on your local filesystem (previously downloaded from the store or written locally).

As an example, we will deploy Mattermost, an open-source, self-hostable online chat service using PostgreSQL as its database.

Typically, applications are deployed using the online universal operators. This ensures that you get the latest version of the charm. Deploying in this way is straightforward:

Deploy Mattermost:

juju deploy mattermost

When deployed, this outputs:

Located charm "mattermost" in charm-store, revision 20

Deploying "mattermost" from charm-store charm "mattermost", revision 20 in channel stable

You can observe the deployment status with the following command:

watch -c juju status --format short --color

Then deploy the PostgreSQL Charm:

juju deploy postgresql-k8s

When deployed, this outputs:

Located charm "postgresql-k8s" in charm-store, revision 9

Deploying "postgresql" from charm-store charm "postgresql-k8s", revision 9 in channel stable

At this point, both applications are deployed in the model located in the Kubernetes cluster, but they don’t know about each other. Next we will relate apps.

5. Relate Applications

Relations

Most applications rely on other applications to function correctly. For example, typically web apps require a database to connect to. Relations avoid the need for manual intervention when the charm’s environment changes. The charm will be notified of new changes, re-configure and restart the application automatically.

Relations are a Juju abstraction that enables applications to inter-operate. They are a communication channel between universal operators.

A certain charm knows that it requires, say, a database and, correspondingly, a database charm knows that it is capable of satisfying another charm’s requirements. The act of joining such mutually-dependent universal operators causes code (hooks) to run in each charm in such a way that both universal operators can effectively talk to one another. When universal operators have joined logically in this manner they are said to have formed a relation.

Create relation

Creating a relation is straightforward. The add-relation command is used to set up a relation between two applications:

juju relate mattermost postgresql:db

This will satisfy Mattermost’s database requirement where PostgreSQL provides the appropriate structures (e.g. tables) needed for Mattermost to run properly.

Ambiguous relations

If the universal operators in question are versatile enough, Juju may need to be supplied with more information as to how the universal operators should be joined.

In this example, we had to specify to which postresql endpoint we wanted to connect: postgresql:db That’s because postgresql has multiple endpoints for syslog, db and db_admin.

Again, watch the deployment status with the following command until both universal operators’ status is active.

watch -c juju status --format short --color

Which will return the following when the applications are related:

- mattermost/0: (agent:idle, workload:active) 8065/TCP

- postgresql/0: (agent:idle, workload:active) 5432/TCP

Your deployment is dynamic: If you need to scale, deploy other applications or move it around, Juju will adapt and maintain the relations active without the need of special configurations.

Access the application

To access the application locally, get the Pod name:

export APP_NAME=$(kubectl get pod -l app.kubernetes.io/name=mattermost -n my-model -o name)

And create a port-forward:

kubectl port-forward -n my-model $APP_NAME 8065

Open your browser and access the page http://localhost:8065. You should see the Mattermost home page.

Congratulations, you just deployed and integrated cloud-native applications in a Kubernetes cluster!

Next steps

This guide presents the core of Juju’s functionality - most applications will follow a similar workflow: bootstrap the controller in your cluster, add a model, deploy and relate applications. If you would like to see some examples of what you can do with Juju, our tutorials page has application specific guide. You can also try Juju on your own cloud or localhost


Last updated 10 days ago.