// Tutorial //

How To Use minikube for Local Kubernetes Development and Testing

Published on February 28, 2022
Default avatar
By Alex Garnett
Senior DevOps Technical Writer
How To Use minikube for Local Kubernetes Development and Testing

Introduction

Kubernetes is an open-source container orchestration system for automating software deployment, scaling, and management. It has become very popular at the enterprise level for facilitating horizontal scaling of server resources, and many cloud providers including DigitalOcean offer their own managed Kubernetes solution.

Since a Kubernetes deployment usually relies on multiple servers, it can be quite resource intensive in order to perform development and testing of a Kubernetes stack before deploying it into production. For this reason, the Kubernetes authors maintain a companion project called minikube, which can work with a container framework like Docker in order to simulate a Kubernetes cluster running on a single machine.

In this tutorial, you will install minikube on a local computer or remote server. You will also access the built-in Kubernetes dashboard to explore your cluster in a browser. Once your cluster is running, you’ll deploy a test application and explore how to access it via minikube. In the final section of this tutorial you’ll explore how to use Minikube alongside remote Kubernetes clusters using configuration profiles

Prerequisites

To follow this tutorial, you will need:

  • Familiarity with Kubernetes concepts. Please refer to the article An Introduction to Kubernetes for more details.

  • The Docker container framework installed in the Windows, Mac, or Linux environment that you’ll be running minikube from. If you are not working in a Linux environment, refer to Docker’s documentation for installation steps. If you are using Docker on Linux, ensure that you’ve configured it to work without sudo privileges.

  • The Homebrew package manager. Homebrew can be installed on macOS, or in Linux environments. If you are using Windows, you can install Homebrew under WSL.

  • At least 2 CPUs, 2GB of memory, and 20GB of disk space available to the environment where you are installing Minikube.

Step 1 — Installing and Running Minikube

You can install minikube via the Homebrew package manager:

  1. brew install minikube
Output
… ==> Installing minikube ==> Pouring minikube--1.25.2.x86_64_linux.bottle.tar.gz ==> Caveats Bash completion has been installed to: /home/sammy/.linuxbrew/etc/bash_completion.d ==> Summary 🍺 /home/sammy/.linuxbrew/Cellar/minikube/1.25.2: 9 files, 70.0MB …

Note: Getting started with minikube on Windows has some caveats. It works under WSL2 (the current version of the Windows Subsystem for Linux), but it needs to be configured to use Docker rather than its own default backend. This requires that you install Docker with WSL2 support and then, after installing minikube following this documentation, run minikube config set driver docker.

To begin using minikube, you can run it with the start command, which will automatically create a local Kubernetes cluster using multiple Docker containers and a recent stable version of Kubernetes.

  1. minikube start

This will take a moment, and should produce output similar to the following, noting that kubectl has been configured for you.

Output
👍 Starting control plane node minikube in cluster minikube 🚜 Pulling base image ... 💾 Downloading Kubernetes v1.23.1 preload ... > preloaded-images-k8s-v16-v1...: 504.42 MiB / 504.42 MiB 100.00% 81.31 Mi > gcr.io/k8s-minikube/kicbase: 378.98 MiB / 378.98 MiB 100.00% 31.21 MiB p 🔥 Creating docker container (CPUs=2, Memory=1987MB) ... 🐳 Preparing Kubernetes v1.23.1 on Docker 20.10.12 ... ▪ kubelet.housekeeping-interval=5m ▪ Generating certificates and keys ... ▪ Booting up control plane ... ▪ Configuring RBAC rules ... 🔎 Verifying Kubernetes components... ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5 🌟 Enabled addons: default-storageclass, storage-provisioner 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Note: If you want to run minikube with a non-default version of Kubernetes for compatibility checking, you can run minikube start with, for example, --kubernetes-version v.1.2.3.

Installing minikube via Homebrew also provided kubectl, the primary tool for managing Kubernetes clusters via the command line. You can now run kubectl get as you would with any other Kubernetes cluster to list all of the pods that are running in your cluster:

  1. kubectl get pods -A

The -A argument will return pods running in all namespaces.

Output
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-64897985d-ttwl9 1/1 Running 0 46s kube-system etcd-minikube 1/1 Running 0 57s kube-system kube-apiserver-minikube 1/1 Running 0 61s kube-system kube-controller-manager-minikube 1/1 Running 0 57s kube-system kube-proxy-ddtgd 1/1 Running 0 46s kube-system kube-scheduler-minikube 1/1 Running 0 57s kube-system storage-provisioner 1/1 Running 1 (14s ago) 54s

