Skip to main content
Back to Category

K3s Kubernetes Setup: Lightweight Container Orchestration

Single and multi-node Kubernetes cluster setup with K3s, kubectl usage, creating deployments and services, application management with Helm. Kubernetes guide for VPS environments.

Read time: 20 dk Container & Orchestration
k3skubernetescontainerorchestrationclusterkubectlhelmvps

Table of Contents

K3s Kubernetes Setup: Lightweight Container Orchestration

Kubernetes is the industry standard for container orchestration. However, a full Kubernetes installation can be resource-intensive and complex. K3s is a lightweight Kubernetes distribution developed by Rancher — it delivers all Kubernetes features in a single binary and works excellently in resource-constrained environments like VPS.

Why Choose K3s?

FeatureFull KubernetesK3s
Binary size~500MB+~100MB
Minimum RAM2GB+512MB
Setup time30-60 min5 min
DependenciesManyMinimal
Kubernetes compatibilityFullFull
Production useYesYes

K3s is fully compatible with the Kubernetes API. kubectl, Helm, and other Kubernetes tools work seamlessly with K3s. It's ideal for small to medium production environments.

System Requirements

hljs bash
# Minimum requirements
# CPU: 1 core
# RAM: 512MB (recommended: 1GB+)
# Disk: 5GB
# OS: Ubuntu 20.04+, Debian 11+, CentOS 8+

# System update
apt update && apt upgrade -y

# Install required tools
apt install -y curl wget

Single Node K3s Installation (Server)

hljs bash
# Install K3s (server mode)
curl -sfL https://get.k3s.io | sh -

# Check service status after installation
systemctl status k3s

# Check cluster status
kubectl get nodes

# List all pods
kubectl get pods -A

Kubeconfig Setup

hljs bash
# Copy kubeconfig for kubectl
mkdir -p ~/.kube
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
chmod 600 ~/.kube/config

# Set KUBECONFIG environment variable
export KUBECONFIG=~/.kube/config
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc

# View cluster info
kubectl cluster-info

Multi-Node Cluster Setup

Master Node (Server)

hljs bash
# Install master node and save token
curl -sfL https://get.k3s.io | sh -

# Get node token (required for worker nodes)
cat /var/lib/rancher/k3s/server/node-token
# Output: K10xxx...::server:yyy...

Worker Node (Agent)

hljs bash
# Join worker node to master
curl -sfL https://get.k3s.io | K3S_URL=https://MASTER_IP:6443 K3S_TOKEN=NODE_TOKEN sh -

# Verify worker joined on master
kubectl get nodes
# NAME          STATUS   ROLES                  AGE
# master-node   Ready    control-plane,master   10m
# worker-node1  Ready    <none>                 2m

Basic kubectl Commands

hljs bash
# List nodes
kubectl get nodes
kubectl get nodes -o wide  # Detailed info

# List pods
kubectl get pods
kubectl get pods -n kube-system  # System pods
kubectl get pods -A              # All namespaces

# List deployments
kubectl get deployments

# List services
kubectl get services

# List namespaces
kubectl get namespaces

# View resource details
kubectl describe pod POD_NAME
kubectl describe node NODE_NAME

# View pod logs
kubectl logs POD_NAME
kubectl logs -f POD_NAME  # Live logs

# Run command in pod
kubectl exec -it POD_NAME -- /bin/bash

Creating Your First Deployment

NGINX Deployment

hljs yaml
# nginx-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
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
hljs bash
# Apply deployment
kubectl apply -f nginx-deployment.yaml

# Check deployment status
kubectl get deployments
kubectl rollout status deployment/nginx-deployment

# List pods
kubectl get pods -l app=nginx

Creating a Service

hljs yaml
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080
  type: NodePort
hljs bash
# Apply service
kubectl apply -f nginx-service.yaml

# Check service
kubectl get services

# Access via browser: http://SERVER_IP:30080

Namespace Management

hljs bash
# Create namespaces
kubectl create namespace production
kubectl create namespace staging

# Deploy to namespace
kubectl apply -f deployment.yaml -n production

# List resources in namespace
kubectl get all -n production

# Change default namespace
kubectl config set-context --current --namespace=production

Application Management with Helm

hljs bash
# Install Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Check Helm version
helm version

# Add Bitnami repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Install WordPress
helm install my-wordpress bitnami/wordpress \
  --set wordpressUsername=admin \
  --set wordpressPassword=StrongPass123! \
  --set service.type=NodePort

# List installed charts
helm list

# Remove chart
helm uninstall my-wordpress

Persistent Volume (Persistent Storage)

hljs yaml
# pvc.yaml — Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path  # K3s default storage class
  resources:
    requests:
      storage: 5Gi
hljs bash
# Create PVC
kubectl apply -f pvc.yaml

# Check PVC status
kubectl get pvc

# List storage classes
kubectl get storageclass

ConfigMap and Secret

hljs bash
# Create ConfigMap
kubectl create configmap app-config \
  --from-literal=DB_HOST=localhost \
  --from-literal=APP_ENV=production

# Create Secret
kubectl create secret generic app-secret \
  --from-literal=DB_PASSWORD=StrongPass123! \
  --from-literal=API_KEY=abc123

# View ConfigMap
kubectl get configmap app-config -o yaml

# View Secret (base64 encoded)
kubectl get secret app-secret -o yaml

K3s Update and Management

hljs bash
# Update K3s
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.28.0+k3s1 sh -

# Manage K3s service
systemctl stop k3s
systemctl start k3s
systemctl restart k3s

# View K3s logs
journalctl -u k3s -f

# Uninstall K3s
/usr/local/bin/k3s-uninstall.sh

# Remove worker node
/usr/local/bin/k3s-agent-uninstall.sh

Monitoring: Kubernetes Dashboard

hljs bash
# Install Kubernetes Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# Create admin user
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF

# Generate token
kubectl -n kubernetes-dashboard create token admin-user

# Start proxy for dashboard access
kubectl proxy
# http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

Conclusion

K3s delivers the full power of Kubernetes with minimal resource usage. It's an ideal solution for production-grade container orchestration in VPS environments. With K3s on REXE servers, you can easily scale your applications, ensure high availability, and implement modern DevOps practices.