Skip to main content

Local Kubernetes Cluster with Minikube and Virtualbox: Example Pod with Port Forwarding, Example Deployment with NodePort Service

1061 words·
Kubernetes Kubernetes Cluster Minikube Virtualbox Kubectl
Kubernetes-Cluster - This article is part of a series.
Part 1: This Article

Minikube allows to run a single-node Kubernetes cluster locally, primarily for development and testing purposes.

Installation
#

Note: Make sure virtualization is enabled.

# Check if virtualization is enabled
egrep -q 'vmx|svm' /proc/cpuinfo && echo yes || echo no

# Shell output:
yes

Virtualbox
#

Ubuntu
#

# Install Virtualbox hypervisor
sudo apt update && sudo apt install virtualbox -y

Debian
#

  • Install VirtualBox
# Install dependencies
sudo apt install software-properties-common dirmngr -y

# Import GPG Key
wget -O- -q https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmour -o /usr/share/keyrings/oracle_vbox_2016.gpg

# Add Repository
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/oracle_vbox_2016.gpg] http://download.virtualbox.org/virtualbox/debian bookworm contrib" | sudo tee /etc/apt/sources.list.d/virtualbox.list

# Install VirtualBox
sudo apt update && sudo apt install virtualbox-7.0 -y

Add to Group
#

  • Check version / verify installation
# Check version
VBoxManage --version
  • Add user to group
# Add user to the vboxusers group
sudo adduser `whoami` vboxusers
  • VirtualBox GUI
# Start VirtualBox GUI
virtualbox

Minikube
#

# Change directory
cd /tmp

# Download Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

# Install Minikube
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64

Kubectl
#

# Install Kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl &&
chmod +x kubectl &&
sudo mv kubectl /usr/local/bin/

Minicube
#

Start & Stop Minikube
#

# Start Minikube: Run Single-node Kubernetes Cluster on Virtualbox VM
minikube start --vm-driver=virtualbox

# Shell output:
...
* Verifying Kubernetes components...
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default


# Start Minikube: Run Single-node Kubernetes Cluster on local server
minikube start --driver=none


# Stop Minukube / Cluster VM
minikube stop

# Delete Cluster VM
minikube delete

Virtualbox Commands
#

# List Virtualbox commands
VBoxManage help


# List running VMs
VBoxManage list runningvms

# Shell output:
"minikube" {cd801244-7c59-4c87-b1ae-762fa975803d}


# List running & stopped VMs
VBoxManage list vms

# List VM details: minikube VM
VBoxManage showvminfo minikube

Minikube Dashboard
#

  • Local host
# List Minikube Dashboard URL: Only accessible from local host
minikube dashboard --url

# Shell output:
http://127.0.0.1:35247/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
  • Proxy
# Create proxy for Minikube Dashboard: Mmake dashboard accessible for other hosts
kubectl proxy --address='0.0.0.0' --disable-filter=true

# Open proxy Minikube Dashboard: Define server IP
http://192.168.30.91:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

Minikube Node
#

# List Minikube node
kubectl get nodes

# Shell output:
NAME       STATUS   ROLES           AGE    VERSION
minikube   Ready    control-plane   111m   v1.27.4


# List node details: minikube node
kubectl describe nodes minikube

Deployment Examples
#

Pod with Port Forwarding
#

The following example deployes a pod and creates a port forwading to test the deployment. This simple setup is useful to verify the functionality of the cluster.

Deploy Pod
#

# Run container: Syntax
kubectl run my-container --image=My-Docker-ID/target-image --port=8080 --labels app=testing

# Run container: Example
kubectl run my-container --image=jueklu/container-1 --port=8080 --labels app=testing
  • kubectl run Convenient for quickly starting a Pod to test a container image

  • --port= Specify the port that the container exposes

List Resources
#

# List resources
kubectl get all

# Shell output:
NAME               READY   STATUS    RESTARTS   AGE
pod/my-container   1/1     Running   0          19s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   83m

Port Forwarding
#

