DevToolBoxGRATIS
Blog

Kubernetes basishandleiding

15 minby DevToolBox

Kubernetes Basics: Getting Started Guide for Developers

Kubernetes (often abbreviated as K8s) has become the industry standard for container orchestration. Whether you are deploying microservices, scaling a web application, or managing complex distributed systems, Kubernetes provides a powerful platform that automates deployment, scaling, and operations of application containers. This guide covers the fundamental concepts every developer needs to understand before working with Kubernetes in 2026.

What is Kubernetes?

Kubernetes is an open-source container orchestration platform originally developed by Google and now maintained by the Cloud Native Computing Foundation (CNCF). It manages containerized workloads and services, providing declarative configuration and automation. Instead of manually deploying containers on individual servers, Kubernetes handles scheduling, networking, storage, and health monitoring automatically.

Key problems Kubernetes solves:

  • Service discovery and load balancing - Kubernetes can expose a container using a DNS name or its own IP address and load-balance traffic across replicas
  • Storage orchestration - Automatically mount local storage, cloud providers, or network storage systems
  • Automated rollouts and rollbacks - Describe the desired state and Kubernetes changes the actual state at a controlled rate
  • Self-healing - Restarts failed containers, replaces and reschedules containers when nodes die
  • Secret and configuration management - Deploy and update secrets and application configuration without rebuilding images
  • Horizontal scaling - Scale your application up or down with a single command, a UI, or automatically based on CPU usage

Core Concepts and Architecture

Cluster Architecture

A Kubernetes cluster consists of two main components: the Control Plane (master) and Worker Nodes. The Control Plane manages the overall state of the cluster, while Worker Nodes run your application workloads.

  • Control Plane - Runs the API server, scheduler, controller manager, and etcd (key-value store for cluster data)
  • Worker Nodes - Run the kubelet agent, container runtime (containerd or CRI-O), and kube-proxy
  • kubectl - The command-line tool used to interact with the Kubernetes API server

Pods

A Pod is the smallest deployable unit in Kubernetes. It represents one or more containers that share storage, network, and a specification for how to run. In most cases, a Pod runs a single container, but multi-container Pods are used for sidecar patterns like logging agents or service meshes.

# pod.yaml - A simple Pod definition
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    app: my-app
    environment: development
spec:
  containers:
    - name: app
      image: node:20-alpine
      ports:
        - containerPort: 3000
      resources:
        requests:
          memory: "128Mi"
          cpu: "250m"
        limits:
          memory: "256Mi"
          cpu: "500m"
      env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url

Deployments

Deployments are the recommended way to manage Pods in production. A Deployment describes a desired state (e.g., 3 replicas of your app), and the Deployment controller changes the actual state to match. Deployments support rolling updates, rollbacks, and scaling.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web
          image: my-registry/web-app:v1.2.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "1000m"

Services

A Service exposes a set of Pods as a network service. Since Pods are ephemeral (they can be created and destroyed at any time), Services provide a stable endpoint for communication. Kubernetes supports several Service types:

  • ClusterIP (default) - Exposes the Service on an internal IP, accessible only within the cluster
  • NodePort - Exposes the Service on each node's IP at a static port (30000-32767)
  • LoadBalancer - Provisions an external load balancer (cloud provider specific)
  • ExternalName - Maps the Service to a DNS name
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

---
# Internal service for database
apiVersion: v1
kind: Service
metadata:
  name: database-service
spec:
  type: ClusterIP
  selector:
    app: postgres
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432

Essential kubectl Commands

kubectl is the primary command-line tool for managing Kubernetes clusters. Here are the commands you will use most frequently:

# Cluster information
kubectl cluster-info
kubectl get nodes
kubectl get namespaces

# Working with Pods
kubectl get pods                           # List all pods in default namespace
kubectl get pods -n my-namespace           # List pods in specific namespace
kubectl get pods -o wide                   # Show additional details (node, IP)
kubectl describe pod my-app                # Detailed pod information
kubectl logs my-app                        # View pod logs
kubectl logs my-app -f                     # Stream logs in real-time
kubectl logs my-app -c sidecar             # Logs from specific container
kubectl exec -it my-app -- /bin/sh         # Shell into a pod

# Working with Deployments
kubectl get deployments
kubectl create deployment web --image=nginx:latest
kubectl scale deployment web --replicas=5
kubectl set image deployment/web web=nginx:1.25
kubectl rollout status deployment/web
kubectl rollout history deployment/web
kubectl rollout undo deployment/web        # Rollback to previous version

# Apply configuration files
kubectl apply -f deployment.yaml
kubectl apply -f ./k8s/                    # Apply all files in directory
kubectl delete -f deployment.yaml

# Resource management
kubectl top pods                           # CPU/memory usage
kubectl top nodes
kubectl get events --sort-by=.metadata.creationTimestamp

ConfigMaps and Secrets

ConfigMaps store non-confidential configuration data as key-value pairs. Secrets store sensitive data like passwords, tokens, and TLS certificates. Both can be injected into Pods as environment variables or mounted as files.

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"
  config.json: |
    {
      "feature_flags": {
        "new_dashboard": true,
        "beta_api": false
      }
    }

---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  database-url: "postgresql://user:pass@db:5432/myapp"
  api-key: "sk-abc123def456"

---
# Using ConfigMap and Secret in a Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: app
          image: my-app:latest
          envFrom:
            - configMapRef:
                name: app-config
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: database-url
          volumeMounts:
            - name: config-volume
              mountPath: /app/config
      volumes:
        - name: config-volume
          configMap:
            name: app-config
            items:
              - key: config.json
                path: config.json

Namespaces

