Kubernetes Getting Started
This article has been initially checked against the Ubuntu 26.04 LTS April 2026 release notes. Kubernetes component versions and production deployment details still need ongoing validation against MicroK8s and upstream updates.
Kubernetes (abbreviated as K8s) is the most popular container orchestration platform today, open-sourced by Google and donated to the CNCF (Cloud Native Computing Foundation). It automates the deployment, scaling, and management of containerized applications, and is the cornerstone of modern cloud-native architecture.
Ubuntu is one of the mainstream Linux distributions for running Kubernetes. Canonical also offers MicroK8s — a lightweight, easy-to-install Kubernetes distribution that’s ideal for development, testing, and edge computing scenarios.
What Is K8s and Why You Need It
Pain Points Before K8s
In the containerization era, Docker solved the problem of “packaging and running applications.” But when you have dozens or even hundreds of containers to manage, new challenges arise:
- If a container crashes, who automatically restarts it?
- When traffic increases, how do you auto-scale?
- How do containers discover and communicate with each other?
- How do you perform rolling updates without service interruption?
- How do you schedule containers across multiple servers?
What K8s Solves
Kubernetes was built to address these exact problems:
| Feature | Description |
|---|---|
| Self-healing | Automatically restarts crashed containers; migrates workloads when nodes fail |
| Horizontal scaling | Automatically increases or decreases container instances based on load |
| Service discovery | Containers auto-register and access each other via DNS names |
| Rolling updates | Gradually replaces old versions for zero-downtime deployments |
| Load balancing | Automatically distributes traffic across multiple container instances |
| Configuration management | Centralized management of application configs and secrets |
MicroK8s Installation
MicroK8s is Canonical’s lightweight Kubernetes, installed via Snap with a single command.
Installing MicroK8s
# Install MicroK8s
# Choose the latest stable channel; check snap info microk8s for available versions
sudo snap install microk8s --classic --channel=1.33/stable
# Add current user to the microk8s group (avoid sudo every time)
sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube
# Re-login for group permissions to take effect
newgrp microk8s
# Check installation status
microk8s status --wait-readyEnabling Common Add-ons
MicroK8s comes with many built-in add-ons:
# Enable DNS (internal cluster name resolution -- almost always required)
microk8s enable dns
# Enable local storage
microk8s enable hostpath-storage
# Enable Dashboard (web management interface)
microk8s enable dashboard
# Enable Ingress (HTTP reverse proxy)
microk8s enable ingress
# Enable container image registry
microk8s enable registry
# Enable multiple add-ons at once
microk8s enable dns hostpath-storage dashboard ingress
# View all available add-ons
microk8s statusConfiguring the kubectl Alias
MicroK8s includes microk8s kubectl, but typing it every time is tedious. You can set up an alias:
# Option 1: Use an alias
alias kubectl='microk8s kubectl'
echo "alias kubectl='microk8s kubectl'" >> ~/.bashrc
# Option 2: Export config for a standalone kubectl installation
microk8s config > ~/.kube/configkubectl Basic Operations
kubectl is the command-line tool for interacting with Kubernetes clusters.
Cluster Information
# View cluster information
kubectl cluster-info
# View all nodes
kubectl get nodes
# View node details
kubectl describe node <node-name>
# View cluster component status
kubectl get componentstatusesViewing Resources
# View all Pods
kubectl get pods
# View Pods across all namespaces
kubectl get pods --all-namespaces
# Or shorthand
kubectl get pods -A
# View Pod details (wide output)
kubectl get pods -o wide
# View all Deployments
kubectl get deployments
# View all Services
kubectl get services
# Or shorthand
kubectl get svc
# View all resources
kubectl get allResource Details and Logs
# View Pod details
kubectl describe pod <pod-name>
# View Pod logs
kubectl logs <pod-name>
# Follow logs in real-time
kubectl logs -f <pod-name>
# View logs for a specific container in a multi-container Pod
kubectl logs <pod-name> -c <container-name>
# Execute commands inside a Pod
kubectl exec -it <pod-name> -- /bin/bashCore Concepts
Pod
A Pod is the smallest deployable unit in Kubernetes. A Pod contains one or more containers that share networking and storage.
# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80# Create a Pod
kubectl apply -f pod-example.yaml
# Check Pod status
kubectl get pod nginx-pod
# Delete a Pod
kubectl delete pod nginx-podDeployment
A Deployment manages Pod replica counts, rolling updates, and rollbacks. In practice, you’ll almost never create Pods directly — instead, you manage them through Deployments.
# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"# Deploy the application
kubectl apply -f deployment-example.yaml
# View deployment status
kubectl get deployment nginx-deployment
# Scale up/down
kubectl scale deployment nginx-deployment --replicas=5
# View rolling update status
kubectl rollout status deployment nginx-deployment
# Update image version
kubectl set image deployment/nginx-deployment nginx=nginx:1.28
# Rollback to previous version
kubectl rollout undo deployment nginx-deployment
# View update history
kubectl rollout history deployment nginx-deploymentService
A Service provides a stable network endpoint for a set of Pods. Pod IPs change dynamically, while a Service provides a fixed access point.
# service-example.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIPService type descriptions:
| Type | Description |
|---|---|
| ClusterIP | Default; accessible only within the cluster |
| NodePort | Opens a port on every node; externally accessible |
| LoadBalancer | Uses the cloud provider’s load balancer |
# Create a Service
kubectl apply -f service-example.yaml
# View the Service
kubectl get svc nginx-service
# Expose a service with NodePort
kubectl expose deployment nginx-deployment --type=NodePort --port=80Deploying Your First Application
Let’s deploy a complete web application from start to finish.
Step 1: Create a Deployment
# Quickly create using the command line
kubectl create deployment hello-app --image=gcr.io/google-samples/hello-app:1.0
# Verify the Pod is running
kubectl get pods -l app=hello-appStep 2: Expose the Service
# Create a NodePort Service
kubectl expose deployment hello-app --type=NodePort --port=8080
# View the assigned port
kubectl get svc hello-appStep 3: Access the Application
# Get the access URL
# MicroK8s runs locally by default, so use localhost
NODE_PORT=$(kubectl get svc hello-app -o jsonpath='{.spec.ports[0].nodePort}')
echo "Access URL: http://localhost:$NODE_PORT"
# Test access
curl http://localhost:$NODE_PORTStep 4: Scale Up
# Scale to 3 replicas
kubectl scale deployment hello-app --replicas=3
# View all Pods
kubectl get pods -l app=hello-appStep 5: Clean Up
# Delete the Service and Deployment
kubectl delete svc hello-app
kubectl delete deployment hello-appHelm Package Management
Helm is the package manager for Kubernetes, similar to Ubuntu’s apt. It uses Charts (packages) to define, install, and upgrade complex Kubernetes applications.
Installing Helm
# Option 1: Install via Snap
sudo snap install helm --classic
# Option 2: Install via official script
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Verify installation
helm versionUsing Helm
# Add the official stable repository
helm repo add bitnami https://charts.bitnami.com/bitnami
# Update repository index
helm repo update
# Search for Charts
helm search repo nginx
helm search repo mysql
# Install an application (Redis example)
helm install my-redis bitnami/redis
# View installed Releases
helm list
# View Release status
helm status my-redis
# Install with custom configuration
helm install my-nginx bitnami/nginx \
--set replicaCount=3 \
--set service.type=NodePort
# Install with a values file for custom configuration
helm install my-app bitnami/nginx -f custom-values.yaml
# Upgrade a Release
helm upgrade my-redis bitnami/redis --set auth.enabled=false
# Rollback
helm rollback my-redis 1
# Uninstall a Release
helm uninstall my-redisCreating Your Own Chart
# Create a new Chart template
helm create my-chart
# Directory structure
# my-chart/
# Chart.yaml # Chart metadata
# values.yaml # Default configuration values
# templates/ # K8s resource templates
# deployment.yaml
# service.yaml
# ingress.yaml
# Validate the Chart
helm lint my-chart/
# Dry-run install (no actual deployment)
helm install my-release my-chart/ --dry-run --debug
# Package the Chart
helm package my-chart/Quick Reference Command Table
| Operation | Command |
|---|---|
| View cluster status | kubectl cluster-info |
| View all Pods | kubectl get pods -A |
| View Pod logs | kubectl logs POD_NAME |
| Enter a Pod | kubectl exec -it POD_NAME -- bash |
| Create a resource | kubectl apply -f file.yaml |
| Delete a resource | kubectl delete -f file.yaml |
| Scale up | kubectl scale deployment NAME --replicas=N |
| Update image | kubectl set image deployment/NAME container=image |
| Rollback | kubectl rollout undo deployment/NAME |
| Port forward | kubectl port-forward pod/NAME 8080:80 |
| View resource usage | kubectl top pods |
| MicroK8s status | microk8s status |
| MicroK8s start | microk8s start |
| MicroK8s stop | microk8s stop |
Production Considerations
MicroK8s is excellent for learning and development, but when using Kubernetes in production, keep these points in mind:
- High availability cluster: Production requires at least 3 control plane nodes to avoid single points of failure
- Resource limits: Always set
resources.requestsandresources.limitsfor every container to prevent one application from consuming all node resources - Network policies: Configure NetworkPolicy to restrict Pod-to-Pod communication following the principle of least privilege
- RBAC permissions: Don’t run applications with cluster-admin privileges; create dedicated ServiceAccounts for each service
- Image security: Only use trusted image registries, regularly scan images for vulnerabilities, and avoid using the
latesttag - Back up etcd: etcd stores all cluster state data — regular backups are critical
- Monitoring and alerting: Deploy Prometheus + Grafana to monitor cluster health
- Log collection: Use EFK (Elasticsearch + Fluentd + Kibana) or Loki for log aggregation
For enterprise-grade support, consider Canonical’s Charmed Kubernetes or managed K8s services from cloud providers (e.g., AWS EKS, Google GKE, Azure AKS).
Common Troubleshooting
# Pod stuck in Pending state
kubectl describe pod <pod-name>
# Usually caused by insufficient resources or node selector mismatch
# Pod in CrashLoopBackOff
kubectl logs <pod-name> --previous
# View logs from the previous crash
# Cannot pull image (ImagePullBackOff)
kubectl describe pod <pod-name>
# Check if the image name is correct and whether image pull credentials are needed
# Service inaccessible
kubectl get endpoints <service-name>
# Verify that the Service selector matches the Pod labels
# DNS resolution failure
kubectl run test --image=busybox --rm -it -- nslookup kubernetes.default
# Check if CoreDNS is running properlyAfter mastering the above content, you’ll have the ability to run and manage basic Kubernetes workloads on Ubuntu. As your experience grows, you can further explore ConfigMap, Secret, PersistentVolume, Ingress, CronJob, and other resource types.