From 120e7b5744be65897f43e93fa5399fa71b3191a3 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 1 Feb 2019 16:40:17 -0800 Subject: [PATCH] Versioning policy --- docs/README.md | 3 + docs/versioningPolicy.md | 221 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 docs/versioningPolicy.md diff --git a/docs/README.md b/docs/README.md index 31c0acf45..fcbdd4eb3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,9 @@ [kustomization](glossary.md#kustomization) with explanations of each field. + * [versioning policy](versioningPolicy.md) - How the code and the kustomization + file evolve in time. + * [workflow](workflows.md) - Some steps one might take in using bespoke and off-the-shelf configurations. diff --git a/docs/versioningPolicy.md b/docs/versioningPolicy.md new file mode 100644 index 000000000..2f9a08ea5 --- /dev/null +++ b/docs/versioningPolicy.md @@ -0,0 +1,221 @@ +# Versioning + +Running `kustomize` means one is running a +particular version of a program, reading a +particular version of a [kustomization] file. + +## Program Versioning + +The command `kustomize version` prints a three +field version tag (e.g. `1.0.11`) that aspires to +[semantic versioning]. + +When enough changes have accumulated to +(subjectively) warrant a new release, +a [release process] is followed, and the +fields in the version number are bumped +per semver. + +## Kustomization File Versioning + +At the time of writing (circa release of v2.0.0): + + - A [kustomization] file is just a YAML file that + can be successfully parsed into a particular Go + struct defined in the `kustomize` binary. + + - This struct does not have a version number, + which is the same as saying that its version + number matches the program's version number, + since it's compiled in. + +### Field Change Policy + +- A field's meaning cannot be changed. + +- A field may be deprecated, then removed. + +- Deprecation means triggering a _minor_ (semver) + version bump in the program, and + defining a migration path in a non-fatal + error message. + +- Removal means triggering a _major_ (semver) + version bump, and fatal error if field encountered + (as with any unknown field). + +### The `edit fix` Command + +This `kustomize` command reads a Kustomization +file, converts deprecated fields to new +fields, and writes it out again in the latest +format. + +This is a type version upgrade mechanism that +works within _major_ program revisions. There is +no downgrade capability, as there's no use case +for it (see discussion below). + +### Examples + +At the time of writing, in v1.0.x, there were 12 +minor releases, with backward compatible +deprecations fixable via `edit fix`. + +With the 2.0.0 release, there were three field +removals: + +- `imageTag` was deprecated when `image` was + introduced, because the latter offers more + general features for image data manipulation. + `imageTag` was removed in v2.0.0. + +- `patches` was deprecated and replaced by + `PatchesStrategicMerge` when `PatchesJson6902` + was introduced, to make a clearer + distinction between patch specification formats. + `patches` was removed in v2.0.0. + +- `secretGenerator/commands` was removed + due to security concerns in v2.0.0 + with no deprecation period. + +The `edit fix` command in a v2.0.x binary +will no longer recognize these fields. + +## Relationship to the k8s API + +### Review of k8s API versioning + +The k8s API has specific [conventions] and a +process for making a [changes]. + +The presence of an `apiVersion` field in a k8s +native type signals: + + - its reliability level (alpha vs beta vs + generally available), + + - the existence of code to provide default values + to fields not present in a serialization, + + - the existence of code to provide both forward + and backward conversion between different + versions of types. + +The k8s API promises a lossless _conversion_ +between versions over a specific range. This +means that a recent client can write an object +bearing the newest possible value for its version, +the server will accept it and store it in +"versionless" JSON form in storage, and can +convert it to a range of older versions should +an older client request data. + +For native k8s types, this all requires writing Go +code in the kubernetes core repo, to provide +defaulting and conversions. + +For CRDs, there's a [proposal] on how to manage +versioning (e.g. a remote service can offer type +defaulting and conversions). + +### Kustomization file versioning + +The critical difference between k8s API versioning +and kustomization file versioning is + + - A k8s API server is able to go _forward_ and + _backward_ in versioning, to work with older + clients, over [some range]. + + - The `kustomize edit fix` command only moves + _forward_ within a _major_ program + version. + +At the time of writing, the YAML in a +kustomization file does not represent a [k8s API] +object, and the kustomize command and associated +library is neither a server of, nor a client to, +the k8s API. + +### Additional Kustomization file rules + +In addition to the [field change policy] described +above, kustomization files conform to +the following rules. + +#### Eschew classic k8s fields + +Field names with dedicated meaning in k8s +(`metadata`, `spec`, `status`, etc.) aren't used. + +This is enforced via code review. + +#### Optional use of k8s `kind` and `apiVersion` + +At the time of writing two [special] k8s +resource fields are allowed, but not required, in +a kustomization file: [`kind`] and [`apiVersion`]. + +If either field is present, they both must be, and +they must have the following values: + +``` +kind: Kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +``` + +They are allowed to exist and have specific values +in a kustomization file only as a sort of +domain-squatting behavior for some future API. A +kustomize user gains nothing from adding these +fields to a kustomization file. + +### Why not require `kind` and `apiVersion`? + +#### Ease of use and setting proper expectations + +Use cases for a kustomization file don't include a +server storing muliple k8s kinds and offering +version downgrades. + +The kustomization file is more akin to a +`Makefile`. A kustomize command can either read a +kustomization file, or it cannot, and in the later +case will complain as specifically as possible +about why (e.g. `unknown field Foo`). + +So requiring a `kind` and `apiVersion` would just +be boilerplate in a user's files, and in all the +examples and tests. + +Nevertheless, _a user still benefits from a +versioning policy_ and has a `fix` command to +upgrade files as needed. + +#### We can change our minds + +When/if the kustomization struct graduates to some +kind of API status, with an expectation of +"versionless" storage and downgrade capability, +whatever it looks like at that moment can be +locked into `/v1beta1` or `/v1` and the `kind` +and `apiVersion` fields can be required from that +moment forward. + + +[field change policy]: #field-change-policy +[some range]: https://kubernetes.io/docs/reference/using-api/deprecation-policy +[proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/customresources-versioning.md +[beta-level rules]: https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md#alpha-beta-and-stable-versions +[changes]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md +[adapt]: https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/types/kustomization.go#L166 +[special]: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#resources +[k8s API]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md +[conventions]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md +[release process]: ../build/README.md +[kustomization]: glossary.md#kustomization +[`kind`]: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#types-kinds +[`apiVersion`]: https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning +[semantic versioning]: https://semver.org