Kubernetes Objects

A comprehensive guide to Kubernetes objects including pods, services, deployments, statefulsets, daemonsets, jobs, cronjobs, and custom resources. Learn how each object works, when to use them, and see practical examples.

Core Objects Workloads Services Storage
What are Kubernetes Objects?

Kubernetes objects are persistent entities that represent the state of your cluster. They describe what containerized applications are running, the resources available to them, and the policies around their behavior. Every object has a spec (the desired state you provide) and a status (the actual state reported by Kubernetes).

Objects are created using the Kubernetes API, typically through YAML or JSON manifests, and are managed by the control plane's controllers that continuously work to match the desired state with the actual state.

Key Concept: All Kubernetes objects follow the same structure: apiVersion, kind, metadata (name, namespace, labels, annotations), and spec (desired state). Understanding this pattern helps you work with any Kubernetes resource.
Object Categories

Kubernetes objects are organized into several categories based on their purpose:

Workload Resources

Manage pod lifecycle and scheduling. Includes Pods, Deployments, StatefulSets, DaemonSets, Jobs, and CronJobs.
Run containerized applications

Service Resources

Expose applications internally or externally. Includes Services, Ingress, NetworkPolicy, and Endpoints.
Network connectivity

Storage Resources

Manage persistent storage. Includes PersistentVolume, PersistentVolumeClaim, StorageClass, and CSI drivers.
Persistent data

Configuration Resources

Manage configuration and secrets. Includes ConfigMaps, Secrets, and ServiceAccounts.
Config management

Identity & Security

Control access and permissions. Includes RBAC objects: Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings.
Access control

Custom Resources

Extend Kubernetes with your own API objects via CustomResourceDefinitions (CRDs).
Custom extensions
Pods: The Smallest Deployable Unit

A Pod is the smallest and most basic deployable object in Kubernetes. It represents a single instance of a running process in your cluster. A pod can contain one or more containers that share storage, network, and execution context.

Single-Container Pods

The most common use case. Each pod runs a single container. Kubernetes manages the lifecycle of the pod and its container.
Standard applications

Multi-Container Pods

Pods can contain multiple containers that work together. They share the same network namespace and can access the same volumes.
Sidecar, ambassador, adapter patterns

Pod Lifecycle

Pods go through phases: Pending, Running, Succeeded, Failed, Unknown. Containers can be in Waiting, Running, or Terminated states.
Status monitoring
# Basic Pod YAML apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" # Create a pod kubectl apply -f pod.yaml # Check pod status kubectl get pods kubectl describe pod nginx-pod # View pod logs kubectl logs nginx-pod # Execute command in pod kubectl exec -it nginx-pod -- /bin/sh
Best Practice: Don't run single pods in production. Use Deployments, StatefulSets, or DaemonSets to manage pods—they provide self-healing, scaling, and rolling updates.
Deployments: Declarative Updates

A Deployment provides declarative updates for Pods and ReplicaSets. It's the recommended way to manage stateless applications in production. Deployments handle scaling, rolling updates, and rollbacks automatically.

Rolling Updates

Updates pods gradually with zero downtime. You can control maxSurge and maxUnavailable to manage the update pace.
Zero-downtime deployments

Rollbacks

Kubernetes keeps revision history (by default 10 revisions). You can roll back to any previous revision with one command.
Recovery from failed deployments

Scaling

Scale replicas up or down manually or automatically with HPA (Horizontal Pod Autoscaler).
Capacity management
# Deployment YAML apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort: 80 # Create deployment kubectl apply -f deployment.yaml # Scale deployment kubectl scale deployment nginx-deployment --replicas=5 # Update image (rolling update) kubectl set image deployment/nginx-deployment nginx=nginx:1.25 # Check rollout status kubectl rollout status deployment/nginx-deployment # Rollback kubectl rollout undo deployment/nginx-deployment # View revision history kubectl rollout history deployment/nginx-deployment
StatefulSets: Stateful Applications

A StatefulSet manages the deployment and scaling of a set of pods, and provides guarantees about the ordering and uniqueness of these pods. Unlike Deployments, StatefulSets are designed for stateful applications like databases, message queues, and other services that require persistent storage and stable network identities.

Stable Network Identity

Each pod in a StatefulSet gets a stable, unique hostname (pod-name-0, pod-name-1, etc.). Pods are created and deleted in order.
Cluster applications

Persistent Storage

Each pod can have its own PersistentVolume. When a pod is rescheduled, it retains its storage and data.
Databases, caches

Ordered Operations

Pods are created, updated, and deleted in order (0 to N-1). Scaling up and down happens sequentially.
Leader election, master-slave
# StatefulSet YAML apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: serviceName: mysql replicas: 3 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password ports: - containerPort: 3306 volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi # Create headless service for StatefulSet apiVersion: v1 kind: Service metadata: name: mysql spec: clusterIP: None selector: app: mysql ports: - port: 3306
Important: StatefulSets require careful planning for storage, network, and scaling. They're more complex than Deployments. Only use them when you need stable network identities and ordered operations.
DaemonSets: Node-Level Services

A DaemonSet ensures that all (or some) nodes run a copy of a pod. As nodes are added to the cluster, pods are added to them. As nodes are removed, those pods are garbage collected. DaemonSets are perfect for node-level services.

Monitoring Agents

Run monitoring agents like Prometheus Node Exporter, Datadog agents, or Sysdig on every node.
Observability

Security Agents

Run security tools like Falco, Twistlock, or Aqua on every node for runtime security.
Security monitoring

Network Plugins