You now have a Kubernetes cluster running locally, which you can work with using regular Kubernetes tooling like kubectl. In the next steps of this tutorial, you’ll learn how to use some of the additional functionality provided by minikube to monitor and modify your local Kubernetes configuration.

Part 2 — Accessing the Kubernetes Dashboard

Minikube implements the Kubernetes Dashboard out of the box. You can use the Kubernetes dashboard to monitor your cluster’s health, or to deploy applications manually. If you deployed Minikube locally, you can access the dashboard by running the minikube dashboard command:

  1. minikube dashboard

This command will automatically start the dashboard, forward a port from inside of your Kubernetes cluster so that you can access it directly, and open a web browser pointed to that local port.

Dashboard

Port forwarding will block the terminal it’s running in as long as it’s active, so you’ll probably want to run this in a new terminal window while you continue to work. You can press Ctrl+C to gracefully quit a blocking process such as this one when you want to stop forwarding the port.

If you’re running minikube on a remote server where you can’t easily access a web browser, you can run minikube dashboard with the --url option appended. This option will start the port forwarding process and provide a URL that you can use to access the dashboard, rather than opening a browser directly:

  1. minikube dashboard --url
Output
🤔 Verifying dashboard health ... 🚀 Launching proxy ... 🤔 Verifying proxy health ... http://127.0.0.1:34197/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

Note the port number that was returned by this command, as it will be different on your system.

However, Kubernetes’ default security configuration will prevent this URL from being accessible on a remote machine. You will need to create an SSH tunnel to access the dashboard URL. To create a tunnel from your local machine to your server, run ssh with the -L flag. Provide the port number that you noted from the forwarding process output along with the IP address of your remote server:

  1. ssh -L 34197:127.0.0.1:34197 sammy@your_server_ip

You should then be able to access the dashboard in a browser at http://127.0.0.1:34197/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/.

Now that you’ve seen more ways of working with minikube like a full Kubernetes cluster, in the next step, you’ll deploy and access a sample application to verify that your Minikube cluster is working as expected.

Part 3 — Deploying and Testing a Sample App

You can use the kubectl command to deploy a test application to your Minikube cluster. The following command will retrieve and deploy a sample Kubernetes application – in this case, Google’s hello-app.

  1. kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0

This command creates a deployment, which you are calling web inside your cluster, from a remote image called hello-app on gcr.io, Google’s container registry.

Next, expose the web deployment as a Kubernetes Service, specifying a static port where it will be accessible with --type=NodePort and --port=8080:

  1. kubectl expose deployment web --type=NodePort --port=8080

Now you can check whether the service is running with the kubectl get service command:

  1. kubectl get service web

Remember, Kubernetes NodePorts use random ports, and your output will be different:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web NodePort 10.109.254.242 <none> 8080:31534/TCP 10s

Now you can use minikube to retrieve a URL that is accessible outside of the container. This URL will allow you to access the hello-app service that is running on port 8080 inside your cluster. If you are running Minikube locally, you will not need to perform any active port forwarding using this method. To retrieve the URL for your sample application, run the following minikube service web –url command:

  1. minikube service web --url
Output
http://192.168.49.2:31534

You can now try connecting to that URL. In order to do this, you’ll use a command line program called curl, which is popular for making different types of web requests. In general, if you want to verify whether a given connection should be working in a browser under ideal circumstances, you should always test first with curl.

  1. curl http://192.168.49.2:31534
Output
Hello, world! Version: 1.0.0 Hostname: web-746c8679d4-j92tb

If you’re running minikube on a local machine, you can also visit this URL in a browser, and it should return the same unstyled plain text. If you’re running on a remote machine, you can use SSH tunneling again as in step 2 if you want to see this output in a browser.

You now have a minimal example of an application deployed via minikube. Typically, in a production Kubernetes cluster, you would provide finer-grained access to any web-accessible endpoints, but that does not depend on any minikube-specific functionality, which you’ve seen the fundamentals of here.

In the next step of this tutorial, you’ll use some of Minikube’s built in tools to change some of the default configuration values of your cluster.

Part 4 — Managing Minikube’s Resources and Filesystem

The minikube command provides several subcommands to help manage your cluster. For example, if you ever need to change the amount of available memory in your cluster, you can use minikube config to adjust the default amount. By default, this value is provided in MB, so minikube config 4096 would provide the equivalent of 4GB to your cluster:

  1. minikube config set memory 4096
Output
❗ These changes will take effect upon a minikube delete and then a minikube start

