✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Service Manifest Management

Kubernetes Service Manifest Management defines and controls services via YAML files to ensure scalable, reliable containerized application deployment.

Kubernetes Service Manifest Management is the discipline of authoring, applying, evolving, and retiring the declarative YAML or JSON documents that define Kubernetes Service objects. A Service manifest is the durable, version-controlled source of truth that tells the Kubernetes API server how a stable network identity should be exposed for a set of Pods, how traffic should be routed to those Pods as they are created and destroyed, and how other workloads in or outside the cluster should discover that identity. Manifest management treats the Service resource not as a one-time kubectl invocation but as a lifecycle: a manifest is written, validated, applied to a cluster, incrementally patched as requirements change, diffed against live cluster state to detect drift, and eventually pruned when the Service is decommissioned.


Structural Anatomy of a Service Manifest

Every Service manifest follows the standard four-field Kubernetes object envelope, with the routing logic concentrated in spec:

apiVersion: v1
kind: Service
metadata:
  name: codartium-api
  namespace: codartium
  labels:
    app.kubernetes.io/name: codartium-api
    app.kubernetes.io/part-of: codartium
spec:
  selector:
    app.kubernetes.io/name: codartium-api
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
  • apiVersion and kind pin the manifest to the core v1 Service schema.
  • metadata.name and metadata.namespace form the Service's cluster-unique identity and the basis of its DNS name.
  • spec.selector is the label query that binds the Service to a live, dynamic set of Pods; it is the mechanism by which the Service stays correct as Pods are rescheduled, scaled, or replaced.
  • spec.ports maps the externally addressable port to the container-facing targetPort, optionally naming each entry for multi-port Services.
  • spec.type selects the exposure model: ClusterIP (internal-only, the default), NodePort (a static port opened on every node), LoadBalancer (provisioned external load balancer, typically via a cloud controller), or ExternalName (a DNS-level CNAME alias with no selector or proxying involved).

Manifest Authoring

Authoring is the act of producing a manifest that is both schema-valid and semantically correct for its intended traffic pattern. Sound authoring practice keeps the selector in lock-step with the label set actually applied to the target Deployment or StatefulSet's Pod template, since a mismatched selector silently yields a Service with zero backing endpoints rather than an error. Authoring also fixes the port topology: port is the contract offered to consumers, targetPort is the contract the container implements, and the two are allowed to diverge so that internal refactors of a container's listening port do not require every client to change. Headless Services (spec.clusterIP: None) are authored deliberately when direct Pod-to-Pod DNS resolution is required, such as for StatefulSet peer discovery, bypassing the virtual-IP load-balancing layer entirely.


Manifest Apply

Applying a manifest is the transition from a static file to live cluster state, most commonly performed with kubectl apply -f (or its equivalent through a GitOps controller) rather than kubectl create, because apply computes a three-way merge between the manifest, the last-applied-configuration annotation, and the live object, allowing manifests to be re-applied idempotently as they evolve.

kubectl apply -f service-codartium-api.yaml --namespace codartium

On apply, the API server allocates a ClusterIP (if not explicitly pinned), and the kube-proxy component on every node programs the corresponding iptables or IPVS rules so that traffic to that virtual IP is transparently load-balanced across the selector's matching Pod endpoints. The EndpointSlice controller continuously reconciles this Pod set in the background, independent of any further manifest changes.


Manifest Patch

Patching covers targeted, incremental updates to a Service that is already live, without resubmitting a full manifest. This is the mechanism behind kubectl patch, kubectl edit, kubectl label, and kubectl annotate when scoped to a Service object, and it underlies how automated systems (autoscalers, admission controllers, GitOps reconcilers) adjust Services at runtime.

kubectl patch service codartium-api \
  --namespace codartium \
  --type merge \
  -p '{"spec":{"ports":[{"name":"http","port":80,"targetPort":9090}]}}'

Patch management distinguishes strategic-merge patches, JSON merge patches, and JSON Patch (RFC 6902) operations; the choice affects whether list fields such as spec.ports are replaced wholesale or merged element-by-element, which is a frequent source of unintended port removal when the wrong patch strategy is used against a multi-port Service.


Manifest Diff

Diffing is the reconciliation step that compares the manifest as committed in source control against the object's actual live state in the cluster, surfacing drift introduced by manual kubectl edit sessions, controller-managed mutations, or admission webhooks.

kubectl diff -f service-codartium-api.yaml --namespace codartium

In GitOps-managed environments this diff is computed continuously by the reconciling controller, and any detected divergence is treated as a signal either to re-apply the source-of-truth manifest (enforcing the declared state) or to pull the live change back into version control (accepting the drift as the new baseline). Systematic diffing is what allows Service Manifest Management to guarantee that the committed YAML remains an accurate description of cluster behavior over time.


Manifest Prune

Pruning is the controlled removal of Service manifests, and the corresponding live objects, once a workload is decommissioned or a Service is superseded. kubectl apply supports --prune, which deletes live objects that are no longer represented among the manifests in a given apply set, and GitOps tooling applies the equivalent logic when a manifest file is removed from its tracked source directory.

kubectl apply -f ./manifests --prune -l app.kubernetes.io/part-of=codartium --namespace codartium

Pruning discipline matters specifically for Services because an orphaned Service silently continues to hold a ClusterIP, respond to DNS queries, and route traffic to whatever Pods happen to match its stale selector, which can misdirect traffic long after the intended backing workload has been removed.


Discovery Consequences of the Manifest

The manifest is not only a routing configuration but the direct input to Kubernetes' service discovery mechanisms. Every Service defined by a manifest is automatically registered in cluster DNS by CoreDNS (or an equivalent resolver) under the pattern <service-name>.<namespace>.svc.cluster.local, and, for Pods started after the Service exists, exposed through SERVICE_NAME_SERVICE_HOST and SERVICE_NAME_SERVICE_PORT environment variables. This means every field in the manifest, the name, the namespace, and the port names, is effectively part of a discovery contract consumed by other workloads, and changing them is a breaking change to any client relying on that DNS name or environment variable rather than a Service-agnostic mechanism such as an Ingress or a service mesh's virtual service.

Author Apply Patch Diff Prune

Practical Guarantees Manifest Management Provides

Disciplined Service Manifest Management yields three guarantees for a cluster: traceability, since every live Service can be traced back to the committed manifest that produced it; reversibility, since any patch or drift can be rolled back by re-applying an earlier manifest revision from version control; and cleanliness, since pruning ensures the set of live Services never silently outlives the manifests that describe them. Together these properties are what allow Kubernetes Service discovery, DNS resolution, environment-variable injection, and load-balanced routing, to remain a reliable abstraction rather than a source of stale or ambiguous network endpoints.