Kubernetes objects: Imperative vs declarative creation explained

Learn how to create and manage Kubernetes objects using both imperative kubectl commands and declarative YAML files. Covers object structure, kubectl apply, dry-run, and api-resources.

4 lessons · 11 min · Intermediate

3 minutes reading time

Written by

Civo Team
Civo Team

Marketing Team at Civo

Everything in Kubernetes happens through objects. Whether you are deploying an application, scaling it, or exposing it to traffic, you are creating and managing Kubernetes objects. These objects represent the desired state of your cluster, and Kubernetes continuously works to ensure the actual state matches what you have defined.

Two ways to create objects

There are two approaches to creating Kubernetes objects: imperative and declarative.

  • Imperative means telling Kubernetes exactly what to do right now using a direct command. It is fast for experimentation and debugging but not repeatable or version-controllable.
  • Declarative means defining the desired state in a YAML file and applying it. Kubernetes figures out how to get from the current state to the desired state. This is the recommended approach for production because it works with version control and GitOps workflows.
imperative_vs_declarative

Imperative creation

Create a deployment directly with a command:

kubectl create deploy nginx --image=nginx --port=80

Verify the deployment was created:

kubectl get deploy

Expected output:

NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 10s

Delete the deployment:

kubectl delete deploy nginx

Declarative creation

The declarative approach uses YAML files applied with kubectl apply. Rather than writing YAML from scratch, use the --dry-run=client -o yaml flag to generate a starting template.

Generating a YAML template without creating the resource

This is one of the most useful kubectl techniques. The --dry-run=client flag runs the command locally without sending anything to the API server, so nothing gets created. Combined with -o yaml it outputs a valid manifest you can save and edit:

kubectl create deploy nginx --image=nginx --port=80 --dry-run=client -o yaml > deploy.yaml

This generates a complete Deployment YAML file saved to deploy.yaml. Open it, make any changes you need, then apply it:

kubectl apply -f deploy.yaml

Expected output:

deployment.apps/nginx created

To update the deployment later, edit the YAML file and run kubectl apply -f deploy.yaml again. Unlike kubectl create, kubectl apply is idempotent — it creates the resource if it does not exist, or updates it if it does.

Structure of a Kubernetes object

Every Kubernetes object is defined by four fields:

apiVersion: apps/v1 # The Kubernetes API version for this resource
kind: Deployment # The type of object to create
metadata: # Data that identifies the object
name: nginx
labels:
app: nginx
spec: # The desired state of the object
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
  • apiVersion specifies which version of the Kubernetes API to use. Different object types use different API versions — for example Deployments use apps/v1 while Pods use v1.
  • kind specifies the type of object. Common values include Pod, Deployment, Service, ConfigMap, and Namespace.
  • metadata contains identifying information including the object name, namespace, and labels.
  • spec defines the desired state. The contents of spec vary by object type — a Deployment spec defines replicas and pod templates, a Service spec defines ports and selectors.

Viewing available API resources

To see every resource type available in your cluster including short names, API groups, and whether they are namespaced:

kubectl api-resources

Expected output (abbreviated):

NAME SHORTNAMES APIVERSION NAMESPACED KIND
pods po v1 true Pod
deployments deploy apps/v1 true Deployment
services svc v1 true Service
namespaces ns v1 false Namespace
nodes no v1 false Node

This is useful when you cannot remember the exact resource name or want to check what custom resource definitions (CRDs) are installed in the cluster.

View all namespaces:

kubectl get ns
Civo Team
Civo Team

Marketing Team at Civo

Civo is the Sovereign Cloud and AI platform designed to help developers and enterprises build without limits. We bridge the gap between the openness of the public cloud and the rigorous security of private environments, delivering full cloud parity across every deployment. As a team, we are dedicated to providing scalable compute, lightning-fast Kubernetes, and managed services that are ready in minutes. Through CivoStack Enterprise and our FlexCore appliance, we empower organizations to maintain total data sovereignty on their own hardware.

Our mission is to make the cloud faster, simpler, and fairer. By providing enterprise-grade NVIDIA GPUs and streamlined model management, we ensure that high-performance AI and machine learning are accessible to everyone. Built for transparency and performance, the Civo Team is here to give you total control over your infrastructure, your data, and your spend.

View author profile