# Port forwarding: Map the local port to the container
kubectl port-forward pod/my-container 8888:8080

# Shell output:
Forwarding from 127.0.0.1:8888 -> 8080
Forwarding from [::1]:8888 -> 8080
# Stop the port forwarding
Strg + C

Note: The port is only accessible from the local machine.

Test Deployment
#

# Optional: Test container deployment
curl localhost:8888

Delete Deployment
#

# Delete container
kubectl delete pod my-container

Deployment
#

Deployment with NodePort Service
#

# Create deployment
kubectl create deployment my-container --image=jueklu/container-1

# Expose Deployment: So that the container port can be accessed
kubectl expose deployment my-container --type=NodePort --port=8080
  • kubectl create deployment Initiates a deployment that manages your pods. Unlike kubectl run, which directly starts a pod, deployments provide additional management features, like scaling and updating.

  • --type=NodePort Kubernetes by default chooses a random port from a default range (30000-32767) to expose the service on each node.

List Resources
#

# List resources
kubectl get all

# Shell output:
pod/my-container-9f9df75fc-pwdf6   1/1     Running   0          80s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP          121m
service/my-container   NodePort    10.96.103.115   <none>        8080:32593/TCP   74s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-container   1/1     1            1           80s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/my-container-9f9df75fc   1         1         1       80s

Pods:

  • pod/my-container-9f9df75fc-pwdf6 This is the pod created by the deployment

Services:

  • service/kubernetes This is the default service created by Kubernetes for internal cluster communication. It allows your applications to communicate with the Kubernetes API server.

  • service/my-container This is the service that was created to expose the deployment

Deployments:

  • deployment.apps/my-container This represents the deployment, which ensures that a specified number of pod replicas (in this case, 1) are running at any given time.

ReplicaSets:

  • replicaset.apps/my-container-9f9df75fc ReplicaSets ensure that a specified number of pod replicas are running at any time. The deployment manages this ReplicaSet to handle pod scaling and rolling updates.

Test Deployment
#

# List the IP of the Minikube node
minikube ip

# Shell output:
192.168.59.100

# Optional: Test container deployment
curl 192.168.59.100:32593

Delete Deployment
#

# Delete the deployment
kubectl delete deployment my-container

# Delete the service to clean up the network access
kubectl delete service my-container

Pod Deployment: YML Manifest
#

Create Manifest
#

# Create yml file
vi deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-container
  labels:
    app: testing
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testing
  template:
    metadata:
      labels:
        app: testing
    spec:
      containers:
      - name: jkw-demo
        image: jueklu/container-1
        ports:
        - containerPort: 8080

Test Manifest
#

# Test in client mode: Validates the manifest file locally 
kubectl apply -f deployment.yml --dry-run=client

# Test in server mode: Validates against the Kubernetes API server but doesn't create or update the resource
kubectl apply -f deployment.yml --dry-run=server

Deploy Manifest
#

# Deploy YML manifest
kubectl apply -f deployment.yml

List Resources
#

# List resources
kubectl get all

# Shell output:
NAME                                READY   STATUS    RESTARTS   AGE
pod/my-container-694754ff4b-2cwxv   1/1     Running   0          7s

NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes             ClusterIP   10.96.0.1        <none>        443/TCP          168m
service/my-container-service   NodePort    10.109.141.183   <none>        8080:32070/TCP   8s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-container   1/1     1            1           8s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/my-container-694754ff4b   1         1         1       8s

Test Deployment
#

# List the IP of the Minikube node
minikube ip

# Shell output:
192.168.59.100

# Optional: Test container deployment
curl 192.168.59.100:32070

Delete Deployment
#

# Delete deployment: Define yml file
kubectl delete -f deployment.yml

Links #

# Minikube Official Documentation
https://minikube.sigs.k8s.io/docs/start/

# Minikube Official Documentation: Commands
https://minikube.sigs.k8s.io/docs/commands/
Kubernetes-Cluster - This article is part of a series.
Part 1: This Article