Run Kubernetes in Docker on Ubuntu for Local Development
DEV Community

Run Kubernetes in Docker on Ubuntu for Local Development

Prerequisites on Ubuntu

You need Docker Engine and kubectl. If you don't have Docker yet:

sudo apt-get update && sudo apt-get install -y docker.io
sudo usermod -aG docker $USER && newgrp docker   # run docker without sudo

Install kind (single static binary)

curl -fsSLo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
kind version

A one-command cluster

kind create cluster --name dev
kubectl cluster-info --context kind-dev
docker ps   # you'll see a dev-control-plane container - that's your node

kind wrote a kubeconfig context for you. Tear the whole thing down just as fast:

kind delete cluster --name dev

A realistic multi-node cluster

Most bugs only show up with more than one node (scheduling, affinity, PodDisruptionBudgets). Define it in a config file:

# kind-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 8080
    protocol: TCP
- role: worker
- role: worker

Then create the cluster:

kind create cluster --name dev --config kind-cluster.yaml
kubectl get nodes

The extraPortMappings bit is the trick people miss: it forwards a port from your Ubuntu host into the control-plane container, so an ingress controller inside the cluster is reachable at http://localhost:8080.

Loading a locally-built image (no registry needed)

This is kind's best feature for the Docker workflow. Build with Docker, push straight into the cluster's nodes - no registry round-trip:

docker build -t myapp:dev .
kind load docker-image myapp:dev --name dev
kubectl create deployment myapp --image=myapp:dev
kubectl set image deployment/myapp myapp=myapp:dev   # after a rebuild + reload

Set imagePullPolicy: IfNotPresent (or Never) in your manifest for locally-loaded images, or the kubelet will try to pull myapp:dev from a registry and fail with ImagePullBackOff.

Ubuntu-specific gotchas

  • cgroup / inotify limits. Big clusters on kind can exhaust inotify watches. If pods crashloop with "too many open files," raise them:

    sudo sysctl fs.inotify.max_user_watches=524288
    sudo sysctl fs.inotify.max_user_instances=512
    
  • Rootless Docker works but needs cgroup v2 delegation configured; if kind create hangs, test with rootful Docker first.

  • It's ephemeral by design. A kind node is a container - restart Docker and the cluster state is gone unless you use extraMounts for persistence. That's a feature for testing, a footgun if you treated it like a server.

When a kind pod won't start, it's the same Kubernetes failures as anywhere - ImagePullBackOff from the pull-policy trap above, or CrashLoopBackOff from the app itself. Fixes here: ImagePullBackOff and CrashLoopBackOff.

Next

minikube with the Docker driver - a heavier but more full-featured local option.

Comments

No comments yet. Start the discussion.