kind: Kubernetes in Docker for CI/CD

kind: Kubernetes in Docker for CI/CD

Introduction

In 2018, kind (Kubernetes in Docker) emerged as a novel approach to running Kubernetes clusters. Unlike minikube’s VM-based model or kubeadm’s full cluster setup, kind runs Kubernetes nodes as Docker containers, making it ideal for CI/CD pipelines, local development, and integration testing.

This mattered because it addressed a gap in the Kubernetes tooling landscape: teams needed fast, disposable clusters for testing without the overhead of VMs or cloud resources. kind’s container-based approach made it possible to spin up multi-node clusters in seconds, run tests, and tear them down—all within CI/CD pipelines or on developer laptops.

Historical note: kind was initially developed by the Kubernetes SIG Testing team to improve Kubernetes’ own CI/CD infrastructure. Its success led to broader adoption as a general-purpose tool for local and automated testing.

kind Highlights

  • Docker-Based: Runs Kubernetes nodes as Docker containers, no VMs or hypervisors required.
  • Multi-Node Support: Can create clusters with multiple control plane and worker nodes for realistic testing.
  • Fast Startup: Clusters start in seconds, making it ideal for CI/CD pipelines.
  • Disposable: Easy to create and destroy clusters, perfect for testing workflows.
  • Kubernetes Conformance: Runs real Kubernetes, ensuring tests match production behavior.
  • Cross-Platform: Works on Linux, macOS, and Windows (with Docker Desktop).

kind vs minikube vs kubeadm: Local Development Comparison

Capabilitykindminikubekubeadm
ArchitectureDocker containersVM (VirtualBox, KVM, etc.)Real VMs/bare metal
Startup TimeSeconds1-2 minutes5-10 minutes
Resource UsageLow (Docker overhead)Medium (VM overhead)High (full nodes)
Multi-NodeYes (native)Limited (experimental)Yes (full HA)
CI/CD FriendlyExcellentGoodPoor (too heavy)
Production FidelityHigh (real Kubernetes)High (real Kubernetes)Highest (real infrastructure)
NetworkingDocker networkingVM networkingReal networking
Best ForCI/CD, testingLocal developmentProduction, learning

CI/CD Integration Patterns

GitHub Actions Example

name: Kubernetes Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install kind
        run: |
          curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.4.0/kind-linux-amd64
          chmod +x ./kind
          sudo mv ./kind /usr/local/bin/kind
      - name: Create cluster
        run: kind create cluster --name test-cluster
      - name: Run tests
        run: |
          kubectl get nodes
          # Run your application tests
      - name: Cleanup
        if: always()
        run: kind delete cluster --name test-cluster

GitLab CI Example

test:
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - apk add --no-cache curl
    - curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.4.0/kind-linux-amd64
    - chmod +x ./kind
    - mv ./kind /usr/local/bin/kind
    - kind create cluster --name test-cluster
  script:
    - kubectl get nodes
    - # Run your tests
  after_script:
    - kind delete cluster --name test-cluster

Use Cases

1. Integration Testing

kind enables realistic integration testing by running actual Kubernetes clusters:

# Create a multi-node cluster for testing
kind create cluster --name integration-test --config kind-config.yaml

# Deploy your application
kubectl apply -f manifests/

# Run integration tests
pytest tests/integration/

# Cleanup
kind delete cluster --name integration-test

2. Operator Testing

Kubernetes operators can be tested against real clusters:

# Create cluster
kind create cluster --name operator-test

# Install CRDs and operator
kubectl apply -f deploy/crds/
kubectl apply -f deploy/operator.yaml

# Run operator tests
go test ./test/e2e/

# Cleanup
kind delete cluster --name operator-test

3. Helm Chart Testing

Test Helm charts against real Kubernetes:

# Create cluster
kind create cluster --name helm-test

# Install and test chart
helm install my-app ./charts/my-app
helm test my-app

# Cleanup
kind delete cluster --name helm-test

Advanced Configurations

Multi-Node Cluster

Create a cluster with multiple control plane and worker nodes:

# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: control-plane
  - role: control-plane
  - role: worker
  - role: worker
  - role: worker
kind create cluster --config kind-config.yaml

Custom Kubernetes Version

Test against specific Kubernetes versions:

kind create cluster --image kindest/node:v1.13.12

Load Images into kind

Load local Docker images into kind clusters:

# Build image
docker build -t my-app:test .

# Load into kind cluster
kind load docker-image my-app:test --name my-cluster

Practical Considerations

Resource Requirements

kind clusters are lightweight but still require:

  • Docker: Must have Docker installed and running.
  • Memory: Each node uses ~200-500MB; multi-node clusters need adequate RAM.
  • Disk: Docker images and cluster state consume disk space.

Networking Limitations

kind uses Docker networking, which has some limitations:

  • Host Network: Pods can’t use host networking mode (security restriction).
  • LoadBalancer Services: No real load balancer; use NodePort or port-forward for testing.
  • Ingress: Requires ingress controller setup; not included by default.

CI/CD Best Practices

  • Parallel Tests: Create separate clusters for parallel test runs to avoid conflicts.
  • Cleanup: Always delete clusters in after_script or finally blocks.
  • Image Caching: Pre-build and cache Docker images to speed up test execution.
  • Resource Limits: Set Docker resource limits to prevent CI runners from running out of memory.

Comparison: kind vs minikube for Local Development

Choose kind When:

  • CI/CD Testing: Need fast, disposable clusters for automated testing.
  • Multi-Node Testing: Testing features that require multiple nodes (HA, scheduling).
  • Docker Native: Already using Docker and want to avoid VM overhead.
  • Cross-Platform: Need consistent behavior across Linux, macOS, and Windows.

Choose minikube When:

  • VM Isolation: Prefer VM-based isolation for security or compatibility.
  • Add-Ons: Need minikube’s built-in add-on system (ingress, dashboard, etc.).
  • Single Node: Simple single-node development is sufficient.
  • Legacy Support: Working with older systems that don’t support Docker.

Getting Started

# Install kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.4.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# Create cluster
kind create cluster

# Use cluster
kubectl cluster-info --context kind-kind

# Delete cluster
kind delete cluster

Caveats & Lessons Learned

  • Docker Dependency: Requires Docker; won’t work in environments without Docker.
  • Networking Differences: Docker networking differs from production; test networking separately if critical.
  • Resource Limits: Multi-node clusters can consume significant resources; monitor Docker resource usage.
  • Image Loading: Must explicitly load images into kind clusters; not automatic like minikube.

Common Failure Modes

  • “Docker not running”: kind requires Docker daemon; ensure Docker is running before creating clusters.
  • “Out of memory”: Multi-node clusters can exhaust system memory; reduce node count or increase available RAM.
  • “Port conflicts”: kind uses host ports; conflicts with other services can prevent cluster creation.

Conclusion

kind’s emergence in 2018 filled a critical gap in the Kubernetes tooling ecosystem: fast, disposable clusters for testing and CI/CD. Its Docker-based architecture made it possible to run real Kubernetes clusters in environments where VMs or cloud resources were impractical or too slow.

While minikube remained popular for local development and kubeadm for production deployments, kind carved out a niche as the go-to tool for automated testing. Its integration into Kubernetes’ own CI/CD infrastructure validated its approach, and its adoption by the broader community demonstrated the need for lightweight, container-based cluster tooling.

For teams building Kubernetes applications, operators, or Helm charts, kind became an essential tool for validating functionality before deploying to production. Its speed, simplicity, and real Kubernetes behavior made it the ideal bridge between local development and production environments.