Using Kubernetes with Juju

Kubernetes (“K8s”) provides a flexible architecture for managing containerised applications at scale. Juju can be used to create a Kubernetes cluster and to manage workloads on top of a live cluster. This guide is about using Juju to manage workloads on a live Kubernetes cluster.

Juju is able to treat the added cluster as it does any other cloud. Applications can relate across K8s and traditional infrastructure.

What is Juju?: If you are unfamiliar with Juju, we recommend following our Getting Started with Juju tutorial.

Running Kubernetes workloads

First off, a Kubernetes cluster will be required. Essentially, you will use it as you would any other cloud that Juju interacts with: the cluster becomes the backing cloud.

The following steps describe the general approach for using Kubernetes with Juju:

  1. Obtain a Kubernetes cluster
  2. Register the cluster with Juju
  3. Add a model
  4. Create persistent static storage (if necessary)
  5. Create storage pools
  6. Deploy a Kubernetes charm

Obtain a Kubernetes cluster

There are many ways to obtain a Kubernetes cluster. If you are unsure which option to choose, then you should install MicroK8s.

Use Case Recommended Action(s)
Local development, testing and experimentation Install MicroK8s
Multi-node testing/production on own 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

Register the Kubernetes cluster with Juju

Registering the cluster with Juju is known as “adding a cloud” in Juju’s terminology. A cloud is a deployment target. The exact process to register the cluster depends on how your system is configured.

If you have installed MicroK8s, the cluster is already registered. Feel free to move to the next section.

If kubectl is working, then the registration process is a single command:

  • Run juju add-k8s

If you have used Juju to deploy Charmed Kubernetes, we can use Juju to extract its configuration file to save it locally:

  • Run mkdir ~/.kube
  • Run juju scp kubernetes-master/0:/home/ubuntu/config ~/.kube/config
  • Run juju add-k8s


  • Copy the cluster’s configuration file from the master node to your local machine and save it as ~/.kube/config, then
  • Run juju add-k8s

Add a model

Before deploying applications with charms, Juju users create a “model”. The model 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 <k8s-cloud-name>.

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.

The model also has a default storage pool called “kubernetes”.

Create persistent static storage

When an application that you wish to deploy–your “workload” in Juju terms–makes uses of persistent storage, you may need to ensure that it has been added to your Kubernetes cluster.

If you are using MicroK8s, feel free to skip this step. MicroK8s automatically provides persistent volumes on demand.

Charmed Kubernetes users can use Juju to provide it with storage based onCeph or NFS.

Users of other clusters should follow their vendor’s instructions and verify that the storage pools are available with the command: kubectl get sc,po.

Create storage pools

Create storage pools for operator storage and, if needed, workload storage. This is done in the usual way, with the create-storage-pool command.

Deploy a Kubernetes charm

A Kubernetes-specific charm is deployed in standard fashion, with the deploy command. If the charm has storage requirements you will need to specify them, as you do with a normal charm.


The below table lists configuration keys supported by Kubernetes charms that are set at deploy time. The corresponding Kubernetes meaning can be obtained from the Kubernetes documentation for Services and Ingress.

Key Type Default
kubernetes-service-type string ClusterIP
kubernetes-service-external-ips string []
kubernetes-service-target-port string <container port>
kubernetes-service-loadbalancer-ip string ""
kubernetes-service-loadbalancer-sourceranges string "[]"
kubernetes-service-externalname string ""
kubernetes-ingress-class string nginx
kubernetes-ingress-ssl-redirect boolean false
kubernetes-ingress-ssl-passthrough boolean false
kubernetes-ingress-allow-http boolean false

For example:

juju deploy mariadb-k8s --config kubernetes-service-loadbalancer-ip=

There are two other keys that are not Kubernetes-specific:

Key Type Default
juju-external-hostname string ""
juju-application-path string "/"

Keys ‘juju-external-hostname’ and ‘juju-application-path’ control how the application is exposed externally using a Kubernetes Ingress Resource in conjunction with the configured ingress controller (default: nginx).

Storage theory

Refer to the Persistent storage and Kubernetes page for the theory on how Juju works with Kubernetes storage.

Tutorials and in-depth guides

The following practical guides are available:

Last updated 28 days ago. Help improve this document in the forum.