liveBook · Manning

Declarative programming

As explained in Kubernetes for Developers

Declarative configuration specifies the desired state of a system rather than a sequence of operational commands.

Suppose an application needs three running copies. You could issue commands to create them, then keep checking and replacing any that fail. Declarative programming takes a different approach: describe the state you want and let Kubernetes work toward it. A Deployment can specify three replicas; Kubernetes places them and continues trying to keep them running after a crash or failure. section 1.2.2

For a containerized application, the configuration-driven workflow is:

  • Write a Deployment manifest, usually in YAML, naming the workload, setting its replica count, and identifying its container image. section 3.2.3
  • Submit the manifest to the cluster with kubectl. To change the application, edit the configuration and apply it again; Kubernetes carries out the specified changes. section 3.2.3 section 3.5
  • Inspect the Deployment and its Pods to see whether the requested copies are running. A desired state does not guarantee an immediate result: a Pod can remain Pending if the nodes lack CPU capacity. section 3.2.3
Listing 3.1 Chapter03/3.2_DeployingToKubernetes/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: timeserver
spec:
  replicas: 3                                    #1
  selector:
    matchLabels:
      pod: timeserver-pod
  template:
    metadata:
      labels:
        pod: timeserver-pod
    spec:
      containers:
      - name: timeserver-container
        image: docker.io/wdenniss/timeserver:1   #2

This Deployment manifest sets replicas to 3 and points to a container image. It records the requested state, rather than three separate commands to start containers. section 3.2.3

Imperative commands tell the Kubernetes API what to do one command at a time: create a Deployment, expose it, or change its image. Those commands can be convenient, but reproducing a setup elsewhere means retaining and replaying the right sequence. With configuration files, you can apply the same setup to staging and production, with any needed adjustments. Files also make changes easier to review and keep under version control. section 3.3 section 11.0

Generating configuration without creating an object

A Secret can follow the same workflow. `kubectl create secret generic` with `--dry-run=client -o yaml` outputs a manifest instead of creating the Secret in the cluster. Save that output as configuration and apply it later with `kubectl apply -f secret.yaml`. Omitting the dry-run option creates the object directly—an imperative operation. section 11.4.3

How Kubernetes for Developers covers it

How deep it goes
Works through manifests, application, inspection, updates, and an imperative comparison without detailing controller internals.
Examples
Uses a three-replica container Deployment, imperative image updates, and YAML generation for a Secret.
What it assumes
Starts with a created cluster and authenticated kubectl, then introduces the Deployment manifest through a container-image example.
What you can do after
Apply it via kubectl to deploy, inspect, update, and reproduce Kubernetes configurations.
How it connects
Connects Deployments and Pods to Kubernetes controllers, kubectl, GitOps, namespaces, and Secrets.

Also explained in

Compare how 14 books explain declarative programming →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kubernetes for Developers. The section links point to the parts of the book it draws on.