Gardener: hosted control planes for homogeneous Kubernetes clusters
Homogeneous Kubernetes clusters at scale on any infrastructure using hosted control planes.
At a glance
- What is it?
- Gardener is a Kubernetes-native cluster management system that runs shoot control planes inside seed clusters instead of dedicated master VMs. It suits platform teams that need the same cluster bill of material on every infrastructure, and it is heavy for anyone managing a handful of clusters.
- Who is it for?
- Adopt Gardener if you operate many Kubernetes clusters across several infrastructures and want one declarative Shoot specification to produce the same bill of material everywhere, and if you can run a garden cluster plus at least one seed. Do not adopt it for a single cluster, for a team without Kubernetes controller experience, or if you need a managed control plane you do not operate yourself.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Gardener solves: one cluster recipe across many infrastructures
Provisioning Kubernetes is a solved problem in isolation. Doing it the same way on AWS, Azure, and an on-premise OpenStack, and keeping those clusters identical after three years of upgrades, is not. Gardener's answer is an API of its own. The README describes it as "100% Kubernetes-native" and states that it "exposes its own Cluster API to create homogeneous clusters on all supported infrastructures". The distinction it draws against SIG Cluster Lifecycle's Cluster API is explicit: that project harmonizes how you get to a cluster, while Gardener's Shoot API "goes one step further and also harmonizes the make-up of the clusters themselves".
The audience follows from that. This is a tool for platform teams running a fleet, where the unit of work is a declarative Shoot specification rather than a Terraform module per environment. The README's own mapping table is the clearest statement of intent: Kubernetes API Server maps to Gardener API Server, Controller Manager to Gardener Controller Manager, Scheduler to Gardener Scheduler, Kubelet to Gardenlet, Node to Seed cluster, Pod to Shoot cluster. If that analogy reads as obvious to you, you are the target user. If it reads as an unnecessary layer, you probably are not.
Shoot, seed, garden: how the three-tier control plane actually fits together
Gardener is an extension API server plus a bundle of custom controllers. It introduces new API objects into an existing Kubernetes cluster called the garden cluster. Those objects describe end-user clusters called shoots, and the README gives a concrete pointer to what a shoot looks like: a declarative cluster specification in example/90-shoot.yaml. Controllers observe those objects, bring the clusters up, reconcile state, and perform automated updates.
The architectural decision that separates Gardener from most open source provisioners is where the control plane runs. Gardener manages etcd, the API server, the controller manager, and the scheduler for each shoot, and hosts those components as native Kubernetes workloads inside seed clusters. The README calls this the kubeception or inception design, and notes the consequence directly: shoot clusters have no dedicated master VMs. The stated benefits are lower total cost of ownership and easier day-2 operations, because updates and robustness handling can reuse Kubernetes primitives that already exist rather than bespoke tooling.
That has a real operational shape. A seed is itself a Kubernetes cluster, so its own health, capacity, and upgrade cadence become part of your shoot availability story. The repository reflects the layering: cmd/ holds the binaries, pkg/ holds the controller logic, extensions/ holds provider integrations, and charts/ holds the deployment manifests. The Dockerfile builds separate images for gardener-apiserver, gardener-controller-manager, gardener-scheduler, gardenlet, gardenadm, gardener-admission-controller, gardener-resource-manager, and gardener-node-agent, which tells you the system is a set of cooperating processes rather than one daemon.
Installing Gardener and creating a first Shoot
The repository does not present itself as a single-command install. The README links to the architecture documentation and the project site at gardener.cloud for concepts, and the top-level tree contains a dev-setup/ directory alongside a Makefile, which is where local development and build instructions live. There is no published helm install line in the repository's README, so treat the following as the build and deployment path the repository exposes rather than a turnkey installer.
Building the binaries uses the Makefile target the Dockerfile itself invokes. The Dockerfile passes EFFECTIVE_VERSION and the target OS and architecture through to make:
make build EFFECTIVE_VERSION=$EFFECTIVE_VERSION GOOS=$TARGETOS GOARCH=$TARGETARCH BUILD_OUTPUT_FILE="/output/bin/"After that runs, /output/bin/ contains the binaries the image stages copy: gardener-apiserver, gardener-controller-manager, gardener-scheduler, gardenlet, gardenadm, gardener-admission-controller, gardener-resource-manager, and gardener-node-agent. The Makefile exports a pinned toolchain, GOTOOLCHAIN := go1.26.8, so the build uses that Go version regardless of what is on your PATH.
For a container-based deployment, the Dockerfile defines one target per component. The gardenlet stage is representative:
FROM distroless-static AS gardenlet
COPY --from=builder /output/bin/gardenlet /gardenlet
WORKDIR /
ENTRYPOINT ["/gardenlet"]Each component is a separate image built from a distroless static base and runs as a non-root user. If you are deploying from published images rather than building, the Makefile records the registry the project publishes to: europe-docker.pkg.dev/gardener-project/snapshots/gardener, with per-component repositories such as apiserver, controller-manager, scheduler, gardenlet, and gardenadm beneath it.
Once a garden cluster and a seed exist, the first real object you create is a Shoot. The example directory is the working reference: example/90-shoot.yaml for the cluster specification, example/30-cloudprofile.yaml for the provider and region definition a shoot refers to, and example/40-secret-seed.yaml plus example/45-secret-seed-backup.yaml for seed credentials. Configuration for the components lives in files such as example/20-componentconfig-gardenlet.yaml and example/20-componentconfig-gardener-controller-manager.yaml. Read those before writing your own; they are the only component configuration examples the repository ships.
Where Gardener is the wrong tool
The hosted control plane design is a bet on a seed cluster you operate. If the seed is unhealthy or out of capacity, shoots hosted on it are affected, and the README does not describe an automatic evacuation mechanism. That is a different failure domain from a provisioner that creates standalone control plane nodes per cluster, where one cluster's problems stay inside that cluster.
The second constraint is scope. Gardener's value proposition is homogeneity across many infrastructures. If you run two clusters on one cloud, the extension framework, the garden cluster, the seed, and the controller set are overhead you will pay for without collecting the return. A plain managed Kubernetes service or a lighter provisioner will get you further with less to operate.
The third is provider coverage. Gardener supports what has an extension. The repository carries an extensions/ directory and example/30-cloudprofile.yaml, and the README describes the framework as adjustable to any programmatic cloud or infrastructure provider. That is a statement about extensibility, not about a specific provider being available today. The README does not list supported providers in the section above, so check the extensions directory and the project site before assuming your infrastructure is covered.
Finally, the version matrix is a moving target. The conformance table in the README shows AWS, Azure, and other providers across Kubernetes versions, with N/A entries where a provider and version combination has no result. The repository also carries supported-kubernetes-versions.yaml at the top level. If you must run a specific Kubernetes version, that file and the conformance grid are what you check, not the general claim of conformance.
How Gardener differs from Cluster API and from managed control planes
The nearest alternative is SIG Cluster Lifecycle's Cluster API, and the README addresses the comparison head on. Cluster API standardizes the path to a cluster. Gardener standardizes the cluster itself, so that the bill of material, configuration, and behavior match across infrastructures. If your problem is "provisioning is inconsistent per provider", Cluster API plus per-provider templates may be enough. If your problem is "the clusters we end up with are not the same", that is the gap Gardener targets.
The README notes that Cluster API v1alpha3 added declarative control plane management, which made it possible to integrate managed services like GKE or Gardener, and states the project would be happy to contribute a Gardener control plane provider if the community is interested. That provider is described as a possibility, not as something shipping in this repository. Do not plan around it.
The other alternative is a fully managed control plane you never operate. There, the provider runs the API server and etcd and you receive a kubeconfig. Gardener gives you the declarative API and the reconciliation model, but you run the garden cluster and the seeds. The trade is control and homogeneity against operational surface area. There is no free option in that trade; the README's cost argument for kubeception is about avoiding dedicated master VMs, not about avoiding the seed.
Maintenance, release cadence, and licence
The repository is not archived, and the last push was on 2026-09-23. Recent releases in the repository are v1.151.1 on 2026-09-19, v1.151.0 on 2026-09-10, and v1.149.4 on 2026-09-07. Patch releases on the previous minor line, v1.149.4, sit alongside the current v1.151 line, which indicates that older lines receive fixes for a period. The README does not state a support window or an end-of-life policy for a given minor version, so if you need a guaranteed upgrade path, that is a question for the project's release documentation rather than the README.
Upgrade cost is the part worth weighing before adoption. Gardener manages etcd, API server, controller manager, and scheduler for every shoot, and it performs automated updates of those components. That means a Gardener upgrade can move many clusters at once. The version matrix in the README shows conformance results per Kubernetes version, and the repository pins a Go toolchain of go1.26.8 for builds. Neither of those tells you how a running landscape behaves during an upgrade. The README does not document rollback, so verify the upgrade and rollback procedure against the project's own documentation before you depend on it.
Licensing is Apache-2.0, and the repository carries REUSE.toml, LICENSES/, NOTICE.md, and a REUSE status badge, so file-level licence metadata is part of the project's process. Apache-2.0 is permissive and includes an explicit patent grant. That is a description of the licence, not legal advice; your own review decides whether it fits your distribution model, particularly if you modify and redistribute the components.
Editorial conclusion
Adopt Gardener if you operate many Kubernetes clusters across several infrastructures and want one declarative Shoot specification to produce the same bill of material everywhere, and if you can run a garden cluster plus at least one seed. Do not adopt it for a single cluster, for a team without Kubernetes controller experience, or if you need a managed control plane you do not operate yourself. Before committing, verify which infrastructure providers have extensions you trust, check the supported-kubernetes-versions.yaml file against the versions you must run, and confirm that the Apache-2.0 licence and the REUSE metadata in the repository satisfy your compliance process.
Frequently asked questions
What is Gardener in the Kubernetes sense?
It is an extension API server plus a set of custom controllers that manage Kubernetes clusters as a service. It introduces its own API objects into a garden cluster to describe end-user shoot clusters, and it hosts the shoot control plane components inside seed clusters.
How do I install Gardener?
The repository exposes a Makefile build, and the Dockerfile calls make build with EFFECTIVE_VERSION, GOOS, GOARCH, and BUILD_OUTPUT_FILE to produce the component binaries. The Dockerfile then defines one image target per component on a distroless static base. The README does not give a single install command; it points to the project site and the architecture documentation for concepts.
How is Gardener's Cluster API different from SIG Cluster Lifecycle's Cluster API?
The README states that Cluster API harmonizes how to get to clusters, while Gardener's Shoot API also harmonizes the make-up of the clusters themselves. The result is homogeneous clusters with the same bill of material, configuration, and behavior across supported infrastructures.
Does Gardener give each cluster its own master VMs?
No. The README states that shoot clusters do not have dedicated master VMs. The control plane components, including etcd, the API server, the controller manager, and the scheduler, are deployed as native Kubernetes workloads into seed clusters, a design the README calls kubeception or inception.
Which Kubernetes versions is Gardener certified for?
The README states that Gardener is certified for K8s versions up to v1.35, with continuous conformance results uploaded to the CNCF test grid per provider and version. The repository also carries supported-kubernetes-versions.yaml, which is the file to check for the versions a given release supports.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gardener-gardener)