-
Notifications
You must be signed in to change notification settings - Fork 73
📖 Add ClusterObjectSet documentation #2615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,393 @@ | ||||||
| # ClusterObjectSets | ||||||
|
|
||||||
| This document explains what ClusterObjectSets are, how they enable safe phased rollouts of Kubernetes resources, and how operator-controller uses them to manage ClusterExtensions. | ||||||
|
|
||||||
| ## What is a ClusterObjectSet? | ||||||
|
|
||||||
| A `ClusterObjectSet` is a cluster-scoped Kubernetes API that represents a versioned set of Kubernetes resources organized into ordered phases. It provides a declarative way to roll out a group of related resources sequentially, with built-in readiness checks between phases. | ||||||
|
|
||||||
| The revision content — the `revision` number, `collisionProtection` strategy, and `phases` (including all objects within them) — is immutable once set. This guarantees that the record of what was deployed at a given revision cannot change after creation. Other fields like `lifecycleState` can change over the object's lifecycle (e.g. transitioning from `Active` to `Archived`), and optional fields like `progressDeadlineMinutes` and `progressionProbes` can be configured independently. | ||||||
|
|
||||||
| Each ClusterObjectSet has: | ||||||
|
|
||||||
| - A **revision number** — an immutable, sequential integer that identifies the version | ||||||
| - A **lifecycle state** — either `Active` (being reconciled) or `Archived` (inactive); transitions from Active to Archived but not back | ||||||
| - A list of **phases** — immutable, ordered groups of Kubernetes objects that are applied sequentially | ||||||
| - A **collision protection** strategy — immutable, controlling how pre-existing objects are handled | ||||||
| - **Status conditions** — reporting rollout progress, availability, and success | ||||||
|
|
||||||
| ClusterObjectSets can be used by any controller or system that needs to manage the rollout of a set of Kubernetes resources in a controlled, phased manner. Within OLM, the operator-controller uses ClusterObjectSets as the mechanism to deploy and upgrade ClusterExtensions. | ||||||
|
|
||||||
| ## Why ClusterObjectSets? | ||||||
|
|
||||||
| ClusterObjectSets solve several problems that arise when managing sets of related Kubernetes resources: | ||||||
|
|
||||||
| - **Immutable revision content** — The revision number, phases, objects, and collision protection strategy are immutable once set, providing a clear, auditable record of exactly what was deployed at each revision. There is no ambiguity about what resources belong to a given version. | ||||||
| - **Phased rollout** — Resources are grouped into phases (e.g. CRDs before Deployments) and applied sequentially. A phase only progresses after all its objects pass readiness probes, preventing partially-applied states. | ||||||
| - **Safe transitions** — During a revision change, both the old and new revisions remain active until the new revision fully rolls out. Object ownership transitions from one revision to the next, ensuring no resource is left unmanaged. | ||||||
| - **Single ownership** — Each Kubernetes resource can only be managed by one ClusterObjectSet at a time. This prevents conflicts between revisions fighting over the same object. | ||||||
| - **Large resource support** — Object manifests can be stored inline or externalized into Secrets via references, allowing ClusterObjectSets to manage bundles that would otherwise exceed etcd's 1.5 MiB object size limit. | ||||||
|
|
||||||
| ## Lifecycle | ||||||
|
|
||||||
| ### Active state | ||||||
|
|
||||||
| When a ClusterObjectSet is `Active`, the controller actively reconciles it using the [boxcutter](https://github.com/package-operator/boxcutter) library: | ||||||
|
|
||||||
| - Phases are applied sequentially, each waiting for readiness before proceeding | ||||||
| - Objects are managed via server-side apply | ||||||
| - Status conditions are updated to reflect rollout progress | ||||||
|
|
||||||
| ### Revision transitions | ||||||
|
|
||||||
| When transitioning from one revision to the next: | ||||||
|
|
||||||
| 1. A new ClusterObjectSet is created with the next sequential revision number | ||||||
| 2. Both old and new revisions remain `Active` during the transition | ||||||
| 3. Objects transition ownership from the old revision to the new one | ||||||
| 4. Once the new revision reports `Succeeded`, the old revision can be archived | ||||||
|
|
||||||
| ### Archival | ||||||
|
|
||||||
| When a revision's lifecycle state is set to `Archived`: | ||||||
|
|
||||||
| - It is removed from the owner list of all previously managed objects | ||||||
| - Objects that did not transition to a succeeding revision are deleted | ||||||
| - The revision cannot be un-archived | ||||||
|
||||||
| - The revision cannot be un-archived | |
| - The revision cannot be unarchived |
Copilot
AI
Mar 31, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phase-ordering table is written with a double leading pipe (|| ... |), which renders as an extra empty column in standard Markdown. Use a single leading | for the header/separator/rows so the table has exactly the intended 3 columns.
perdasilva marked this conversation as resolved.
Show resolved
Hide resolved
perdasilva marked this conversation as resolved.
Show resolved
Hide resolved
perdasilva marked this conversation as resolved.
Show resolved
Hide resolved
perdasilva marked this conversation as resolved.
Show resolved
Hide resolved
perdasilva marked this conversation as resolved.
Show resolved
Hide resolved
Copilot
AI
Mar 31, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition tables under "Status conditions" are formatted with a double leading pipe (||), which adds an extra empty column in Markdown. Update these tables to use a single leading | so they render correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc says the revision content (including
phases) is immutable “once set” and implies it cannot change after creation. In the current API validation,spec.phasescan still be set/changed if the existing value is empty (XValidation: self == oldSelf || oldSelf.size() == 0). Consider clarifying this as “write-once after it becomes non-empty” (or documenting the exception) so the behavior matches the API.