Skip to content

Commit

Permalink
Add paragraph about adding tags on API types
Browse files Browse the repository at this point in the history
Signed-off-by: joshvanl <vleeuwenjoshua@gmail.com>
JoshVanL committed Jan 18, 2022
1 parent 80c786d commit 24dfdc0
Showing 1 changed file with 36 additions and 25 deletions.
61 changes: 36 additions & 25 deletions design/20220118.server-side-apply.md
Original file line number Diff line number Diff line change
@@ -45,43 +45,46 @@ Server Side Apply works by the client sending a PATCH API request with a
instructs which field manager to use (or alternatively, will be derived from the
client's user agent). This API call tells the API server that the client wishes
to manage and set the fields and values of the resource (or alternatively remove
managed fields which are omitted) as the appear in the body, that have the field
manager name `<my-field-manager>` (or user agent equivalent).
managed fields which are omitted) as they appear in the body. A client's managed
fields are defined as the fields that are labelled with the client's manager
name `<my-field-manager>` (or client's user agent equivalent).

Server Side Apply is is useful for cert-manager for 2 reasons:

### Conflicts

cert-manager controllers, namely the certificates controllers, where multiple
controllers are writing to the same resource type, lead to cases where UPDATE
operations result in resource version conflicts. This results in error logs
that regularly confuse users and miss-attribute the problem they are having, as
well as needless re-queuing churn through the controller slowing cert-manager
down.
cert-manager controllers, namely the certificates controllers, have multiple
controllers that are writing to the same resource type. This leads to cases
where UPDATE operations result in resource version conflicts. This in turn,
results in error logs that regularly confuse users and miss-attribute the
problem they are having, as well as needless re-queuing churn through the
controller, slowing cert-manager down.

### Deleting Fields

Without Server Side Apply, it is difficult for cert-manager to reason about some
fields that should be _deleted_ on an UPDATE operation during reconciliation.
One such example are Certificate SecretTemplate's Annotations and Labels. If a
key was removed from either field on the Certificate, the next reconciliation
would not know which keys should be preserved or removed (as they may have been
annotated or labelled from a third party).

Managed fields define ownership of these fields, therefore cert-manager is able
to observe a discrepancy due to a previous Certificate state and perform another
apply (omitting those keys), resulting in those fields being removed. Without
managed fields, cert-manager would have to create a third state store in either
annotations or status fields on that resource.

key was removed from either the Annotation or Label field on the SecretTemplate,
the next reconciliation would not know which keys should be preserved or removed
(as they may have been annotated or labelled from a third party). This problem
occurs in several places where copying or transforming state from one resource
to another happens.

Managed fields define ownership of applied fields. cert-manager is therefore
able to observe a discrepancy occurring from, for example, a previous
SecretTemplate state and performing another apply (omitting those keys),
resulting in those fields being removed on the Secret. Without managed fields,
cert-manager would have to create a third state store in either annotations or
status fields on that resource.

## Field Manager and User Agent

Field Manager is a string denoting the manager who owns a field or set of fields
on a resource. This string is set by the client at API call time and is
The Field Manager is a string denoting the manager who owns a field or set of
fields on a resource. This string is set by the client at API call time and is
derived by either the client setting the `fieldManager` URL query explicitly, or
calculated from the client's user agent ([characters preceding the first /, quote
unprintable character and then trim what's beyond the 128
calculated from the client's user agent ([characters preceding the first "/",
quote unprintable characters and then trim what's beyond the 128
limit](https://github.com/kubernetes/kubernetes/blob/9a75e7b0fd1b567f774a3373be640e19b33e7ef1/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go#L252)).

cert-manager will use a consistent naming scheme for both the user agent prefix
@@ -127,14 +130,14 @@ cert-manager-certificates-issuing/v1.7.0 (Linux/amd64) cert-manager/0b686b8f38c8

All CREATE and UPDATE operations in cert-manager controllers are to be replaced
with APPLY. For this change, controllers will need to be modified so that for
these call, _only_ the fields in which they manage should be included in the
these calls, _only_ the fields in which they manage should be included in the
PATCH API call. This means each controller will need to define exactly which
fields they are concerned with.

Some fields, such as the Certificate Issuing Condition are managed by more than
one controller (issuing and trigger Certificate controllers), and as such, will
need to make use of the `force` option in their API calls. This option tells the
API server to revoke managment of that field from the previous owner, overwrite
API server to revoke management of that field from the previous owner, overwrite
the field, and change owner ship to the new client.

The [fake client-go client](https://github.com/kubernetes/client-go/issues/970)
@@ -144,6 +147,14 @@ testing against a real API server as integration tests, the controller
[test framework must add custom support for Apply](https://github.com/jetstack/cert-manager/blob/master/pkg/controller/test/context_builder.go),
or a new testing framework should be developed.

Some API fields will need to have some metadata updated to function better under
Server Side Apply. One such example is adding `x-kubernetes-list-type=map` and
`x-kubernetes-list-map-keys=Type` to the [Certificates Status Condition
slice](https://github.com/jetstack/cert-manager/blob/0ca1ce9a6a1d7c311afd4b3e786975759249132a/pkg/apis/certmanager/v1/types_certificate.go#L385),
so that controllers are able to apply distinct condition types, without
conflicting with other controller conditions (i.e. the Ready and Issuing
conditions).

## Feature Gate

Placing the APPLY functionality behind a feature gate should be considered.
@@ -153,4 +164,4 @@ regressions in the stability of controller reconciliation.

To reach graduation, the cert-manager authors should consider the server side
apply implementation for cert-manager to be safe for end users. Graduation
should ideally be done over no more than a release or 2.
should ideally be done over no more than one or two releases.

0 comments on commit 24dfdc0

Please sign in to comment.