See also: How to manage controllers
In Juju, a controller is the initial cloud instance that is created by the Juju CLI during bootstrapping, connecting the Juju CLI with the underlying cloud API. It might be deployed as a container, lxc container, or VM, depending on the cloud environment. It runs an API server and has access to an underlying database whose role is to keep track of the state of all the deployed models, applications, or machines in that environment. The controller is a central piece of Juju, constituting the management node of a Juju cloud environment and being responsible for implementing all the changes defined by a Juju user.
A controller exists in a single cloud, though it can manage multiple clouds by bootstrapping a controller into one cloud and then adding another cloud to that controller. It can also manage multiple workloads in multiple clouds via cross-model integrations.
The controller runs as one or more controller agents on the cloud where it has been deployed. Once deployed, the controller can perform operations on the cloud where it has been deployed via the API exposed by the cloud. Juju clients only communicate with the controller when performing operations on the cloud.
It is also possible to form a high-availability cluster of controller agents in a cloud, which is basically a set of controller agents running in that cloud forming one highly-available controller all together. For more, see Controller high availability.
See more: How to manage the Juju dashboard