Search…

Core Kubernetes objects

In this series (14 parts)
  1. Why Kubernetes exists
  2. Kubernetes architecture
  3. Core Kubernetes objects
  4. Kubernetes networking
  5. Storage in Kubernetes
  6. Kubernetes configuration and secrets
  7. Resource management and autoscaling
  8. Kubernetes workload types
  9. Kubernetes observability
  10. Kubernetes security
  11. Helm and package management
  12. GitOps with ArgoCD
  13. Kubernetes cluster operations
  14. Service mesh concepts

Kubernetes has dozens of object types, but most applications rely on a small set. This article covers the seven you will use constantly.

Pods

A Pod is the smallest deployable unit. It wraps one or more containers that share a network namespace and storage volumes. Most pods run a single container, but sidecar patterns (logging agents, service mesh proxies) add more.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-standalone
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.27
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: "50m"
          memory: "64Mi"
        limits:
          cpu: "100m"
          memory: "128Mi"

You rarely create bare pods. If a pod dies, nothing restarts it. That is where ReplicaSets and Deployments come in.

Key pod facts:

  • Every pod gets its own IP address.
  • Containers in the same pod communicate over localhost.
  • Pods are ephemeral. They are created, they run, and they are replaced.

ReplicaSet

A ReplicaSet ensures a specified number of pod replicas are running at all times. If a pod crashes, the ReplicaSet controller creates a replacement.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: web-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: myregistry/web:2.1.0
          ports:
            - containerPort: 8080

You almost never create ReplicaSets directly. Deployments manage them for you and add rollout capabilities on top.

Deployment

A Deployment manages ReplicaSets and provides declarative updates. When you change the image tag, the Deployment creates a new ReplicaSet and gradually shifts traffic.

graph TD
  D["Deployment: web-app"] --> RS1["ReplicaSet v1 (0 replicas)"]
  D --> RS2["ReplicaSet v2 (3 replicas)"]
  RS2 --> P1["Pod v2-abc"]
  RS2 --> P2["Pod v2-def"]
  RS2 --> P3["Pod v2-ghi"]

After a successful rollout, the old ReplicaSet is scaled to zero but kept around for rollback.

A complete Deployment manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
  labels:
    app: web-app
spec:
  replicas: 3
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: web-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web
          image: myregistry/web-app:2.1.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "250m"
              memory: "256Mi"

The strategy section controls rollout behavior. maxSurge: 1 allows one extra pod during updates. maxUnavailable: 0 ensures no downtime.

Common operations:

# Apply changes
kubectl apply -f deployment.yaml

# Check rollout status
kubectl rollout status deployment/web-app

# Roll back to previous version
kubectl rollout undo deployment/web-app

# View rollout history
kubectl rollout history deployment/web-app

Service

Pods come and go. Their IP addresses change. A Service provides a stable network endpoint that routes traffic to a set of pods matched by label selectors.

ClusterIP

The default type. Creates an internal IP reachable only within the cluster.

apiVersion: v1
kind: Service
metadata:
  name: web-app-svc
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: web-app
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

Other pods reach this service at web-app-svc.production.svc.cluster.local or simply web-app-svc within the same namespace.

NodePort and LoadBalancer

NodePort exposes the service on a static port (30000-32767) on every node. Useful for development. LoadBalancer provisions a cloud load balancer that forwards to the service. This is the standard way to expose services on managed clusters. We cover networking details in Kubernetes networking.

Namespace

Namespaces partition a cluster into virtual sub-clusters. They scope names, apply resource quotas, and control access.

apiVersion: v1
kind: Namespace
metadata:
  name: staging
  labels:
    environment: staging

Every cluster starts with default, kube-system, kube-public, and kube-node-lease. A common pattern is one namespace per environment or per team.

ConfigMap

ConfigMaps store non-sensitive configuration data as key-value pairs. Pods consume them as environment variables or mounted files.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  DATABASE_HOST: "postgres.production.svc.cluster.local"
  DATABASE_PORT: "5432"
  LOG_LEVEL: "info"

Reference it with envFrom to load all keys as environment variables, or valueFrom.configMapKeyRef to select individual keys. You can also mount a ConfigMap as a file volume.

Secret

Secrets hold sensitive data. They are base64-encoded, not encrypted. Use stringData to provide plain text input:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: production
type: Opaque
stringData:
  username: admin
  password: supersecret

Secrets are consumed the same way as ConfigMaps. We cover secure secret management in Kubernetes configuration and secrets.

How these objects relate

The hierarchy matters. A Deployment manages ReplicaSets. A ReplicaSet manages Pods. A Service routes to Pods. ConfigMaps and Secrets feed configuration into Pods.

# Trace ownership
kubectl get deployment web-app -o jsonpath='{.metadata.uid}'
kubectl get rs -l app=web-app -o jsonpath='{.items[*].metadata.ownerReferences[*].name}'
kubectl get pods -l app=web-app -o wide

When debugging, start at the top. If pods are not running, check the ReplicaSet. If the ReplicaSet looks fine, check the Deployment. If the Deployment is stuck, check events with kubectl describe.

What comes next

You now know the core building blocks. The next article covers Kubernetes networking: how pods communicate, how Services work under the hood, and how to expose applications to the outside world with Ingress.

Start typing to search across all content
navigate Enter open Esc close