Deploy Kubernetes with Kind on macOS

Learn how to install and configure Kind (Kubernetes IN Docker) on macOS to create lightweight, multi-node Kubernetes clusters for local development and testing.

What is Kind?

Kind (Kubernetes IN Docker) is a tool for running local Kubernetes clusters using Docker container "nodes". It was primarily designed for testing Kubernetes itself, but is perfect for local development and CI pipelines. Kind allows you to create multi-node clusters quickly and easily, making it ideal for testing more complex Kubernetes deployments.

Prerequisites

Before we begin, ensure your Mac meets these requirements:

  • macOS 10.15 (Catalina) or newer
  • Docker Desktop installed and running
  • At least 4GB of free memory (more for multi-node clusters)
  • At least 20GB of free disk space
  • Internet connection

Installation Process

1

Install Docker Desktop

Kind requires Docker to create container nodes. If you haven't installed Docker Desktop yet:

  1. Download Docker Desktop from Docker's official website
  2. Install and launch Docker Desktop
  3. Ensure Docker is running:
docker --version
docker ps

For Apple Silicon Macs (M1/M2/M3), make sure you're using the ARM64 version of Docker Desktop.

2

Install Homebrew (if not already installed)

Homebrew is the package manager for macOS that makes installing development tools easy.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Verify the installation:

brew --version
3

Install Kind using Homebrew

The easiest way to install Kind on macOS is using Homebrew:

brew install kind

Verify the installation:

kind --version

You should see output similar to: kind version 0.27.0

4

Alternative: Manual Installation

If you prefer not to use Homebrew, you can install Kind manually:

For Intel Macs:

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.27.0/kind-darwin-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

For Apple Silicon Macs (M1/M2/M3):

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.27.0/kind-darwin-arm64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

Verify the installation:

kind --version
5

Install kubectl

You'll need kubectl to interact with your Kubernetes cluster:

brew install kubectl

Or manually:

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

For Apple Silicon Macs, use:

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

Verify the installation:

kubectl version --client

Creating Your First Cluster

1

Start Docker Desktop

Ensure Docker Desktop is running before creating a Kind cluster. You can check its status in the menu bar or by running:

docker ps

If Docker isn't running, open Docker Desktop from your Applications folder.

2

Create a Basic Cluster

To create a simple single-node cluster:

kind create cluster

This command:

  1. Creates a Docker container that acts as a Kubernetes node
  2. Installs Kubernetes components inside the container
  3. Sets up your kubectl configuration to point to the new cluster

The first time you run this, it will download the Kind node image, which may take a few minutes depending on your internet connection.

3

Verify Your Cluster

Check that your cluster is running:

kubectl cluster-info

You should see information about your Kubernetes control plane and CoreDNS.

List the nodes in your cluster:

kubectl get nodes

You should see one node with the status "Ready".

Creating Multi-Node Clusters

1

Create a Configuration File

One of Kind's strengths is the ability to create multi-node clusters. Create a file named kind-config.yaml with the following content:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

This configuration defines a cluster with one control plane node and two worker nodes.

2

Create the Multi-Node Cluster

Create your cluster using the configuration file:

kind create cluster --name multi-node-cluster --config kind-config.yaml

This will create a new cluster with the specified configuration.

3

Verify the Multi-Node Cluster

Check that all nodes are running:

kubectl get nodes

You should see three nodes: one control-plane and two workers.

Managing Multiple Clusters

1

List Your Clusters

You can have multiple Kind clusters running simultaneously. To list all your clusters:

kind get clusters
2

Switch Between Clusters

To switch between clusters, use kubectl with the context name:

kubectl config use-context kind-multi-node-cluster

Or switch back to your default cluster:

kubectl config use-context kind-kind

List all available contexts:

kubectl config get-contexts
3

Delete a Cluster

When you're done with a cluster, you can delete it:

kind delete cluster --name multi-node-cluster

If you don't specify a name, it will delete the default cluster:

kind delete cluster

Working with Applications

1

Deploy a Sample Application

Let's deploy a simple web application to test our cluster:

kubectl create deployment hello-node --image=nginx

Expose the deployment as a service:

kubectl expose deployment hello-node --type=NodePort --port=8080
2

Access the Application

Access your application using port forwarding:

kubectl port-forward service/hello-node 8080:8080

Now you can access your application at http://localhost:8080.

Loading Local Images

1

Build a custom Docker image

# Pull NginX Docker image
docker pull nginx

# Build a Docker image from nginx using CLI only
cat > Dockerfile << EOF
FROM nginx
COPY index.html /usr/share/nginx/html/index.html
EOF

