Kubernetes (K3s) Setup Guide¶
A comprehensive guide for installing and configuring a lightweight Kubernetes cluster using K3s on Ubuntu.
What is K3s?¶
K3s is a lightweight, certified Kubernetes distribution designed for resource-constrained environments. It bundles everything needed into a single binary under 100MB.
Server Installation¶
Install K3s Server (Control Plane)¶
Verify Node Readiness¶
Wait approximately 30 seconds, then verify:
Retrieve Node Token¶
The token is required for joining worker nodes:
Get Kubeconfig¶
Tip: Copy this file to your local machine for remote
kubectlaccess. Replace theserveraddress127.0.0.1with your server's IP.
# Copy kubeconfig to local machine
scp your_username@10.0.0.10:/etc/rancher/k3s/k3s.yaml ~/.kube/k3s.yaml
export KUBECONFIG=~/.kube/k3s.yaml
Agent (Worker Node) Installation¶
Join a Worker Node¶
Replace 10.0.0.10 with your server's IP and <your_node_token> with the token from the server.
Verify Cluster¶
On the server node:
kubectl Basics¶
# List all pods across namespaces
kubectl get pods -A
# List nodes
kubectl get nodes -o wide
# Describe a specific resource
kubectl describe pod <pod_name> -n <namespace>
# View logs
kubectl logs <pod_name> -n <namespace>
kubectl logs <pod_name> -n <namespace> -f # follow
# Execute command in a pod
kubectl exec -it <pod_name> -n <namespace> -- /bin/bash
Deployments and ReplicaSets¶
Create a Deployment¶
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Scale a Deployment¶
Services¶
ClusterIP (Internal Only)¶
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
NodePort (External Access via Node IP)¶
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
LoadBalancer¶
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
Ingress with Traefik¶
K3s ships with Traefik as the default Ingress Controller.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-clusterip
port:
number: 80
Persistent Volumes and StorageClasses¶
PersistentVolumeClaim¶
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 5Gi
Note: K3s includes the
local-pathStorageClass by default.
Use PVC in a Pod¶
spec:
containers:
- name: app
image: nginx:1.25
volumeMounts:
- mountPath: /data
name: app-storage
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: app-pvc
ConfigMaps and Secrets¶
ConfigMap¶
# Or as YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
Secret¶
kubectl create secret generic app-secret \
--from-literal=DB_PASSWORD=your_password_here \
--from-literal=API_KEY=your_api_token_here
Helm Basics¶
Install Helm¶
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
Install a Chart (Example: Rancher)¶
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
helm repo update
kubectl create namespace cattle-system
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=rancher.example.com \
--set bootstrapPassword=your_password_here
Verify Installation¶
Troubleshooting¶
Port Conflicts¶
# Check what is using a port
sudo lsof -i :6443
sudo lsof -i :6444
# Kill blocking process
sudo kill -9 <PID>
Service Logs¶
# Server logs
sudo journalctl -u k3s.service -f
# Agent logs
sudo journalctl -u k3s-agent.service -f
Firewall Ports¶
Ensure these ports are open:
| Port | Protocol | Description |
|---|---|---|
| 6443 | TCP | Kubernetes API |
| 8472 | UDP | Flannel VXLAN |
| 10250 | TCP | Kubelet metrics |
| 51820 | UDP | Flannel WireGuard |