The output notes that you will need to redeploy your cluster for the change to take effect.

Note: Although production Kubernetes clusters do not normally need full redeploys when adjusting resources like memory, you should never expect to make persistent changes inside of a running Kubernetes cluster – only to your configuration files. As a result, redeploying your minikube cluster should be straightforward.

  1. minikube delete
Output
🔥 Deleting "minikube" in docker ... 🔥 Deleting container "minikube" ... 🔥 Removing /home/sammy/.minikube/machines/minikube ... 💀 Removed all traces of the "minikube" cluster.
  1. minikube start

minikube also provides the ability to temporarily mount a directory from your local file system into the cluster. You can export a directory into your cluster using the minikube mount command.

The syntax of themount command uses the following syntax: local_path:minikube_host_path. The local_path portion of the command is your local directory that you want to mount into the cluster. The minikube_host_path portion of the command is the location in the Minikube container or VM where you would like to access the files.

This sample command will mount your local home directory into your minikube cluster at the /host path:

  1. minikube mount $HOME:/host
Output
📁 Mounting host path /home/sammy into VM as /host ... ▪ Mount type: ▪ User ID: docker ▪ Group ID: docker ▪ Version: 9p2000.L ▪ Message Size: 262144 ▪ Options: map[] ▪ Bind Address: 192.168.49.1:43605 🚀 Userspace file server: ufs starting ✅ Successfully mounted /home/sammy to /host 📌 NOTE: This process must stay alive for the mount to be accessible ...

This can be useful if you want to preserve input or output such as logging from a minikube cluster.

As with port forwarding, this will run as a blocking process in this terminal until you send a Ctrl+C command. In the next and final step, you’ll learn how to efficiently switch between minikube and a full, remote Kubernetes cluster.

Part 5 — (Optional) Working with Multiple Kubernetes Clusters

In order to run multiple Kubernetes clusters locally, minikube sets up multiple profiles. For example, if you want to work with and test multiple versions of Kubernetes, you can create multiple Kubernetes clusters and switch between them using the --profile or -p flag.

If you plan to work with one specific profile for a while, the minikube profile command lets you configure the default profile that you would like to use, instead of specifying it with the --profile flag with every command.

You can start Minikube with a new profile by running minikube start with the -p flag:

  1. minikube start -p new-profile

You can then change Minikube’s active profile with minikube profile:

  1. minikube profile new-profile
Output
✅ minikube profile was successfully set to new-profile

You can also retrieve the current profile you’re working under with the get profile command:

  1. minikube config get profile
Output
New-profile

Whether or not you’re using multiple profiles, minikube automatically creates configuration files in their default locations where kubectl and other Kubernetes tooling can parse them. For example, if you were to run kubectl get nodes, it would parse your minikube cluster config, returning a single node:

  1. kubectl get nodes
Output
NAME STATUS ROLES AGE VERSION minikube Ready control-plane,master 3h18m v1.23.1

When running kubectl, you can specify the path to a different kubeconfig file than your default ~/.kube/config. kubectl will use the cluster credentials specified in that configuration instead of the default. For example, if you have another cluster configuration in a file called remote-kubeconfig.yaml, you could retrieve the nodes from that cluster using the following command:

  1. kubectl --kubeconfig=remote-kubeconfig.yaml get nodes

These non-Minikube nodes are running remotely:

Output
NAME STATUS ROLES AGE VERSION pool-xr6rvqbox-uha8f Ready <none> 2d2h v1.21.9 pool-xr6rvqbox-uha8m Ready <none> 2d2h v1.21.9 pool-xr6rvqbox-uha8q Ready <none> 2d2h v1.21.9

Kubernetes is generally designed to work with one configuration file per cluster, so that they can be passed to kubectl and other commands at runtime. While it is possible to merge configurations, best practices will vary based on your use of Kubernetes, and it is not necessary to do so. You may also want to investigate using Krew, a package manager for Kubectl plugins.

Conclusion

In this tutorial, you installed Minikube and configured the built-in Kubernetes dashboard to monitor and deploy applications. You also explored some best practices for working simultaneously with a local testing instance of minikube and a remote Kubernetes instance using Minikube profiles and the kubectl --kubeconfig flag. Testing and evaluating Kubernetes configurations using minikube locally can be a great help for determining whether and when you’re prepared to deploy Kubernetes in production.

Next, you may want to learn how to deploy some scalable applications on Kubernetes, such as ArgoCD for Continuous Deployment, or TOBS for observability.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Senior DevOps Technical Writer

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!