Deploying a Hello World Web App on K3s Cluster on Proxmox

This guide walks through deploying a simple nginx-based hello world application on a K3s cluster, using Traefik ingress for external access on standard HTTP port 80.

Prerequisites

  • Running K3s cluster with at least one master node
  • kubectl configured to access your cluster
  • Firewall allowing HTTP traffic on port 80
  • Traefik ingress controller (comes pre-installed with K3s)

Step 1: Create the Application Deployment

Create a file called nginx-hello-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hello
  labels:
    app: nginx-hello
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-hello
  template:
    metadata:
      labels:
        app: nginx-hello
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html-content
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html-content
        configMap:
          name: nginx-hello-html
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-hello-html
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head>
        <title>Hello from Kubernetes!</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                text-align: center;
                padding: 50px;
                margin: 0;
            }
            .container {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 10px;
                padding: 40px;
                max-width: 600px;
                margin: 0 auto;
                backdrop-filter: blur(10px);
            }
            h1 { font-size: 3em; margin-bottom: 20px; }
            p { font-size: 1.2em; margin: 10px 0; }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>🎉 Hello from Kubernetes! 🎉</h1>
            <p>This nginx pod is running on your K3s cluster</p>
            <p>Deployed on experimental infrastructure</p>
        </div>
    </body>
    </html>

Step 2: Create Service and Ingress

Create nginx-hello-ingress.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-hello-service
spec:
  selector:
    app: nginx-hello
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-hello-ingress
spec:
  ingressClassName: traefik
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-hello-service
            port:
              number: 80

Step 3: Deploy the Application

# Apply the deployment
kubectl apply -f nginx-hello-deployment.yaml

# Apply the service and ingress
kubectl apply -f nginx-hello-ingress.yaml

Step 4: Verify Deployment

# Check pods are running
kubectl get pods -l app=nginx-hello

# Verify service
kubectl get svc nginx-hello-service

# Check ingress status
kubectl describe ingress nginx-hello-ingress

# Verify Traefik is running
kubectl get svc -n kube-system traefik

Step 5: Access Your Application

Once deployed, access your hello world application at:

  • http://<any-node-ip>/ (e.g., http://10.3.34.10/)

Test with curl:

curl http://<node-ip>/

Key Components Explained

Deployment: Creates 2 nginx pods for high availability ConfigMap: Contains the custom HTML content served by nginx Service: Exposes the pods internally within the cluster Ingress: Routes external HTTP traffic to the service using Traefik

Troubleshooting

404 Not Found: Ensure the ingress path matches what nginx serves (usually /) Connection Timeout: Check firewall rules allow port 80 Pods Not Starting: Check kubectl logs -l app=nginx-hello Ingress Not Working: Verify Traefik is running with kubectl get pods -n kube-system | grep traefik