Server-Side Apply (SSA) has been generally available in Kubernetessince the v1.22 releasein August 2021. It’s a strategy for declarative resource management that improves diff calculations and warns about merge conflicts by moving the logic of thekubectl applycommand onto the server.

This article will explain how SSA works and why it’s preferred to the previous client-side apply (CSA) approach. You’ll also learn how to enable SSA when you make changes to objects in your cluster.

Understanding Declarative Updates

Thekubectl applycommand performsdeclarative object updates. Instead of instructing Kubernetes to modify specific fields, you provide a complete representation of the object as you’d like it to appear. The system automatically computes the differences compared to your cluster’s existing state. It’ll then carry out the actions that transform the state into the desired state expressed by your manifest file.

kind: Pod

name: nginx

  • name: nginx

image: nginx:latest

Runningkubectl applywith this manifest will start a new Pod that runs the

image. The difference between the cluster’s existing state and the desired one is clear: a Pod has been created, where previously there was none with the

name.

You might then modify the manifest by changing one of the Pod’s properties:

image: nginx:1.23

This time the difference between the existing state and the desired one is less substantial. Thekubectl applycommand will detect the revised

field and update your Pod’s configuration accordingly.

The Problems With Client-Side Apply

Diffing the changes and resolving any conflicts is the most important part of declarative updates. This process runs within Kubectl by default. The client is responsible for identifying the existing object on the server and comparing its changes.

Thekubectl applycommand writes alast-applied-configurationannotation onto objects to assist with this process. It enables identification of fields that exist on the live object but which have been removed from the incoming manifest. The client then knows to clear them from the object to achieve the new state.

This approach is problematic when there’s multiple agents updating the same object. A single object could be modified both by Kubectl and a dedicatedcontrollerin your cluster, for example. Client-side apply can’t track which agent modified a field, nor can it understand when a conflict occurs. It simply compares your local manifest to the existing object’slast-applied-configurationand merges in any changes.

Client-side apply is also inherently tied to Kubectl. Third-party tools that want to make their own declarative updates need to either call out to Kubectl or recreate the

logic from scratch. Neither of these two options are particularly ideal.

How Server-Side Apply Works

The fundamental problem with CSA is that outdated local manifests are never detected. If another applier changes an object before you runkubectl apply, your old local revisions may overwrite the correct new ones. With SSA enabled the conflict will be detected and the update will be blocked. It’s a centralized system which enforces that your local state is kept up to date.

SSA worksby adding acontrol plane mechanism that stores information about each field in your objects. It replaces thelast-applied-configurationannotation with a newmetadata.managedFieldsfield. Each field in your object gets tracked within themanagedFields.

Fields are assigned a “field manager” which identifies the client that owns them. If you apply a manifest with Kubectl, then Kubectl will be the designated manager. A field’s manager could also be a controller or an external integration that updates your objects.

Managers are forbidden from updating each other’s fields. You’ll be blocked from changing a field withkubectl applyif it’s currently owned by a different controller. Three strategies are available to resolve these merge conflicts:

This approach is much more powerful than traditionalkubectl apply. It prevents accidental overwrites, lets controllers reliably claim ownership of fields they control, and is fully declarative. SSA tracks how different users have changed individual fields, instead of only recording the object’s entire last state. It also means you can now use apply inside any tool, irrespective of language or

binary availability. You’ll get the same consistent results however you initiate the operation.

Using SSA Today

You can activate SSA by setting the–server-sideflag each time you run Kubectl apply:

pod/nginx serverside-applied

The command’s output changes to highlight that SSA has been used.

apiVersion: v1

creationTimestamp: “2022-11-24T16:02:29Z”

  • apiVersion: v1

fieldsType: FieldsV1

.: {}

f:image: {}

f:name: {}

manager: kubectl

operation: Apply

time: “2022-11-24T16:02:29Z”

f:lastProbeTime: {}

f:lastTransitionTime: {}

f:status: {}

f:type: {}

f:containerStatuses: {}

f:hostIP: {}

f:phase: {}

f:podIP: {}

f:ip: {}

f:startTime: {}

manager: kubelet

operation: Update

subresource: status

time: “2022-11-24T16:02:31Z”

Fields are grouped together by the manager that owns them. In this example,specis managed by Kubectl because that’s how the Pod was created. Thestatusfield is managed by Kubelet, however, because the Node running the Pod changes that field’s value during the Pod’s lifecycle.

SSA is also ready to usein controllers. It enables more powerful semantics and new kinds of controller, including onesthat reconstruct objects. This model handles changes by first rebuilding an object’s fields from scratch to the controller’s satisfaction, then applying the result back to the server. It’s a more natural method than manually establishing the sequence of operations that’ll produce a desired change.

Checking Whether an Object Is Managed With SSA

you may check whether an object’s using CSA or SSA by retrieving its YAML manifest in Kubectl:

kubectl.kubernetes.io/last-applied-configuration: |

{“apiVersion”:“v1”,“kind”:“Pod”,“metadata”:{“annotations”:{},“name”:“nginx”,“namespace”:“default”},“spec”:{“containers”:[{“image”:“nginx:latest”,“name”:“nginx”}]}}

creationTimestamp: “2022-11-24T14:20:07Z”

namespace: default

You canmove an objectbetween CSA and SSA by simply adding or omitting the–server-sideflag next time you runkubectl apply. Kubernetes handles conversion oflast-applied-configurationintomanagedFieldsand vice versa.

Upgrades to SSA can present conflicts if your local manifest differs from the object on the server. This occurs when you’ve run an imperative command such askubectl scaleorkubectl labelsince your last apply operation against the object. You should check your local manifest accurately matches the live object before converting to SSA.

Summary

Server-side apply is an approach to declarative object management where fields are tracked by the Kubernetes control plane. This facilitates robust conflict detection and flexible resolution strategies. SSA addresses the limitations of client-side apply that permit fields to be unintentionally overwritten without any warning.

Although SSA is now generally available, you still need to manually specify it each time you runkubectl apply. It’s worth bearing in mind that SSA is most useful in situations where objects are being managed by several different processes, such as human operators with Kubectl and a controller loop. You won’t benefit much from SSA if you’re exclusively usingkubectl applyto create and update objects.

A future Kubernetes releaseis expected to remove CSA, making SSA the default and only option. The–server-sideflag will then become redundant.