Run CNI plugins or network policy agents like Calico, Cilium, or Weave on every node.
Networking
# DaemonSet YAML apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: hostNetwork: true hostPID: true containers: - name: node-exporter image: prom/node-exporter:latest ports: - containerPort: 9100 securityContext: privileged: true volumeMounts: - name: proc mountPath: /host/proc readOnly: true - name: sys mountPath: /host/sys readOnly: true volumes: - name: proc hostPath: path: /proc - name: sys hostPath: path: /sys
Services: Stable Network Access

A Service is an abstraction that defines a logical set of Pods and a policy by which to access them. Services enable loose coupling between dependent Pods by providing a stable endpoint (IP or DNS name) that doesn't change as pods are created, scaled, or replaced.

ClusterIP

Exposes the service on an internal IP in the cluster. Only reachable from within the cluster.
Internal communication

NodePort

Exposes the service on the same port on each Node's IP. Accessible from outside the cluster.
External access (simple)

LoadBalancer

Exposes the service externally using a cloud provider's load balancer. Typically used in cloud environments.
Production external access

Headless

clusterIP is set to None. The service doesn't have a cluster IP, and DNS resolves to individual pod IPs.
StatefulSets
# Service YAML apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: ClusterIP # or NodePort, LoadBalancer selector: app: nginx ports: - port: 80 targetPort: 80 protocol: TCP # LoadBalancer service apiVersion: v1 kind: Service metadata: name: nginx-lb spec: type: LoadBalancer selector: app: nginx ports: - port: 80 targetPort: 80 # Create service kubectl apply -f service.yaml # Check service kubectl get svc # Get service details kubectl describe svc nginx-service
Jobs and CronJobs: Batch Processing

Jobs create one or more pods and ensure that they successfully terminate. They're ideal for one-off tasks and batch processing. CronJobs run Jobs on a scheduled basis.

Jobs

Runs a pod that performs a task and completes. Ensures the task completes successfully, retrying if needed.
Batch jobs, database migrations

CronJobs

Runs Jobs on a schedule using a cron expression. Perfect for recurring tasks.
Backups, reports, cleanup
# Job YAML apiVersion: batch/v1 kind: Job metadata: name: database-migration spec: template: spec: containers: - name: migration image: myapp:migration env: - name: DB_URL valueFrom: secretKeyRef: name: db-secret key: url restartPolicy: Never # CronJob YAML apiVersion: batch/v1 kind: CronJob metadata: name: backup-job spec: schedule: "0 2 * * *" # Daily at 2 AM jobTemplate: spec: template: spec: containers: - name: backup image: backup-image:latest restartPolicy: Never # Create Job kubectl apply -f job.yaml # Check job status kubectl get jobs kubectl describe job database-migration
Custom Resources: Extending Kubernetes

Custom Resource Definitions (CRDs) allow you to extend the Kubernetes API with your own resources. This enables platform engineering teams to create domain-specific APIs.

# CustomResourceDefinition YAML apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: applications.mycompany.io spec: group: mycompany.io versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer image: type: string scope: Namespaced names: plural: applications singular: application kind: Application shortNames: - app # Using the custom resource apiVersion: mycompany.io/v1 kind: Application metadata: name: my-app spec: replicas: 3 image: nginx:latest
Best Practice: Use Custom Resources with operators to automate complex application management. The combination of CRDs and controllers is the foundation of the Kubernetes operator pattern.
Object Comparison Table
Object Use Case Stateful? Scaling Update Strategy
Pod Single container instance No Manual N/A
Deployment Stateless applications No Manual/Auto Rolling update
StatefulSet Stateful applications Yes Manual Ordered updates
DaemonSet Node-level services No Per node Rolling update
Job One-off tasks No Parallel N/A
CronJob Scheduled tasks No Parallel N/A
Service Network access N/A N/A N/A
Frequently Asked Questions
What's the difference between a Pod and a Container?
A Pod is a group of one or more containers that share storage and network. It's the smallest deployable unit in Kubernetes. A Container is a single runtime instance of a container image. Pods can contain multiple containers that work together.
When should I use a StatefulSet instead of a Deployment?
Use StatefulSets for stateful applications that require stable network identities, ordered deployment, and persistent storage. Examples: databases (MySQL, PostgreSQL), message queues (Kafka, RabbitMQ), and distributed systems (Zookeeper, etcd).
What is a headless service and when is it used?
A headless service has clusterIP set to None. It doesn't provide load balancing; instead, DNS resolves to individual pod IPs. It's used with StatefulSets for direct pod-to-pod communication and service discovery.
How do I rollback a deployment?
Use kubectl rollout undo deployment/<name>. You can also rollback to a specific revision with kubectl rollout undo deployment/<name> --to-revision=<revision>.
What are Custom Resource Definitions (CRDs)?
CRDs allow you to extend the Kubernetes API with your own resources. They enable platform teams to create domain-specific APIs and implement operators for custom automation.
When should I use a Job vs a CronJob?
Use a Job for one-time tasks (database migration, batch processing). Use a CronJob for recurring tasks (daily backups, hourly reports, periodic cleanup).
What's the difference between ClusterIP, NodePort, and LoadBalancer?
ClusterIP exposes the service internally within the cluster. NodePort exposes it on each node's IP at a specific port. LoadBalancer uses a cloud provider's load balancer to expose the service externally.
How do I create a custom resource in Kubernetes?
First, create a CustomResourceDefinition (CRD) that defines the resource schema. Then, you can create instances of that resource using YAML/JSON manifests. CRDs are a core Kubernetes feature.
Previous: Architecture Next: Cluster Setup

Understanding Kubernetes objects is fundamental to working with Kubernetes. Master these resources to build, deploy, and manage applications effectively in production.