K8s charm architecture

Canonical k8s Charms encompass two primary components: the k8s charm and the k8s-worker charm.

@startuml set separator none title Juju - Containers  top to bottom direction  !include <C4/C4> !include <C4/C4_Context> !include <C4/C4_Container>  Person(Administrator, "Administrator", $descr="", $tags="", $link="")  System_Boundary("Juju_boundary", "Juju", $tags="") {   Container(Juju.JujuController, "Juju Controller", $techn="Snap Package", $descr="", $tags="", $link="")   Container(Juju.JujuClient, "Juju Client", $techn="Snap Package", $descr="", $tags="", $link="")   Container(Juju.CompatibleCharms, "Compatible Charms", $techn="", $descr="Other Compatible Canonical Charms", $tags="", $link="")   Container(Juju.K8s, "K8s", $techn="Charmed Operator", $descr="K8s Charm", $tags="", $link="")   Container(Juju.K8sRelationData, "K8s Relation Data", $techn="", $descr="", $tags="", $link="")   Container(Juju.K8sWorker, "K8s Worker", $techn="Charmed Operator", $descr="K8s Worker Charm", $tags="", $link="")   Container(Juju.K8sWorkerRelationData, "K8s Worker Relation Data", $techn="Juju Relation Databag", $descr="", $tags="", $link="") }  Rel(Juju.K8sWorker, Juju.K8sWorkerRelationData, "Reads from and writes to", $techn="", $tags="", $link="") Rel(Juju.K8sWorkerRelationData, Juju.K8sWorker, "Retrieves Peer Data", $techn="", $tags="", $link="") Rel(Juju.JujuController, Juju.K8s, "Manages", $techn="", $tags="", $link="") Rel(Juju.JujuController, Juju.K8sWorker, "Manages", $techn="", $tags="", $link="") Rel(Administrator, Juju.JujuClient, "Uses", $techn="", $tags="", $link="") Rel(Juju.JujuClient, Juju.JujuController, "Manages", $techn="", $tags="", $link="") Rel(Juju.K8s, Juju.CompatibleCharms, "Integrates with", $techn="", $tags="", $link="") Rel(Juju.K8sWorker, Juju.CompatibleCharms, "Integrates with", $techn="", $tags="", $link="") Rel(Juju.K8s, Juju.K8sRelationData, "Reads from and writes to", $techn="", $tags="", $link="") Rel(Juju.K8sRelationData, Juju.K8s, "Retrieves Peer Data", $techn="", $tags="", $link="") Rel(Juju.K8s, Juju.K8sWorkerRelationData, "Share Cluster Data", $techn="", $tags="", $link="")  SHOW_LEGEND(true) @enduml

Charms are instantiated on a machine as a Juju unit, and a collection of units constitutes an application. Both k8s and k8s-worker units are responsible for installing and managing its machine’s k8s snap, however the charm type determines the node’s role in the Kubernetes cluster. The k8s charm manages control-plane nodes, whereas the k8s-worker charm manages Kubernetes worker nodes. The administrator manages the cluster via the juju client, directing the juju controller to reach the model’s eventually consistent state. For more detail on Juju’s concepts, see the Juju docs.

The administrator may choose any supported cloud-types (Openstack, MAAS, AWS, GCP, Azure…) on which to manage the machines making up the Kubernetes cluster. Juju selects a single leader unit per application to act as a centralised figure with the model. The k8s leader oversees Kubernetes bootstrapping and enlistment of new nodes. Follower k8s units will join the cluster using secrets shared through relation data from the leader. The entire lifecycle of the deployment is orchestrated by the k8s charm, with tokens and cluster-related information being exchanged through Juju relation data.

Furthermore, the k8s-worker unit functions exclusively as a worker within the cluster, establishing a relation with the k8s leader unit and requesting tokens and cluster-related information through relation data. The k8s leader is responsible for issuing these tokens and revoking them if a unit administratively departs the cluster.

The k8s charm also supports the integration of other compatible charms, enabling integrations such as connectivity with an external etcd datastore and the sharing of observability data with the Canonical Observability Stack (COS). This modular and integrated approach facilitates a robust and flexible Canonical Kubernetes deployment managed through Juju.