Skip to content

Commit

Permalink
Update api concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
jennybuckley committed Mar 12, 2019
1 parent d60533d commit 98fc96c
Showing 1 changed file with 37 additions and 38 deletions.
75 changes: 37 additions & 38 deletions content/en/docs/reference/using-api/api-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,23 +317,29 @@ Some values of an object are typically generated before the object is persisted.
* Any field set by a mutating admission controller
* For the `Service` resource: Ports or IPs that kube-apiserver assigns to v1.Service objects


## Server Side Apply

Server Side Apply (SSA) is offering an apply path on the apiserver side of kubernetes instead of the previous/current Client Side Apply (CSA) that happens in kubectl.
{{< feature-state for_k8s_version="v1.14" state="alpha" >}} Server Side Apply allows clients other than kubectl to perform the Apply operation, and will eventually fully replace the complicated Client Side Apply logic that only exists in kubectl. If the Server Side Apply feature is enabled, The `PATCH` endpoint will accept the additional `application/apply-patch+yaml` content type.

Compared to the `last-applied` annotation managed by `kubectl`, Server Side Apply uses a more declarative approach, which tracks a user's field management, rather than a user's last applied state. This means that as a side effect of using Server Side Apply, information about which field manager manages each field in an object also becomes available.


*Note:* This is an alpha feature and needs to be enabled by setting the related (Feature Gate)[docs/reference/command-line-tools-reference/feature-gates.md].
### Enable the Server Side Apply alpha feature

### Concepts
Server Side Apply is an alpha feature, so it is disabled by default. To turn this [feature gate](/docs/reference/command-line-tools-reference/feature-gates.md) on,
you need to:

With SSA we replace the current `last-applied` annotation managed by `kubectl` with a more declarative approach to keep track of field ownership.
This means, when using SSA we assign ownership of fields to the applier (`fieldManager`).
* Include "ServerSideApply=true" in the `--feature-gates` flag when starting
`kube-apiserver`. If you have multiple `kube-apiserver` replicas, all should
have the same flag setting.

#### Field Ownership

Owning a field in the SSA context means, the subject who last changed the field will be recorded as the current field owner.
Any other subject that tries to change the field, will get its request rejected (if not forced, see Forcing changes below).
### Field Management

Field ownership is stored in a newly introduced field that is part of the objects `metadata`.
For a user to manage a field, in the Server Side Apply sense, means that the user relies on and expects the value of the field not to change. The user who last made an assertion about the value of a field will be recorded as the current field manager. This can be done either by changing the value with `POST`, `PUT`, or non-apply `PATCH`, or by including the field in a config sent to the Server Side Apply endpoint. Any applier that tries to change the field which is managed by someone else will get its request rejected (if not forced, see the Conflicts section below).

Field management is stored in a newly introduced `managedFields` field that is part of an object's [`metadata`](/docs/reference/generated/kubernetes-api/v1.14/#objectmeta-v1-meta).

A simple example looks like this:

