kubectl apply --server-side: Usage, Options & Common CI Errors
Let the API server own the merge and track who manages each field.
kubectl apply --server-side (SSA) performs the three-way merge on the API server instead of the client, recording a field manager for each field you own. It is the modern default for CI because it makes ownership explicit and avoids the last-applied-configuration annotation.
What it does
With --server-side the API server computes the merge and stores per-field ownership in metadata.managedFields. Two actors editing disjoint fields coexist cleanly; two actors editing the same field produce a conflict you must resolve deliberately. --field-manager names your manager so ownership is attributable.
Common usage
kubectl apply -f deploy.yaml --server-side
kubectl apply -k overlays/prod --server-side --field-manager=ci-deploy
kubectl apply -f deploy.yaml --server-side --force-conflicts
kubectl get deploy/web -o jsonpath='{.metadata.managedFields[*].manager}'Common errors in CI
"Apply failed with N conflicts: conflict with \"<manager>\"" appears when another controller - or a prior client-side apply, or an HPA managing replicas - owns a field you are setting. The fix is deliberate: --force-conflicts takes ownership, but use it knowingly because it can fight a controller that legitimately owns that field (e.g. an HPA owning spec.replicas - drop replicas from your manifest instead). Migrating an object from client-side to server-side apply can also conflict on the first SSA run; resolve once with --force-conflicts and stay on SSA thereafter.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes