The Charmed Operator Framework

The Charmed Operator Framework allows the development of operators in a simple and straightforward way, using standard Python structures to allow for clean, maintainable, and reusable code. Charmcraft is a command line tool used alongside the Operator Framework to create, build, and publish operators (packaged as charms).

A Kubernetes operator is a container that drives lifecycle management, configuration, integration and daily actions for an application. Operators simplify software management and operations. They capture reusable app domain knowledge from experts in a software component that can be shared.

The Charmed Operator Framework extends the operator pattern to enable Charmed Operators, packaged as and often referred to as “charms”. Charms are not just for Kubernetes but also operators for traditional Linux or Windows application management. Operators use an Operator Lifecycle Manager (OLM), like Juju, to coordinate their work in a cluster. The system uses Golang for concurrent event processing under the hood, but enables the operators to be written in Python.

Operators should ‘do one thing and do it well’. Each operator drives a single application or service and can be composed with other operators to deliver a complex application or service. An operator handles instantiation, scaling, configuration, optimisation, networking, service mesh, observability, and day-2 operations specific to that application.

Machine Charms

Juju’s beginnings were centered around simplifying the deployment of complex applications and services in a cloud-first world. At the time, many of those applications were run in virtual machines or on bare-metal servers, and deployments to these environments continue to enjoy first-class support. A machine charm can be deployed to a number of different underlying compute/storage resource providers:

  • Bare-metal (perhaps using MAAS)
  • A virtual machine (on public or private cloud)
  • VMware
  • OpenStack
  • A LXD cluster

Kubernetes Charms

More recently, the Juju OLM introduced support for Charmed Operators on Kubernetes. Juju can bring the same benefits to applications deployed on Kubernetes, by placing operators alongside workloads to manage them throughout their lifecycle. When a model is created with Juju, a corresponding Kubernetes namespace is created. When a charm is deployed on Kubernetes, it is deployed as a StatefulSet that manages a set of Pods running the specified application containers alongside a sidecar container containing the charm code.

By definition, the sidecar pattern is designed to allow the augmentation of workloads with additional capabilities and features. The pattern is implemented in this case by a small auxiliary container, located in the same Pod as your application, that provides operations functionality - this is exactly how Juju operates in other environments, and a well-established pattern in the Kubernetes community.

By utilising this pattern, we ensure that there is always an operator right next to every unit of the workload, irrespective of how the application is scaled. The operator will always have direct access to shared memory, the same network namespace and the ability to manipulate the workload as required to keep it running smoothly. This approach simplifies the operation of upstream or third-party application images, enabling administrators to make changes at runtime to suit their environment should they wish, without the requirement to maintain a fleet of bespoke container images.

For charm developers, these benefits are realised by utilising Pebble to manage workloads. Pebble is a lightweight, API-driven process supervisor designed for use with Charmed Operators. Pebble enables charm developers to define how they want workloads to run, and provides an API that enables operations code to manage the workloads throughout their life.

Subordinate Charms

Subordinate charms were created to enable the development of charms that could be deployed alongside existing charms, to augment them with specific functionality that may not be included in the original application charm. They are, in many ways, analogous to the sidecars described above. All charms are principal charms, except those that are subordinates. A subordinate charm depends on the creation of a relationship to a principal charm, it is never deployed as a standalone application. This is best explained with an example:

Consider the deployment of a large web application scaled to n replicas. Each instance of the charm comprises a unit, in Juju parlance, and an App is the sum of all units of a given charm with the same name. When a large web application is scaled to n replicas, n units will be started by Juju.

The administrators of the web application will likely want to collect logs from the application server. The developer of the application charm may not have included a mechanism for forwarding logs from the service that is compatible with the administrator’s specific environment. By using a subordinate charm such as rsyslog-forwarder, the administrator can ensure that each deployed unit of their web application is automatically configured to forward logs using rsyslog. To do this, they must simply deploy the subordinate and juju relate their web application to it.

Subordinate charms are written in the same way as other charms, with the addition of an extra subordinate flag in the charm’s metadata.

Multi-cloud models

One of the most powerful concepts in Juju deployments is the way application deployments are modelled. A single Juju controller can interact with multiple underlying substrates, be those bare-metal private clouds, public clouds or a hand-crafted Kubernetes cluster. Irrespective of the substrate they are deployed upon, charms can be related using cross-model relations. This enables seamless interoperability between substrates, where the Juju OLM handles all of the networking, permissions and configuration on your behalf.

For example, if you already bootstrapped a database cluster on bare-metal using Juju, but your new web application runs on Kubernetes, you can just juju relate your different charms for seamless integration across clouds.


Level Path Navlink
0 Introduction
1 overview Overview
1 dev-setup Development Setup
1 hello-world Hello, World
0 Charming Essentials
1 charm-anatomy Charm Anatomy
1 events Lifecycle Events
1 constructs Framework Constructs
1 pebble Interacting with Pebble
1 workloads Running Workloads
1 config Handling Configuration
1 actions Handling Actions
1 logging Logging
1 testing Testing
1 charm-documentation Charm Documentation
0 Advanced Topics
1 leadership Leadership
1 relations Relations
1 storage Storage
1 libraries Libraries
1 resources Resources
1 debugging Debugging
0 Charmcraft
1 setting-up-charmcraft Installing Charmcraft
1 charmcraft-config Configuration
1 publishing Publishing Charms
1 publishing-resources Publishing Resources
1 charmcraft-libraries Publishing Libraries
1 bundles Publishing Bundles
1 charmcraft-analyze Analyzers and Linters
1 charmcraft-deprecations Deprecations
1 charmcraft-roadmap Roadmap
0 Get Help
1 discourse Community Discourse
1 chat Community Chat
0 Reference
1 Github
1 API Documentation
1 metadata-reference Metadata reference
1 bundle-reference Bundle reference
1 history Charming History


Mapping table
Path Location

There’s a few bugs in this document:

Under the “Kubernetes Charm” header
When a model is created on Kubernetes, a corresponding Kubernetes namespace is created.

This should read “When a model is created in juju, a corresponding…”

1 Like

Thanks, will fix now.

Although the navigation menu here correctly links “Github” to, when rendered it is linked to, which is a 404.

Hmm that’s annoying, I wonder if that’s changed recently :confused:

@toto do you know how to solve that? Trying to link to an external link the nav?

@jkfran Can you please take a look here?

I opened a bug on it a few days back, I believe it is being worked on -

We had a bug in the previous version of our documentation parser with external links. It should be fine now :slight_smile:

1 Like

Hi, here are sum suggestions/fixes/imporvements on the doc.

Hi Kos - top reviewing today!

Have made some adjustments here. I’ve left the charmed operators link pointing at the docs homepage as it has a brief definition and link off to other places with more context. Will review when I find a better end destination!

I made some additional clarifying edits about what a unit is compared to an application as a corollary to the “scale to n replicas” example.