Expand All @@ -346,7 +352,7 @@ metadata:
labels:
test-label: test
managedFields:
- manager: apply
- manager: kubectl
operation: Apply
apiVersion: v1
fields:
Expand All @@ -359,19 +365,18 @@ data:
key: new value
```
The above object contains a manager in `metadata.managedFields`. The manager object consists of basic information about the managing entity itself, like operation type, api version
and eventually the fields managed by it.
The above object contains a manager in `metadata.managedFields`. The manager object consists of basic information about the managing entity itself, like operation type, api version, and the fields managed by it.

Note that this field is managed by the apiserver and should not be changed by the user.

Note that this field is managed by the apiserver itself and should not get changed by the user (while possible through a non-SSA PATCH).

#### Operations
### Operations

The operation mainly implemented by this feature, is `Apply`(`application/apply-patch+yaml`). Other operations like the current `Update`(`application/merge-patch+json`) will update the
`managedFields` as well, but behave a little differently.
The two operation types considered by this feature are `Apply` (`PATCH` with content type `application/apply-patch+yaml`) and `Update` (all other operations which modify the object). These two operations will both update the `managedFields`, but behave a little differently.

For instance, only the `Apply` operation will fail on conflicts while `Update` does not.
For instance, only the `Apply` operation will fail on conflicts while `Update` does not. Also, `Apply` operations are required to identify themselves by providing a `fieldManager` query parameter, while the field is optional for `Update` operations.

An example of multiple managers could look like this:
An example object with multiple managers could look like this:

```yaml
apiVersion: v1
Expand All @@ -382,14 +387,14 @@ metadata:
labels:
test-label: test
managedFields:
- manager: apply
- manager: kubectl
operation: Apply
apiVersion: v1
fields:
f:metadata:
f:labels:
f:test-label: {}
- manager: kubectl
- manager: kube-controller-manager
operation: Update
apiVersion: v1
time: '2019-03-30T16:00:00.000Z'
Expand All @@ -400,32 +405,26 @@ data:
key: new value
```

In this example, a second operation was run as an `Update` by the manager called `kubectl`. The update changed the data field which caused a field ownership change to the `kubectl` manager.
Note that if this update would have been an `Apply` operation by the `kubectl` manager, the operation would have failed due to conflicting ownership.

#### Conflicts
In this example, a second operation was run as an `Update` by the manager called `kube-controller-manager`. The update changed a value in the data field which caused the field's management to change to the `kube-controller-manager`.
Note that if this update would have been an `Apply` operation, the operation would have failed due to conflicting ownership.

A conflict is a special error event that occurs when an `Apply` operation tries to change a field, the requesting manager does now currently own.

TODO/WIP
### Merge

#### Comparison with CSA
When an user sends a partially specified object to the Server Side Apply endpoint, the server merges it with the live object favoring the value in the applied config if it is specified twice. If the set of items present in the applied config is not a superset of the items applied by the same user last time, each missing item not managed by any other field manager is removed.

TODO

### Make a SSA request
### Conflicts

To use the server side apply feature both the direct api as well as a kubectl flag is available.
A conflict is a special status error that occurs when an `Apply` operation tries to change a field, which another user also claims to manage. This will prevent an applier from unintentionally overwriting the value set by another user. When this occurs, the applier has 3 options to resolve the conflicts:

#### Kubectl
* **Overwrite value, become sole manager:** If overwriting the value was intentional (or if the applier is an automated process like a controller) the applier should set the `force` query parameter to true and make the request again. This will force the operation to succeed, change the value of the field, and remove the field from all other managers' entries in managedFields.
* **Don't overwrite value, give up management claim:** If the applier doesn't care about the value of the field anymore, they can remove it from their config and make the request again. This will leave the value unchanged, and cause the field to be removed from the applier's entry in managedFields.
* **Don't overwrite value, become shared manager:** If the applier still cares about the value of the field, but doesn't want to overwrite it, they can change the value of the field in their config to match the value of the object on the server, and make the request again. This will leave the value unchanged, and cause the field's management to be shared by the applier and all other field managers that already claimed to manage it.

To use the new server side apply path instead of the current client side path inside kubectl, provide the `--server-side` flag when applying.
For example to create a new object through SSA, apply the yaml file as usual:

```bash
kubectl apply --server-side -f https://k8s.io/examples/application/simple_deployment.yaml
```

{{% /capture %}}
### Comparison with Client Side Apply

A consequence of the conflict detection and resolution implemented by Server Side Apply is that an applier will always have up to date field values in their local state. If they don't, they will get a conflict the next time they apply. Any of the three options to resolve conflicts will result in the applied config being an up to date subset of the object on the server's fields.

This is different from in Client Side Apply, where outdated values which have been overwritten by other users are left in an applier's local config. These values only become accurate when the user upates that specic field, if ever, and an applier has no way of knowing whether their next apply will overwrite other users' changes.

0 comments on commit 98fc96c

Please sign in to comment.