Skip to content

Commit ff03634

Browse files
committed
Add examples of a full feature lifecycles
1 parent 8694b15 commit ff03634

File tree

1 file changed

+92
-54
lines changed
  • keps/sig-architecture/4330-compatibility-versions

1 file changed

+92
-54
lines changed

keps/sig-architecture/4330-compatibility-versions/README.md

Lines changed: 92 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ tags, and then generate with `hack/update-toc.sh`.
8484
- [Non-Goals](#non-goals)
8585
- [Proposal](#proposal)
8686
- [Component Flags](#component-flags)
87-
- [Feature Compatibility Versioning](#feature-compatibility-versioning)
87+
- [Changes to Feature Gates](#changes-to-feature-gates)
88+
- [Feature Gate Lifespans](#feature-gate-lifespans)
8889
- [CEL Environment Compatibility Versioning](#cel-environment-compatibility-versioning)
8990
- [StorageVersion Compatibility Versioning](#storageversion-compatibility-versioning)
9091
- [API Compatibility Versioning](#api-compatibility-versioning)
@@ -224,32 +225,99 @@ Kubernetes components (apiservers, controller managers, schedulers) will offer a
224225
minor versions. If unset, the compatibility version defaults to the `<major.minor>`
225226
version of the binary version.
226227

227-
### Feature Compatibility Versioning
228+
### Changes to Feature Gates
228229

229-
Features will be versioned, i.e.:
230+
Features will track version information, i.e.:
230231

231232
```go
232-
type FeatureSpec struct {
233-
//...
234-
235-
// Version indicates the version this feature spec was introduced.
236-
Version semver.Version
237-
}
233+
map[Feature]VersionedSpecs{
234+
featureA: VersionedSpecs{
235+
{Version: mustParseVersion("1.27"), Default: false, PreRelease: Beta},
236+
{Version: mustParseVersion("1.28"), Default: true, PreRelease: GA},
237+
},
238+
featureB: VersionedSpecs{
239+
{Version: mustParseVersion("1.28"), Default: false, PreRelease: Alpha},
240+
},
241+
featureC: VersionedSpecs{
242+
{Version: mustParseVersion("1.28"), Default: false, PreRelease: Beta},
243+
},
244+
featureD: VersionedSpecs{
245+
{Version: mustParseVersion("1.26"), Default: false, PreRelease: Alpha},
246+
{Version: mustParseVersion("1.28"), Default: true, PreRelease: Deprecated},
247+
}
238248
```
239249
240250
When a component starts, feature gates will be compared against the
241251
compatibility version to determine which features to enable to match the set of
242252
features that where enabled for the Kubernetes version the compatibility version
243253
is set to.
244254
245-
Also, `--feature-gates` must behave the same as it did for the Kubernetes
255+
#### Feature Gate Lifespans
256+
257+
`--feature-gates` must behave the same as it did for the Kubernetes
246258
version the compatibility version is set to. I.e. it must be possible to use
247259
`--feature-gates` to disable features that were beta, and enable feature that
248260
were alpha in the Kubernetes version the compatibility version is set to. One
249261
important implication of this requirement is that feature gating must be kept in
250262
the Kubenetes codebase until a feature has reached GA (or been removed) for N-3
251263
releases.
252264
265+
For example, a feature that is promoted once per release would look something like:
266+
267+
```go
268+
map[Feature]VersionedSpecs{
269+
featureA: VersionedSpecs{
270+
{Version: mustParseVersion("1.26"), Default: false, PreRelease: Alpha},
271+
{Version: mustParseVersion("1.27"), Default: true, PreRelease: Beta},
272+
{Version: mustParseVersion("1.28"), Default: true, PreRelease: GA},
273+
},
274+
}
275+
```
276+
277+
The lifecycle of the feature would be:
278+
279+
| Release | Stage | Feature tracking information |
280+
| ------- | ----- | ------------------------------------------------- |
281+
| 1.26 | alpha | Alpha: 1.26 |
282+
| 1.27 | beta | Alpha: 1.26, Beta: 1.27 (on-by-default) |
283+
| 1.28 | GA | Alpha: 1.26, Beta: 1.27 (on-by-default), GA: 1.28 |
284+
| 1.29 | GA | Alpha: 1.26, Beta: 1.27 (on-by-default), GA: 1.28 |
285+
| 1.30 | GA | Alpha: 1.26, Beta: 1.27 (on-by-default), GA: 1.28 |
286+
| 1.31 | GA | **Feature implementation becomes part of normal code, Feature gate and feature tracking information may be removed from code** |
287+
288+
All feature gating and tracking must remain in code through 1.30 for N-3
289+
compatibility version support.
290+
291+
For a feature that is removed, e.g.:
292+
293+
```go
294+
map[Feature]VersionedSpecs{
295+
featureA: VersionedSpecs{
296+
{Version: mustParseVersion("1.26"), Default: false, PreRelease: Alpha},
297+
{Version: mustParseVersion("1.27"), Default: false, PreRelease: Deprecated},
298+
{Version: mustParseVersion("1.31"), Default: false, PreRelease: Removed},
299+
},
300+
}
301+
```
302+
303+
The lifecycle of the feature implementation would be:
304+
305+
| Release | Stage | Feature tracking information |
306+
| ------- | ----- | ------------------------------------------------- |
307+
| 1.26 | alpha | Alpha: 1.26 |
308+
| 1.27 | alpha | Alpha: 1.26, Deprecated: 1.27 |
309+
| 1.28 | alpha | Alpha: 1.26, Deprecated: 1.27 |
310+
| 1.29 | alpha | Alpha: 1.26, Deprecated: 1.27 |
311+
| 1.30 | - | Alpha: 1.26, Deprecated: 1.27, Removed: 1.31 |
312+
| 1.31 | - | Alpha: 1.26, Deprecated: 1.27, Removed: 1.31 |
313+
| 1.32 | - | Alpha: 1.26, Deprecated: 1.27, Removed: 1.31 |
314+
| 1.33 | - | **Feature implementation and feature tracking information may be removed from code** |
315+
316+
Note that this respects a 1yr deprecation policy.
317+
318+
All feature gating and tracking must remain in code through 1.32 for N-3
319+
compatibility version support.
320+
253321
### CEL Environment Compatibility Versioning
254322
255323
CEL environments already [support a compatibility
@@ -328,7 +396,8 @@ depend on the feature.
328396
329397
- For each control plane component, in the [recommended
330398
order](https://kubernetes.io/releases/version-skew-policy/):
331-
- sets `--compatibility-version=1.30`
399+
- Cluster admin restarts the component with `--compatibility-version=1.30` set
400+
-
332401
333402
This avoids having to rollback the binary version. Once the workload is fixed, the
334403
cluster administrator can remove the `--compatibility-version` to roll the cluster
@@ -608,62 +677,31 @@ This section must be completed when targeting alpha to a release.
608677
609678
###### How can this feature be enabled / disabled in a live cluster?
610679
611-
<!--
612-
Pick one of these and delete the rest.
613-
614-
Documentation is available on [feature gate lifecycle] and expectations, as
615-
well as the [existing list] of feature gates.
616-
617-
[feature gate lifecycle]: https://git.k8s.io/community/contributors/devel/sig-architecture/feature-gates.md
618-
[existing list]: https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
619-
-->
620-
621680
- [ ] Feature gate (also fill in values in `kep.yaml`)
622-
- Feature gate name:
681+
- Feature gate name: CompatibilityVersions
623682
- Components depending on the feature gate:
624-
- [ ] Other
625-
- Describe the mechanism:
626-
- Will enabling / disabling the feature require downtime of the control
627-
plane?
628-
- Will enabling / disabling the feature require downtime or reprovisioning
629-
of a node?
683+
- kube-apiserver
684+
- kube-controller-manager
685+
- kube-scheduler
686+
630687
631688
###### Does enabling the feature change any default behavior?
632689
633-
<!--
634-
Any change of default behavior may be surprising to users or break existing
635-
automations, so be extremely careful here.
636-
-->
690+
No. Only when the feature gate is enabled AND `--compatibility-version` is set
691+
does behavior change.
637692
638693
###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
639694
640-
<!--
641-
Describe the consequences on existing workloads (e.g., if this is a runtime
642-
feature, can it break the existing applications?).
643-
644-
Feature gates are typically disabled by setting the flag to `false` and
645-
restarting the component. No other changes should be necessary to disable the
646-
feature.
647-
648-
NOTE: Also set `disable-supported` to `true` or `false` in `kep.yaml`.
649-
-->
695+
Yes. Once disabled, the component ignores any `--compatibility-version` value
696+
and operates normally at the current binary version.
650697
651698
###### What happens if we reenable the feature if it was previously rolled back?
652699
653-
###### Are there any tests for feature enablement/disablement?
700+
Behavior is as expected, `--compatibility-version` is again applied.
654701
655-
<!--
656-
The e2e framework does not currently support enabling or disabling feature
657-
gates. However, unit tests in each component dealing with managing data, created
658-
with and without the feature, are necessary. At the very least, think about
659-
conversion tests if API types are being modified.
702+
###### Are there any tests for feature enablement/disablement?
660703
661-
Additionally, for features that are introducing a new API field, unit tests that
662-
are exercising the `switch` of feature gate itself (what happens if I disable a
663-
feature gate after having objects written with the new field) are also critical.
664-
You can take a look at one potential example of such test in:
665-
https://github.com/kubernetes/kubernetes/pull/97058/files#diff-7826f7adbc1996a05ab52e3f5f02429e94b68ce6bce0dc534d1be636154fded3R246-R282
666-
-->
704+
Yes, feature enablement/disablement will be fully tested in Alpha.
667705
668706
### Rollout, Upgrade and Rollback Planning
669707

0 commit comments

Comments
 (0)