# Create a simple HTML file
echo '<html><body><h1>This time on Kind?!</h1></body></html>' > index.html

# Build the image
docker build -t custom-app:latest .

2

Load the Image into Kind

Load your local image into the Kind cluster:

# Load the image into the Kind cluster
kind load docker-image custom-app:latest

# If the above command doesn't work, try with sudo:
# sudo kind load docker-image custom-app:latest

# Verify the image was loaded successfully
kubectl get nodes -o json | jq '.items[].status.images[] | select(.names[] | contains("custom-app"))'

If you have multiple clusters, specify which one:

kind load docker-image custom-app:latest --name multi-node-cluster
3

Use your custom built Docker image

# Use the image in Kubernetes without pushing to a registry
# We need to use a YAML file to set imagePullPolicy to Never
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-app
spec:
  selector:
    matchLabels:
      app: custom-app
  replicas: 1
  template:
    metadata:
      labels:
        app: custom-app
    spec:
      containers:
      - name: custom-app
        image: custom-app:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 80
EOF

# Expose the deployment as a service
kubectl expose deployment custom-app --type=NodePort --port=80

# Forward the service port to access from your local machine
kubectl port-forward svc/custom-app 8081:80

Advanced Configuration for macOS

1

Resource Allocation

On macOS, Kind uses Docker Desktop, which has its own resource limits. To ensure optimal performance:

  1. Open Docker Desktop
  2. Go to Settings (Gear at the top right) > Resources
  3. Adjust CPU, memory, and disk limits based on your needs
  4. For multi-node clusters, allocate at least 4GB of memory
2

Persistent Volumes

To use persistent volumes with Kind on macOS, you need to configure host path mapping:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraMounts:
  - hostPath: /path/on/your/mac
    containerPath: /data

Create the cluster with this configuration, and then you can create PersistentVolumes that use the /data path.

3

Registry Integration

For development workflows, you can set up a local registry:

# Create a registry container
docker run -d -p 5000:5000 --name kind-registry registry:2

# Connect it to Kind
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"]
    endpoint = ["http://kind-registry:5000"]
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 5000
    hostPort: 5000
EOF

# Connect the registry to the Kind network
docker network connect "kind" kind-registry

Now you can push to localhost:5000/my-app and use it in your cluster.

Troubleshooting on macOS

1

Docker Desktop Issues

If you encounter problems with Docker Desktop:

  1. Restart Docker Desktop
  2. Check Docker Desktop logs (Help > Diagnose & Feedback)
  3. Increase resource allocation in Preferences
  4. Reset Docker Desktop to factory defaults if necessary
2

Kind Cluster Creation Fails

If cluster creation fails:

  1. Check Docker is running: docker ps
  2. Ensure you have enough resources allocated to Docker
  3. Try with a simpler configuration first
  4. Check for network issues or proxies that might interfere
  5. Run with verbose logging: kind create cluster --verbosity 4
3

Performance Issues

If your cluster is slow:

  1. Increase CPU and memory allocation in Docker Desktop
  2. Close unnecessary applications
  3. For Apple Silicon Macs, ensure you're using ARM64 images
  4. Consider using a smaller cluster configuration
4

Network Issues

If you have network problems:

  1. Check your macOS firewall settings
  2. Verify Docker Desktop has network access
  3. Try restarting Docker Desktop
  4. Check if VPN software is interfering with Docker networking

Best Practices for macOS

1

Resource Management

  • Allocate appropriate resources to Docker Desktop based on your cluster size
  • Close unused clusters to free up resources
  • Monitor resource usage with Activity Monitor
2

Development Workflow

  • Use port forwarding for quick access to services
  • Set up a local registry for faster image deployment
  • Use volume mounts to share code between your Mac and the cluster
  • Consider using Tilt, Skaffold, or DevSpace for streamlined development
3

Apple Silicon Considerations

If you're using an M1/M2/M3 Mac:

  • Use ARM64 images when possible for better performance
  • Be aware that some container images might not have ARM64 variants
  • Docker Desktop's Rosetta 2 translation works well but adds overhead

Conclusion

Kind on macOS provides a powerful, lightweight way to run Kubernetes clusters locally. Its ability to create multi-node clusters using Docker containers makes it perfect for development, testing, and learning Kubernetes concepts.

By following this guide, you should now have a fully functional Kind environment on your Mac, ready for developing and testing Kubernetes applications.

Next Steps

  • Explore the Kind documentation for more advanced configurations
  • Learn about Kubernetes networking concepts using your Kind cluster
  • Set up a CI/CD pipeline using Kind for testing
  • Try deploying more complex applications to your cluster