Skip to content

Commit 437f38b

Browse files
committed
Address comments
1 parent 04e5a04 commit 437f38b

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

content/en/blog/_posts/2021-07-15-server-side-apply-ga.md renamed to content/en/blog/_posts/2021-08-06-server-side-apply-ga.md

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
---
22
layout: blog
33
title: "Kubernetes 1.22: Server Side Apply moves to GA"
4-
description: >
5-
Server Side Apply moves to GA.
6-
date: 2021-07-15T10:00:00-08:00
7-
slug: Server-Side-Apply-GA
4+
date: 2021-08-06
5+
slug: server-side-apply-ga
86
---
97

10-
Authors: Jeffrey Ying, Google & Joe Betz, Google
8+
**Authors:** Jeffrey Ying, Google & Joe Betz, Google
119

12-
Server-side Apply (SSA) has been promoted to GA in the Kubernetes v1.22 release. Support for Server-side Apply was introduced as alpha in Kubernetes v1.14 release, promoted to beta in the Kubernetes v1.16 release, and [promoted to beta 2](https://kubernetes.io/blog/2020/04/01/kubernetes-1.18-feature-server-side-apply-beta-2/) in the Kubernetes v1.18 release.
13-
14-
The GA milestone indicates that Kubernetes users may depend on the feature and its API without fear of backwards incompatible changes in future causing regressions. GA features are protected by the [Kubernetes deprecation policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/).
10+
Server-side Apply (SSA) has been promoted to GA in the Kubernetes v1.22 release. The GA milestone means you can depend on the feature and its API, without fear of future backwards-incompatible changes. GA features are protected by the Kubernetes [deprecation policy](/docs/reference/using-api/deprecation-policy/).
1511

1612
## What is Server-side Apply?
1713

18-
Server-side Apply helps users and controllers manage their resources through declarative configurations. Server-side Apply replaces the client side apply feature implemented by “kubectl apply” with a server-side implementation, permitting use by tools/clients other than kubectl. To learn more about why Server-side Apply is important, or to learn how to use Server-side Apply from `kubectl`, see the [Beta 2 release announcement](https://kubernetes.io/blog/2020/04/01/kubernetes-1.18-feature-server-side-apply-beta-2/).
14+
Server-side Apply helps users and controllers manage their resources through declarative configurations. Server-side Apply replaces the client side apply feature implemented by “kubectl apply” with a server-side implementation, permitting use by tools/clients other than kubectl. Server-side Apply is a new merging algorithm, as well as tracking of field ownership, running on the Kubernetes api-server. Server-side Apply enables new features like conflict detection, so the system knows when two actors are trying to edit the same field. Refer to the [Server-side Apply Documentation](/docs/reference/using-api/server-side-apply/) and [Beta 2 release announcement](https://kubernetes.io/blog/2020/04/01/kubernetes-1.18-feature-server-side-apply-beta-2/) for more information.
1915

2016
## What’s new since Beta?
2117

@@ -24,7 +20,9 @@ Since the [Beta 2 release](https://kubernetes.io/blog/2020/04/01/kubernetes-1.18
2420
### Support for subresources
2521

2622
Server-side Apply now fully supports subresources like `status` and `scale`. This is particularly important for [controllers](/docs/concepts/architecture/controller/), which are often responsible for writing to subresources.
23+
2724
## Server-side Apply support in client-go
25+
2826
Previously, Server-side Apply could only be called from the client-go typed client using the `Patch` function, with `PatchType` set to `ApplyPatchType`. Now, `Apply` functions are included in the client to allow for a more direct and typesafe way of calling Server-side Apply. Each `Apply` function takes an "apply configuration" type as an argument, which is a structured representation of an Apply request. For example:
2927

3028
```go
@@ -41,7 +39,7 @@ hpaApplyConfig := v1ac.HorizontalPodAutoscaler(autoscalerName, ns).
4139
return hpav1client.Apply(ctx, hpaApplyConfig, metav1.ApplyOptions{FieldManager: "mycontroller", Force: true})
4240
```
4341

44-
Note in this example that `HorizontalPodAutoscaler` is imported from an "applyconfigurations" package. Each "apply configuration" type represents the same Kubernetes object kind as the corresponding go struct, but where all fields are pointers to make them optional, allowing apply requests to be accurately represented. For example, this when the apply configuration in the above example is marshalled to YAML, it produces:
42+
Note in this example that `HorizontalPodAutoscaler` is imported from an "applyconfigurations" package. Each "apply configuration" type represents the same Kubernetes object kind as the corresponding go struct, but where all fields are pointers to make them optional, allowing apply requests to be accurately represented. For example, when the apply configuration in the above example is marshalled to YAML, it produces:
4543

4644
```yaml
4745
apiVersion: autoscaling/v1
@@ -90,11 +88,11 @@ spec:
9088
9189
Which, among other things, contains `spec.maxReplicas` set to `0`. This is almost certainly not what the caller intended (the intended apply configuration says nothing about the `maxReplicas` field), and could have serious consequences on a production system: it directs the autoscaler to downscale to zero pods. The problem here originates from the fact that the go structs contain required fields that are zero valued if not set explicitly. The go structs work as intended for create and update operations, but are fundamentally incompatible with apply, which is why we have introduced the generated "apply configuration" types.
9290

93-
The "apply configurations" also have convenience `With<FieldName>` functions that make it easier to build apply requests. This allows developers to set fields without having to deal with the fact that all the fields in the "apply configuration" types are pointers, and are inconvenient to set using go. For example `MinReplicas: &0` is not legal go code, so without the `With` functions, developers would work around this problem by using a library, .e.g. `MinReplicas: pointer.Int32Ptr(0)`, but string enumerations like `corev1.Protocol` are still a problem since they cannot be supported by a general purpose library. In addition to the convenience, the `With` functions also isolate developers from the underlying representation, which makes it safer for the underlying representation to be changed to support additional features in the future.
91+
The "apply configurations" also have convenience `With<FieldName>` functions that make it easier to build apply requests. This allows developers to set fields without having to deal with the fact that all the fields in the "apply configuration" types are pointers, and are inconvenient to set using go. For example `MinReplicas: &0` is not legal go code, so without the `With` functions, developers would work around this problem by using a library, e.g. `MinReplicas: pointer.Int32Ptr(0)`, but string enumerations like `corev1.Protocol` are still a problem since they cannot be supported by a general purpose library. In addition to the convenience, the `With` functions also isolate developers from the underlying representation, which makes it safer for the underlying representation to be changed to support additional features in the future.
9492

9593
## Using Server-side Apply in a controller
9694

97-
The new client-go support makes it much easier to use Server-side Apply in controllers.
95+
You can use the new support for Server-side Apply no matter how you implemented your controller. However, the new client-go support makes it easier to use Server-side Apply in controllers.
9896

9997
When authoring new controllers to use Server-side Apply, a good approach is to have the controller recreate the apply configuration for an object each time it reconciles that object. This ensures that the controller fully reconciles all the fields that it is responsible for. Controllers typically should unconditionally set all the fields they own by setting `Force: true` in the `ApplyOptions`. Controllers must also provide a `FieldManager` name that is unique to the reconciliation loop that apply is called from.
10098

@@ -126,41 +124,44 @@ deploymentApplyConfig.Spec.Template.Spec.WithContainers(corev1ac.Container().
126124
applied, err := deploymentClient.Apply(ctx, extractedDeployment, metav1.ApplyOptions{FieldManager: fieldMgr})
127125
```
128126

129-
For developers using Custom Resource Definitions (CRDs), the Kubebuilder apply support provides the same capabilities. <TODO: explain how to use Kubebuilder in more detail?>.
127+
For developers using Custom Resource Definitions (CRDs), the Kubebuilder apply support will provide the same capabilities. Documentation will be included in the Kubebuilder book when available.
128+
130129
## Server-side Apply and CustomResourceDefinitions
131130

132-
It is strongly recommended that all CRDs have a schema. Custom Resource Definitions (CRDs) without a schema are treated as unstructured data by Server-side Apply. Keys are treated as fields in a struct and lists are assumed to be atomic.
131+
It is strongly recommended that all [Custom Resource Definitions](/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (CRDs) have a schema. CRDs without a schema are treated as unstructured data by Server-side Apply. Keys are treated as fields in a struct and lists are assumed to be atomic.
133132

134-
CRD that specify a schema are able to specify additional annotations in the schema. Please refer to the documentation on the full list of available annotations.
133+
CRDs that specify a schema are able to specify additional annotations in the schema. Please refer to the documentation on the full list of available annotations.
135134

136135
New annotations since beta:
137136

138-
Defaulting: Values for fields that appliers do not express explicit interest in should be defaulted. This prevents an applier from unintentionally owning a defaulted field that might cause conflicts with other appliers. If unspecified, the default value is nil or the nil equivalent for the corresponding type.
137+
**Defaulting:** Values for fields that appliers do not express explicit interest in should be defaulted. This prevents an applier from unintentionally owning a defaulted field that might cause conflicts with other appliers. If unspecified, the default value is nil or the nil equivalent for the corresponding type.
139138

140-
- Usage: see the [CRD Defaulting](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting) documentation for more details.
141-
- Golang: `+default=<value>`,
139+
- Usage: see the [CRD Defaulting](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting) documentation for more details.
140+
- Golang: `+default=<value>`
142141
- OpenAPI extension: `default: <value>`
143142

144143

145144
Atomic for maps and structs:
146145

147-
Maps: By default maps are granular. A different manager is able to manage each map entry. They can also be configured to be atomic such that a single manager owns the entire map.
146+
**Maps:** By default maps are granular. A different manager is able to manage each map entry. They can also be configured to be atomic such that a single manager owns the entire map.
148147

149-
- Usage: Refer to [Merge Strategy](https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy) for a more detailed overview
148+
- Usage: Refer to [Merge Strategy](/docs/reference/using-api/server-side-apply/#merge-strategy) for a more detailed overview
150149
- Golang: `+mapType=granular/atomic`
151-
- OpenAPI extension: x-kubernetes-map-type: granular/atomic`
150+
- OpenAPI extension: `x-kubernetes-map-type: granular/atomic`
152151

153-
Structs: By default structs are granular and a separate applier may own each field. For certain kinds of structs, atomicity may be desired. This is most commonly seen in small coordinate-like structs such as Field/Object/Namespace Selectors, Object References, RGB values, Endpoints (Protocol/Port pairs), etc.
152+
**Structs:** By default structs are granular and a separate applier may own each field. For certain kinds of structs, atomicity may be desired. This is most commonly seen in small coordinate-like structs such as Field/Object/Namespace Selectors, Object References, RGB values, Endpoints (Protocol/Port pairs), etc.
154153

155-
- Usage: Refer to [Merge Strategy](https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy) for a more detailed overview
154+
- Usage: Refer to [Merge Strategy](/docs/reference/using-api/server-side-apply/#merge-strategy) for a more detailed overview
156155
- Golang: `+structType=granular/atomic`
157156
- OpenAPI extension: `x-kubernetes-map-type:atomic/granular`
158157

159-
What's Next?
158+
## What's Next?
159+
160+
After Server Side Apply, the next focus for the API Expression working-group is around improving the expressiveness and size of the published Kubernetes API schema. To see the full list of items we are working on, please join our working group and refer to the work items document.
161+
162+
## How to get involved?
160163

161-
<TODO: jpbetz: explain WG API expression's future a bit?>
162-
How to get involved?
163-
The working-group for apply is available on slack #wg-api-expression, through the mailing list and we also meet every other Tuesday at 9.30 PT on Zoom.
164+
The working-group for apply is [wg-api-expression](https://github.com/kubernetes/community/tree/master/wg-api-expression). It is available on slack [#wg-api-expression](https://kubernetes.slack.com/archives/C0123CNN8F3), through the [mailing list](https://groups.google.com/g/kubernetes-wg-api-expression) and we also meet every other Tuesday at 9.30 PT on Zoom.
164165

165166
We would also like to use the opportunity to thank the hard work of all the contributors involved in making this promotion to GA possible:
166167

0 commit comments

Comments
 (0)