Namespaces provide a way to divide cluster resources between multiple users or teams. They are useful for organizing environments (dev, staging, production) or isolating teams within a shared cluster.

# Create namespaces
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production

# Deploy to a specific namespace
kubectl apply -f deployment.yaml -n staging

# Set default namespace for kubectl
kubectl config set-context --current --namespace=development

# Resource quotas per namespace
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    pods: "20"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"

Ingress Controllers

Ingress manages external HTTP and HTTPS access to services within a cluster. An Ingress controller (like NGINX Ingress or Traefik) reads Ingress resources and configures the load balancer accordingly. This allows path-based and host-based routing, TLS termination, and more.

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - myapp.example.com
        - api.example.com
      secretName: app-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-v1-service
                port:
                  number: 8080
          - path: /v2
            pathType: Prefix
            backend:
              service:
                name: api-v2-service
                port:
                  number: 8080

Local Development with Minikube

Minikube runs a single-node Kubernetes cluster on your local machine. It is the easiest way to learn and experiment with Kubernetes without needing a cloud provider.

# Install minikube (macOS)
brew install minikube

# Start a local cluster
minikube start --driver=docker --cpus=4 --memory=8192

# Enable useful addons
minikube addons enable ingress
minikube addons enable metrics-server
minikube addons enable dashboard

# Open Kubernetes dashboard
minikube dashboard

# Access a LoadBalancer service locally
minikube tunnel

# Stop and delete cluster
minikube stop
minikube delete

Health Checks and Probes

Kubernetes uses probes to determine the health of a container. Configuring probes correctly is critical for reliable deployments and self-healing behavior.

  • Liveness probe - Determines if a container is running. If it fails, Kubernetes restarts the container
  • Readiness probe - Determines if a container is ready to accept traffic. If it fails, the Pod is removed from Service endpoints
  • Startup probe - Used for slow-starting containers. Disables liveness and readiness checks until the container has started
spec:
  containers:
    - name: app
      image: my-app:latest
      ports:
        - containerPort: 8080

      # Liveness: restart if /healthz fails
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 20
        failureThreshold: 3

      # Readiness: stop sending traffic if /ready fails
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
        failureThreshold: 3

      # Startup: allow up to 5 minutes for slow startup
      startupProbe:
        httpGet:
          path: /healthz
          port: 8080
        failureThreshold: 30
        periodSeconds: 10

Best Practices for Beginners

  • Always set resource requests and limits - Prevents a single Pod from consuming all node resources and helps the scheduler make better decisions
  • Use Deployments, not bare Pods - Deployments handle rolling updates, rollbacks, and self-healing automatically
  • Configure health probes - Readiness and liveness probes enable Kubernetes to route traffic correctly and restart unhealthy containers
  • Use namespaces for isolation - Separate environments and teams with namespaces and resource quotas
  • Store configuration in ConfigMaps - Never hardcode configuration in container images; use ConfigMaps and Secrets for environment-specific values
  • Use labels consistently - Labels like app, version, environment enable powerful selection, monitoring, and automation
  • Pin image versions - Never use the latest tag in production; always specify exact image versions for reproducibility
  • Enable RBAC - Use Role-Based Access Control to limit what users and service accounts can do
  • Monitor with metrics-server - Install metrics-server for kubectl top and Horizontal Pod Autoscaler
  • Start with managed Kubernetes - Use EKS, GKE, or AKS for production instead of managing your own control plane

Frequently Asked Questions

What is the difference between Docker and Kubernetes?

Docker is a container runtime that builds and runs individual containers. Kubernetes is an orchestration platform that manages many containers across many machines. Docker creates the containers; Kubernetes decides where to run them, how many to run, how to network them together, and how to handle failures. In modern Kubernetes, containerd (a component of Docker) is typically used as the container runtime.

When should I use Kubernetes?

Kubernetes is ideal when you need to run multiple services that must scale independently, require high availability, or need automated deployment workflows. If you have a single small application, simpler solutions like Docker Compose, a PaaS (Heroku, Railway), or serverless might be more appropriate. Kubernetes adds operational complexity, so evaluate whether the benefits justify the overhead.

How does Kubernetes handle scaling?

Kubernetes supports both horizontal and vertical scaling. Horizontal Pod Autoscaler (HPA) automatically adjusts the number of Pod replicas based on CPU utilization, memory usage, or custom metrics. Vertical Pod Autoscaler (VPA) adjusts resource requests and limits. Cluster Autoscaler adds or removes nodes from the cluster based on pending Pod demands.

What is Helm and should I use it?

Helm is a package manager for Kubernetes that bundles related YAML manifests into reusable charts. It simplifies deploying complex applications (databases, monitoring stacks, ingress controllers) with a single command. Helm is recommended once you move beyond simple deployments and need to manage multiple environments or share configurations across teams.

How do I debug a failing Pod?

Start with kubectl describe pod <name> to see events and status conditions. Check logs with kubectl logs <name>. If the container is crash-looping, usekubectl logs <name> --previous to see logs from the last terminated container. For deeper debugging, use kubectl exec -it <name> -- /bin/sh to shell into the running container and inspect the filesystem, network, and processes.

𝕏 Twitterin LinkedIn
Was dit nuttig?

Blijf op de hoogte

Ontvang wekelijkse dev-tips en nieuwe tools.

Geen spam. Altijd opzegbaar.

Try These Related Tools

🐳Docker Compose Generator

Related Articles

Docker Compose Tutorial: Van basis tot productie-klare stacks

Compleet Docker Compose tutorial: docker-compose.yml syntax, services, netwerken, volumes, omgevingsvariabelen, healthchecks en voorbeelden.

GitHub Actions CI/CD: Complete gids

Stel CI/CD-pipelines in met GitHub Actions.