DEV Community

Prithiviraj R
Prithiviraj R

Posted on

Deploying a Professional Kubernetes Web UI Dashboard (kubectl-webui)

A practical, step‑by‑step guide to containerizing, publishing, and running a lightweight Kubernetes Web UI on EKS using ECR, eksctl and standard Kubernetes manifests.

Why this guide?

Working with Kubernetes purely from the CLI is powerful, but sometimes you need a small, secure web UI to help teams quickly inspect resources, tail logs, and run quick in‑pod commands without giving full kubectl access. This blog post walks through building kubectl-webui—a production‑aware Flask UI packaged as a container, pushed to ECR, and deployed to an AWS EKS cluster with RBAC, sample apps for testing, and a short troubleshooting section.

Prerequisites

Make sure you have the following installed and configured:

  • AWS CLI (aws --version) and credentials (run aws configure).
  • Docker (docker --version).
  • kubectl (kubectl version --client).
  • eksctl (eksctl version).

Verify AWS identity with:

aws sts get-caller-identity

Project overview

Repository structure (important files):

kubectl-webui/
├── app.py # Flask application
├── Dockerfile # Docker build configuration
├── requirements.txt # Python dependencies
├── templates/ # HTML templates
├── static/ # CSS / assets
├── scripts/ # helper shell scripts
├── nginx.conf
└── supervisord.conf
Enter fullscreen mode Exit fullscreen mode

Build the Docker image

Dockerfile highlights:

  • Base image: python:3.9-slim.
  • Installs kubectl and AWS CLI inside the image for cluster interactions.
  • Uses supervisord + nginx to serve the app alongside process supervision.
  • Adds an unprivileged app user and copies application files.

Build command (AMD64 for EKS node compatibility):

docker build --platform linux/amd64 -t kubectl-webui-professional:amd64 .
Enter fullscreen mode Exit fullscreen mode

Verify the image exists:

docker images | grep kubectl-webui
Enter fullscreen mode Exit fullscreen mode

Push image to Amazon ECR

Create the repository, login, tag and push:

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION="us-west-2"
REPO_NAME="kubectl-webui"


aws ecr create-repository --repository-name $REPO_NAME --region $REGION
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com


docker tag kubectl-webui-professional:amd64 $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:professional


docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:professional
Enter fullscreen mode Exit fullscreen mode

Confirm the image with:

aws ecr describe-images --repository-name $REPO_NAME --region $REGION
Enter fullscreen mode Exit fullscreen mode
Create an EKS cluster

Create a managed cluster for testing or production readiness:

eksctl create cluster \
--name kubectl-webui-cluster \
--region us-west-2 \
--nodegroup-name kubectl-webui-nodes \
--node-type t3.medium \
--nodes 2 --nodes-min 1 --nodes-max 3 --managed


aws eks update-kubeconfig --region us-west-2 --name kubectl-webui-cluster
kubectl get nodes
Enter fullscreen mode Exit fullscreen mode

Deploy the Web UI and RBAC manifests

A single YAML (kubectl-webui-k8s.yaml) contains Deployment, Service (LoadBalancer), ServiceAccount, ClusterRole and ClusterRoleBinding. Key points:

  • Deployment references the ECR image URI (replace ACCOUNT_ID and REGION).
  • Container listens on 5000 (Flask) and is exposed through an ELB on port 80.
  • RBAC is scoped to read resources (get, list, watch) for pods, services, nodes, deployments and related objects.

Apply the manifests and watch rollout:

kubectl apply -f kubectl-webui-k8s.yaml
kubectl rollout status deployment/kubectl-webui
kubectl get svc kubectl-webui-service
Enter fullscreen mode Exit fullscreen mode

Note: the LoadBalancer hostname takes a couple of minutes to provision.

Deploy sample applications (for testing)

sample-apps.yaml includes simple test workloads:

  • nginx-app + ClusterIP service
  • redis-app + ClusterIP service
  • busybox-app (sleeping pod) to exec into
  • log-collector DaemonSet (fluentd)
kubectl apply -f sample-apps.yaml

kubectl get all
Enter fullscreen mode Exit fullscreen mode

Testing the dashboard

Get LoadBalancer hostname:

kubectl get svc kubectl-webui-service -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
Enter fullscreen mode Exit fullscreen mode
  1. Open the returned URL in your browser (http). Example placeholder used in the repo is an ELB hostname.
  2. Try the UI features:
  • List pods, services, deployments
  • Describe and view pod logs
  • Exec into the busybox pod to run commands
  • View events and basic resource usage

Troubleshooting (common patterns)

ImagePullBackOff

  • Ensure the image exists in ECR and the image URI used in the Deployment is correct.
  • Use aws ecr describe-images and kubectl get deployment -o yaml | grep image to verify.

RBAC permission errors

  • Confirm the ServiceAccount exists: kubectl get sa kubectl-webui-sa.
  • Test permissions from the service account context:
kubectl auth can-i list pods --as=system:serviceaccount:default:kubectl-webui-sa
Enter fullscreen mode Exit fullscreen mode

LoadBalancer stuck in Pending

  • Confirm cluster nodes are in public subnets with proper tagging or your cloud provider setup allows ELB provisioning.
  • Check kubectl describe svc kubectl-webui-service and your cloud console for ELB status.

Pod fails to start

  • Inspect logs: kubectl logs -l app=kubectl-webui.
  • Describe the pod for events: kubectl describe pod -l app=kubectl-webui.

Architecture (high level)

Developer browser → ELB (LoadBalancer) → kubectl-webui Pod → Kubernetes API Server → cluster workloads (nginx, redis, busybox)

This pattern keeps the UI stateless (single replica acceptable for small teams) and relies on EKS IAM + Kubernetes RBAC to control access.

Security & Production Notes

  • Do not give this UI cluster‑wide admin rights. Keep RBAC read‑only or narrowly scoped.
  • If exposing publicly, place the service behind an HTTPS ALB with authentication (OIDC, Cognito or a reverse proxy with auth).
  • Use image scanning and automated CI to build/push images, and use immutable tags (e.g. :sha-<commit>) rather than :latest.

Conclusion

The kubectl‑webui project demonstrates how a compact, secure web UI can simplify everyday cluster operations while preserving Kubernetes best practices. By containerizing the app, publishing images to ECR, and deploying on EKS with scoped RBAC, you get a reproducible, auditable workflow that teams can trust. For production use, tighten access with HTTPS and authentication, use private networking where possible, and adopt CI/CD with immutable image tags.

Happy learning

Prithiviraj Rengarajan
DevOps Engineer

Top comments (0)