9 minute read
Gardener is implemented using the operator pattern: It uses custom controllers that act on our own custom resources, and apply Kubernetes principles to manage clusters instead of containers. Following this analogy, you can recognize components of the Gardener architecture as well-known Kubernetes components, for example, shoot clusters can be compared with pods, and seed clusters can be seen as worker nodes.
The following Gardener components play a similar role as the corresponding components in the Kubernetes architecture:
|Gardener Component||Kubernetes Component|
Similar to how the
kube-scheduler of Kubernetes finds an appropriate node
for newly created pods, the
gardener-scheduler of Gardener finds an appropriate seed cluster
to host the control plane for newly ordered clusters.
By providing multiple seed clusters for a region or provider, and distributing the workload,
Gardener also reduces the blast radius of potential issues.
Kubernetes runs a primary “agent” on every node, the kubelet, which is responsible for managing pods and containers on its particular node. Decentralizing the responsibility to the kubelet has the advantage that the overall system is scalable. Gardener achieves the same for cluster management by using a gardenlet as primary “agent” on every seed cluster, and is only responsible for shoot clusters located in its particular seed cluster:
gardener-controller-manager has control loops to manage resources of the Gardener API. However, instead of letting the
gardener-controller-manager talk directly to seed clusters or shoot clusters, the responsibility isn’t only delegated to the gardenlet, but also managed using a reversed control flow: It’s up to the gardenlet to contact the Gardener API server, for example, to share a status for its managed seed clusters.
Reversing the control flow allows placing seed clusters or shoot clusters behind firewalls without the necessity of direct access via VPN tunnels anymore.
Kubernetes doesn’t manage worker nodes itself, and it’s also not responsible for the lifecycle of the kubelet running on the workers. Similarly, Gardener doesn’t manage seed clusters itself, so Gardener is also not responsible for the lifecycle of the gardenlet running on the seeds. As a consequence, both the gardenlet and the kubelet need to prepare a trusted connection to the Gardener API server and the Kubernetes API server correspondingly.
To prepare a trusted connection between the gardenlet and the Gardener API server, the gardenlet initializes a bootstrapping process after you deployed it into your seed clusters:
The gardenlet starts up with a bootstrap
kubeconfighaving a bootstrap token that allows to create
After the CSR is signed, the gardenlet downloads the created client certificate, creates a new
kubeconfigwith it, and stores it inside a
Secretin the seed cluster.
The gardenlet deletes the bootstrap
kubeconfigsecret, and starts up with its new
The gardenlet starts normal operation.
gardener-controller-manager runs a control loop
that automatically signs CSRs created by gardenlets.
The gardenlet bootstrapping process is based on the kubelet bootstrapping process. More information: Kubelet’s TLS bootstrapping.
If you don’t want to run this bootstrap process you can create
kubeconfig pointing to the garden cluster for the gardenlet yourself,
and use field
gardenClientConnection.kubeconfig in the
gardenlet configuration to share it with the gardenlet.
Gardenlet Certificate Rotation
The certificate used to authenticate the gardenlet against the API server
has a certain validity based on the configuration of the garden cluster
--cluster-signing-duration flag of the
After about 80% of the validity expired, the gardenlet tries to automatically replace
the current certificate with a new one (certificate rotation).
To use certificate rotation, you need to specify the secret to store
kubeconfig with the rotated certificate in field
.gardenClientConnection.kubeconfigSecret of the
gardenlet component configuration.
Rotate certificates using bootstrap
If the gardenlet created the certificate during the initial TLS Bootstrapping
using the Bootstrap
kubeconfig, certificates can be rotated automatically.
The same control loop in the
gardener-controller-manager that signs
the CSRs during the initial TLS Bootstrapping also automatically signs
the CSR during a certificate rotation.
ℹ️ You can trigger an immediate renewal by annotating the
Secret in the seed
cluster stated in the
.gardenClientConnection.kubeconfigSecret field with
gardener.cloud/operation=renew and restarting the gardenlet. After it booted
up again, gardenlet will issue a new certificate independent of the remaining
validity of the existing one.
Rotate Certificate Using Custom
When trying to rotate a custom certificate that wasn’t created by gardenlet
as part of the TLS Bootstrap, the x509 certificate’s
needs to conform to the following:
- the Common Name (CN) is prefixed with
- the Organization (O) equals
gardener-controller-manager doesn’t automatically
sign the CSR.
In this case, an external component or user needs to approve the CSR manually,
for example, using command
kubectl certificate approve seed-csr-<...>).
If that doesn’t happen within 15 minutes,
the gardenlet repeats the process and creates another CSR.
Configuring the Seed to work with
The Gardenlet works with a single seed, which must be configured in the
.seedConfig. This must be a copy of the
Seed resource, for example (see
for a more complete example):
apiVersion: gardenlet.config.gardener.cloud/v1alpha1 kind: GardenletConfiguration seedConfig: metadata: name: my-seed spec: provider: type: aws # ... secretRef: name: my-seed-secret namespace: garden
make start-gardenlet, the corresponding script will automatically
fetch the seed cluster’s
kubeconfig based on the
and set the environment accordingly.
On startup, gardenlet registers a
Seed resource using the given template
seedConfig if it’s not present already.
In the component configuration for the gardenlet, it’s possible to define:
- settings for the Kubernetes clients interacting with the various clusters
- settings for the control loops inside the gardenlet
- settings for leader election and log levels, feature gates, and seed selection or seed configuration.
More information: Example Gardenlet Component Configuration.
Similar to how Kubernetes uses
Lease objects for node heart beats
the gardenlet is using
Lease objects for heart beats of the seed cluster.
Every two seconds, the gardenlet checks that the seed cluster’s
endpoint returns HTTP status code 200.
If that is the case, the gardenlet renews the lease in the Garden cluster in the
gardener-system-seed-lease namespace and updates
GardenletReady condition in the
status.conditions field of the
Similarly to the
node-lifecycle-controller inside the
gardener-controller-manager features a
seed-lifecycle-controller that sets
GardenletReady condition to
Unknown in case the gardenlet fails to renew the lease.
As a consequence, the
gardener-scheduler doesn’t consider this seed cluster for newly created shoot clusters anymore.
The gardenlet includes an HTTPS server that serves a
It’s used as a liveness probe in the
Deployment of the gardenlet.
If the gardenlet fails to renew its lease
then the endpoint returns
500 Internal Server Error, otherwise it returns
Please note that the
/healthz only indicates whether the gardenlet
could successfully probe the Seed’s API server and renew the lease with
the Garden cluster.
It does not show that the Gardener extension API server (with the Gardener resource groups)
However, the Gardenlet is designed to withstand such connection outages and
retries until the connection is reestablished.
The gardenlet consists out of several controllers which are now described in more detail.
⚠️ This section is not necessarily complete and might be under construction.
BackupEntry controller reconciles those
core.gardener.cloud/v1beta1.BackupEntry resources whose
.spec.seedName value is equal to the name of a
Seed the respective gardenlet is responsible for.
Those resources are created by the
Shoot controller (only if backup is enabled for the respective
Seed) and there is exactly one
The controller creates an
extensions.gardener.cloud/v1alpha1.BackupEntry resource (non-namespaced) in the seed cluster and waits until the responsible extension controller reconciled it (see this for more details).
The status is populated in the
core.gardener.cloud/v1beta1.BackupEntry resource has an owner reference pointing to the corresponding
Hence, if the
Shoot is deleted, also the
BackupEntry resource gets deleted.
In this case, the controller deletes the
extensions.gardener.cloud/v1alpha1.BackupEntry resource in the seed cluster and waits until the responsible extension controller has deleted it.
Afterwards, the finalizer of the
core.gardener.cloud/v1beta1.BackupEntry resource is released so that it finally disappears from the system.
Keep Backup for Deleted Shoots
In some scenarios it might be beneficial to not immediately delete the
BackupEntrys (and with them, the etcd backup) for deleted
In this case you can configure the
.controllers.backupEntry.deletionGracePeriodHours field in the component configuration of the gardenlet.
For example, if you set it to
48, then the
BackupEntrys for deleted
Shoots will only be deleted
48 hours after the
Shoot was deleted.
Additionally, you can limit the shoot purposes for which this applies by setting
For example, if you set it to
[production] then only the
.spec.purpose=production will be deleted after the configured grace period. All others will be deleted immediately after the
Gardener users can use shoot clusters as seed clusters, so-called “managed seeds” (aka “shooted seeds”),
By default, the gardenlet that manages this shoot cluster then automatically
creates a clone of itself with the same version and the same configuration
that it currently has.
Then it deploys the gardenlet clone into the managed seed cluster.
If you want to prevent the automatic gardenlet deployment,
seedTemplate section in the
ManagedSeed resource, and don’t specify
In this case, you have to deploy the gardenlet on your own into the seed cluster.
More information: Register Shoot as Seed
Migrating from Previous Gardener Versions
If your Gardener version doesn’t support gardenlets yet, no special migration is required, but the following prerequisites must be met:
- Your Gardener version is at least 0.31 before upgrading to v1.
- You have to make sure that your garden cluster is exposed in a way that it’s reachable from all your seed clusters.
With previous Gardener versions, you had deployed the Gardener Helm chart
(incorporating the API server,
controller-manager, and scheduler).
With v1, this stays the same, but you now have to deploy the gardenlet Helm chart as well
into all of your seeds (if they aren’t managed, as mentioned earlier).
More information: Deploy a Gardenlet for all instructions.
Was this page helpful?