Kubernetes basics: pods, deployments and services

Kubernetes runs containers across many machines and keeps them healthy. Learn the few core objects that explain most of it.

A cluster of containers managed by a control plane

Kubernetes (often K8s) is a system that runs containers on a group of machines and keeps them in the state you describe. You say "I want 3 copies of this app", and Kubernetes starts them, replaces any that die and spreads them across machines.

The big idea: desired state

You write what you want in YAML files. Kubernetes keeps comparing that with what is actually running and fixes the difference. This loop is why it can heal itself.

Core objects

  • Cluster: the machines (nodes) plus the control plane that makes decisions.
  • Pod: the smallest unit. One or more containers that share a network and storage. Pods are temporary; they can be replaced at any time.
  • Deployment: manages a set of identical pods. It keeps the requested number running and does rolling updates (new version replaces old gradually) and rollbacks.
  • Service: a stable address and name in front of changing pods. It load-balances between them.
  • ConfigMap and Secret: settings and sensitive values kept outside the image.
  • Namespace: a way to separate groups of objects inside one cluster.

A small example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: myapp:1.0
          ports:
            - containerPort: 3000
          resources:
            requests: { cpu: "100m", memory: "128Mi" }
            limits: { memory: "256Mi" }
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000

The Deployment asks for 3 pods running myapp:1.0. The Service finds them by the label app: web and gives them one address.

Commands you will use first

kubectl apply -f app.yaml              # create or update objects
kubectl get pods                       # list pods
kubectl describe pod <name>            # details and events (great for debugging)
kubectl logs <pod>                     # container logs
kubectl rollout status deployment/web  # watch an update
kubectl rollout undo deployment/web    # go back to the previous version
kubectl scale deployment/web --replicas=5

For learning, run a small local cluster with minikube or kind.

Health checks and resources

  • Readiness probe: tells Kubernetes when a pod is ready to receive traffic.
  • Liveness probe: tells it when to restart a stuck container.
  • Requests and limits: what a pod needs and the most it may use. Without them, one pod can starve others.

Safety habits

  • Keep Secrets out of Git. Remember that a Secret is only base64-encoded by default, so limit who can read it and consider encryption at rest or an external secret manager.
  • Run containers as non-root and use specific image tags, not latest.
  • Limit access with RBAC and do not share cluster-admin credentials.
  • Do not expose the Kubernetes API or dashboard to the internet.

Do you need Kubernetes?

Kubernetes is powerful and also complex to run. For one app on one server, systemd or Docker Compose is often enough. It starts to pay off with many services, several machines, frequent deployments or a need for automatic scaling. A managed service from a cloud provider removes much of the cluster operation work.

Takeaway: describe the desired state in YAML, use Deployments for pods and Services for stable access, add probes and resource limits, protect Secrets and access, and adopt Kubernetes only when its complexity buys you something.


Linux & DevOps series, Part 2 (delivery and operations): 1 of 5.

Keep reading