Minikube Add-ons for Production-Like Environments#
A bare minikube cluster runs workloads but lacks the infrastructure that production clusters rely on – metrics collection, ingress routing, TLS, monitoring, and load balancer support. Minikube’s addon system bridges this gap with one-command installs of production components.
Surveying Available Add-ons#
List everything minikube offers:
minikube addons listThis prints dozens of addons with their status. Most are disabled by default. The ones worth enabling depend on what you are testing, but a production-like setup typically needs five to seven of them.
Essential Add-ons#
metrics-server#
Enables kubectl top commands and is required for HorizontalPodAutoscaler to function.
minikube addons enable metrics-serverVerify it is working:
kubectl top nodes
# NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
# minikube 250m 6% 1024Mi 25%
kubectl top pods -AResource footprint is minimal – under 50MB of memory. Enable this in every minikube cluster.
ingress#
Deploys an nginx ingress controller, letting you create Ingress resources just like in production.
minikube addons enable ingressCreate an Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80To reach the ingress from your host, get the minikube IP and add it to /etc/hosts:
echo "$(minikube ip) myapp.local" | sudo tee -a /etc/hostsOn Docker driver setups (common on macOS), you need minikube tunnel running in a separate terminal to expose the ingress controller’s LoadBalancer service.
ingress-dns#
Automates DNS resolution for ingress hostnames so you do not have to manually edit /etc/hosts:
minikube addons enable ingress-dnsAfter configuration, *.test domains resolve to the minikube IP automatically. Follow the minikube docs for the one-time resolver setup on your OS.
dashboard#
The Kubernetes Dashboard UI for visual cluster inspection:
minikube addons enable dashboard
minikube dashboardThis opens the dashboard in your browser. Useful for quickly inspecting workloads, but not something you need running at all times.
registry#
Runs a container registry inside minikube at localhost:5000. Push images to it and reference them in deployments without configuring imagePullSecrets:
minikube addons enable registryPush an image:
docker tag myapp:latest localhost:5000/myapp:latest
docker push localhost:5000/myapp:latestReference it in a deployment:
containers:
- name: myapp
image: localhost:5000/myapp:latestOn macOS with the Docker driver, you need to set up port forwarding for the registry. Run this in the background:
kubectl port-forward -n kube-system service/registry 5000:80 &The registry addon is lightweight (around 30MB memory) and eliminates the need for Docker Hub or any external registry during development.
metallb#
Provides LoadBalancer service support. Without it, services of type LoadBalancer stay in Pending state forever in minikube.
minikube addons enable metallbConfigure an IP range for metallb to assign from:
minikube addons configure metallb
# -- Enter Load Balancer Start IP: 192.168.49.100
# -- Enter Load Balancer End IP: 192.168.49.110The IP range should be within minikube’s network. Check your minikube subnet:
minikube ip
# 192.168.49.2Pick a range in the same /24 that does not conflict with the node IP. Once configured, LoadBalancer services get real IPs:
kubectl get svc
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# myapp LoadBalancer 10.96.123.45 192.168.49.100 80:31234/TCPMonitoring Stack via Helm#
Minikube does not have a built-in monitoring addon, but you can install the kube-prometheus-stack via Helm. This gives you Prometheus, Grafana, and Alertmanager in one chart.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.resources.requests.memory=512Mi \
--set prometheus.prometheusSpec.resources.requests.cpu=250m \
--set grafana.resources.requests.memory=256Mi \
--set alertmanager.alertmanagerSpec.resources.requests.memory=128MiAccess Grafana:
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80
# Default credentials: admin / prom-operatorThis stack needs at least 2GB of available memory in minikube. Start minikube with adequate resources:
minikube start --cpus=4 --memory=8192cert-manager for TLS Testing#
Install cert-manager via Helm to test TLS certificate workflows:
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=trueCreate a self-signed ClusterIssuer for local testing:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: myapp-tls
namespace: default
spec:
secretName: myapp-tls-secret
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
dnsNames:
- myapp.local
- myapp.testThis creates a TLS secret that you can reference in Ingress resources, testing the same certificate workflow you would use in production with Let’s Encrypt or an internal CA.
Resource Impact of Add-ons#
Not all addons are equal in resource consumption:
| Add-on | Memory | CPU | Notes |
|---|---|---|---|
| metrics-server | ~40MB | Minimal | Enable always |
| ingress (nginx) | ~100MB | Minimal | Enable when testing HTTP routing |
| dashboard | ~200MB | Low | Enable on demand |
| registry | ~30MB | Minimal | Enable for image workflow testing |
| metallb | ~50MB | Minimal | Enable when you need LoadBalancer IPs |
| kube-prometheus-stack | ~2GB+ | Moderate | Enable only when testing monitoring |
| cert-manager | ~100MB | Low | Enable when testing TLS |
Plan your minikube memory allocation accordingly. A cluster with metrics-server, ingress, registry, and metallb needs roughly 4GB total (including system components). Add the monitoring stack and you need 6-8GB.
Practical Setup Script#
A bash script that creates a production-like minikube environment:
#!/usr/bin/env bash
set -euo pipefail
CLUSTER_NAME="${1:-dev}"
CPUS="${2:-4}"
MEMORY="${3:-8192}"
K8S_VERSION="${4:-v1.29.0}"
echo "Starting minikube cluster: ${CLUSTER_NAME}"
minikube start \
-p "${CLUSTER_NAME}" \
--driver=docker \
--cpus="${CPUS}" \
--memory="${MEMORY}" \
--kubernetes-version="${K8S_VERSION}"
echo "Enabling core addons..."
minikube -p "${CLUSTER_NAME}" addons enable metrics-server
minikube -p "${CLUSTER_NAME}" addons enable ingress
minikube -p "${CLUSTER_NAME}" addons enable registry
minikube -p "${CLUSTER_NAME}" addons enable dashboard
echo "Configuring metallb..."
minikube -p "${CLUSTER_NAME}" addons enable metallb
MINIKUBE_IP=$(minikube -p "${CLUSTER_NAME}" ip)
IP_PREFIX=$(echo "${MINIKUBE_IP}" | cut -d. -f1-3)
cat <<EOF | minikube -p "${CLUSTER_NAME}" kubectl -- apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- ${IP_PREFIX}.100-${IP_PREFIX}.110
EOF
echo "Installing cert-manager..."
helm repo add jetstack https://charts.jetstack.io --force-update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true \
--kube-context "${CLUSTER_NAME}"
echo "Cluster ${CLUSTER_NAME} is ready with production-like addons."
kubectl --context "${CLUSTER_NAME}" get nodesRun it with defaults or override:
chmod +x setup-minikube.sh
./setup-minikube.sh dev 4 8192 v1.29.0This gives you a repeatable, production-like local cluster in under two minutes.