Deploy your first application to Kubernetes
Before starting, make sure you have the following set up:
# Check Docker is installed and running
docker --version
# Check kubectl is available
kubectl version --client
# Verify Kubernetes cluster is running
kubectl cluster-info
# Check nodes are ready
kubectl get nodes
Look for the whale icon in your system tray/menu bar. It should be running (not showing any errors).
Click the gear icon (⚙️) → Kubernetes → Ensure "Enable Kubernetes" is checked.
In the bottom-left corner, you should see both Docker (whale) and Kubernetes (ship wheel) icons in green.
First, let's understand what files we're working with:
The Dockerfile creates a container image that:
nginx:alpine as the base (a lightweight web server)FROM nginx:alpine
COPY app/ /usr/share/nginx/html/
EXPOSE 80
The Deployment tells Kubernetes to:
lab-app:v1)The Service exposes our application to the network:
NodePort makes it accessible from your machineapp: lab-appNavigate to the project directory and build the image:
# Navigate to the lab directory
cd k8s-lab
# Build the Docker image
docker build -t lab-app:v1 .
-t lab-app:v1 tags the image with name "lab-app" and version "v1". The . tells Docker to use the current directory.Verify the image was created:
docker images | grep lab-app
lab-app v1 abc123def 10 seconds ago 45MBOpen Terminal (Mac/Linux) or PowerShell/Command Prompt (Windows)
cd k8s-lab && docker build -t lab-app:v1 .
Open Docker Desktop → Click "Images" in the left sidebar → You should see lab-app with tag v1
Apply the Kubernetes manifests to create your resources:
# Create the Deployment (runs your app pods)
kubectl apply -f manifests/deployment.yaml
# Create the Service (exposes your app)
kubectl apply -f manifests/service.yaml
deployment.apps/lab-app createdservice/lab-app-service createdkubectl apply -f manifests/Docker Desktop's Kubernetes doesn't have a GUI for applying manifests, so we'll use kubectl:
kubectl apply -f manifests/
Open Docker Desktop → Click "Containers" → Look for containers with lab-app in the name
kubectl commands.Check that all resources are running correctly:
# Check the Deployment status
kubectl get deployments
# Check the Pods (should show 2 running)
kubectl get pods
# Check the Service
kubectl get services
READY 2/2Running with 1/1 readyNodePort with port 30080Watch pods start up in real-time:
# Watch until pods are Running (Ctrl+C to stop)
kubectl get pods -w
Click on "Containers" in the left sidebar
Look for containers named k8s_lab-app_lab-app-xxxxx. You should see 2 of them (for 2 replicas).
Each container should show a green "Running" status
Symptoms: kubectl get pods shows status other than "Running"
Get more details about the pod:
# Get pod name first
kubectl get pods
# Describe the pod (replace with actual name)
kubectl describe pod lab-app-xxxxxx
Look at the Events section at the bottom for error messages.
Symptoms: Pod status shows "ImagePullBackOff" or "ErrImagePull"
Cause: Kubernetes can't find the Docker image
1. Verify the image exists locally:
docker images | grep lab-app
2. If the image doesn't exist, rebuild it:
docker build -t lab-app:v1 .
3. Make sure you're in the k8s-lab directory when building!
Symptoms: Browser shows "connection refused" or "site can't be reached"
1. Check pods are running:
kubectl get pods
2. Check service exists and has correct port:
kubectl get services
3. Check service has endpoints (should show pod IPs):
kubectl get endpoints lab-app-service
4. If endpoints are empty, check pod labels match service selector.
Symptoms: kubectl commands return errors about connection or server
1. Open Docker Desktop Settings (gear icon)
2. Go to Kubernetes
3. Ensure "Enable Kubernetes" is checked
4. If already checked, click "Reset Kubernetes Cluster"
5. Wait for the Kubernetes icon to turn green
Symptoms: Service can't start or port conflict error
1. Find what's using the port:
# Mac/Linux
lsof -i :30080
# Windows
netstat -ano | findstr :30080
2. Either stop that process, or edit service.yaml to use a different nodePort (30000-32767)
Logs help debug application issues:
# View logs for a specific pod
kubectl logs lab-app-xxxxxx
# Follow logs in real-time
kubectl logs -f lab-app-xxxxxx
# View logs for all pods with a label
kubectl logs -l app=lab-app
To delete everything and start fresh:
# Delete Kubernetes resources
kubectl delete -f manifests/
# Delete the Docker image
docker rmi lab-app:v1
# Verify cleanup
kubectl get all
docker images | grep lab-app
Completed the lab? Try these challenges to deepen your Kubernetes knowledge:
Increase the number of pod replicas:
# Scale to 4 replicas
kubectl scale deployment lab-app --replicas=4
# Watch pods scale up
kubectl get pods -w
# Scale back down
kubectl scale deployment lab-app --replicas=2
Open a shell inside a running container:
# Get pod name
kubectl get pods
# Open shell in pod (replace xxxxx)
kubectl exec -it lab-app-xxxxx -- /bin/sh
# Inside the container, explore:
ls /usr/share/nginx/html
cat /etc/nginx/nginx.conf
exit
Update your application with zero downtime:
# Make a change to app/index.html
# Then build a new version
docker build -t lab-app:v2 .
# Update the deployment
kubectl set image deployment/lab-app lab-app=lab-app:v2
# Watch the rolling update
kubectl rollout status deployment/lab-app
# Rollback if needed
kubectl rollout undo deployment/lab-app
Monitor CPU and memory usage:
# View pod resource usage
kubectl top pods
# View node resource usage
kubectl top nodes
# Describe pod to see resource limits
kubectl describe pod lab-app-xxxxx | grep -A 5 "Limits\|Requests"
kubectl top requires the metrics-server to be installed. In Docker Desktop, this may need to be enabled separately.# --- Viewing Resources ---
kubectl get pods # List all pods
kubectl get deployments # List all deployments
kubectl get services # List all services
kubectl get all # List everything
# --- Detailed Information ---
kubectl describe pod [name] # Pod details & events
kubectl logs [pod-name] # View pod logs
kubectl logs -f [pod-name] # Stream logs live
# --- Managing Resources ---
kubectl apply -f [file] # Create/update resource
kubectl delete -f [file] # Delete resource
kubectl scale deployment [name] --replicas=N
# --- Debugging ---
kubectl exec -it [pod] -- /bin/sh # Shell into pod
kubectl get events # View cluster events