tutorial

How to Monitor Glasskube with Vigilmon

Glasskube is an open-source Kubernetes package manager that brings `apt`-style package management to Kubernetes — with a web UI, CLI, GitOps integration, and...

Glasskube is an open-source Kubernetes package manager that brings apt-style package management to Kubernetes — with a web UI, CLI, GitOps integration, and automatic dependency resolution. When its package operator stops reconciling, or its repository sync falls behind, cluster packages silently drift from their desired state. External monitoring catches these failures before they become incidents.

This tutorial shows you how to use Vigilmon to monitor Glasskube's operator health, repository sync status, and update pipeline.


Why Glasskube needs external monitoring

Glasskube has several moving parts, each of which can fail independently:

| Component | Role | |---|---| | Package Operator | Controller that reconciles ClusterPackage and Package CRDs | | Package Repository | Remote index that lists available packages and versions | | Glasskube UI | Web dashboard for browsing and managing packages | | Update Pipeline | Automated checks for new package versions |

Failures in each component look different:

  • Operator crash-loops — installed packages are never updated; new Package resources stay in Pending indefinitely
  • Repository sync fails — the package catalog shows stale data; users can't discover or install new packages
  • Dependency resolution breaks — a transitive dependency update causes an incompatibility; the operator surfaces an error in the CR status but no alert fires
  • UI is unreachable — operators can't inspect package state or trigger upgrades through the dashboard
  • Update pipeline stalls — security patches don't get applied because the version check never ran

Standard Kubernetes probes only check that the operator pod is alive. They cannot check whether the repository is actually reachable, whether CRDs are being reconciled, or whether the update pipeline ran recently.


What you'll need

  • Glasskube installed on a Kubernetes cluster (glasskube bootstrap)
  • Glasskube UI exposed via Ingress or LoadBalancer
  • A free Vigilmon account

Step 1: Verify Glasskube components are running

kubectl get pods -n glasskube-system
# NAME                                    READY   STATUS    RESTARTS
# glasskube-controller-manager-xxx-yyy   1/1     Running   0
# glasskube-ui-zzz-www                   1/1     Running   0

Check the controller manager health endpoint:

kubectl port-forward -n glasskube-system svc/glasskube-controller-manager-metrics-service 8080:8080
curl -s http://localhost:8080/healthz
# ok

Step 2: Expose the UI and health endpoint

If the Glasskube UI is not yet exposed externally, add an Ingress:

# glasskube-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: glasskube-ui
  namespace: glasskube-system
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - glasskube.internal.example.com
      secretName: glasskube-tls
  rules:
    - host: glasskube.internal.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: glasskube-ui
                port:
                  number: 8080

Apply:

kubectl apply -f glasskube-ingress.yaml

Also expose the controller manager health endpoint through a separate Ingress path or use an internal Vigilmon agent:

# glasskube-health-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: glasskube-health
  namespace: glasskube-system
spec:
  ingressClassName: nginx
  rules:
    - host: glasskube-health.internal.example.com
      http:
        paths:
          - path: /healthz
            pathType: Exact
            backend:
              service:
                name: glasskube-controller-manager-metrics-service
                port:
                  number: 8080

Step 3: Monitor the package operator health

In Vigilmon:

  1. Click Add MonitorHTTP(S)
  2. URL: https://glasskube-health.internal.example.com/healthz
  3. Interval: 1 minute
  4. Expected status: 200
  5. String assertion: response body contains ok
  6. Timeout: 10 seconds
  7. Name: Glasskube – Package Operator Health
  8. Save

Step 4: Monitor repository sync status

Glasskube periodically syncs its package repository from a remote URL (defaulting to the official Glasskube repository). If the sync fails, the package catalog becomes stale.

Add a custom health endpoint that verifies the repository was synced recently. Create a CronJob that checks sync status and exposes it:

# repo-sync-check.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: repo-sync-check-script
  namespace: glasskube-system
data:
  check.sh: |
    #!/bin/sh
    # Check if the PackageRepository resource is synced
    STATUS=$(kubectl get packagerepository glasskube -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null)
    if [ "$STATUS" = "True" ]; then
      echo '{"status":"ok","repository":"synced"}'
      exit 0
    else
      echo '{"status":"error","repository":"not synced"}'
      exit 1
    fi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: repo-sync-probe
  namespace: glasskube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: repo-sync-probe
  template:
    metadata:
      labels:
        app: repo-sync-probe
    spec:
      serviceAccountName: glasskube-controller-manager
      containers:
        - name: probe
          image: bitnami/kubectl:latest
          command:
            - /bin/sh
            - -c
            - |
              while true; do
                STATUS=$(kubectl get packagerepository glasskube \
                  -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null)
                if [ "$STATUS" = "True" ]; then
                  echo "synced" > /tmp/repo-status
                else
                  echo "not-synced" > /tmp/repo-status
                fi
                sleep 30
              done
---
apiVersion: v1
kind: Service
metadata:
  name: repo-sync-probe
  namespace: glasskube-system
spec:
  selector:
    app: repo-sync-probe
  ports:
    - port: 8080
      targetPort: 8080

Expose via Ingress and add a Vigilmon HTTP monitor:

  • URL: https://glasskube-health.internal.example.com/repo-sync
  • String assertion: "synced"
  • Name: Glasskube – Repository Sync Status

Step 5: Monitor package reconciliation

Create a probe that watches for Package or ClusterPackage resources stuck in non-Ready states:

# Run this as a CronJob every 5 minutes
kubectl get clusterpackages -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}'
# cert-manager    True
# ingress-nginx   True
# prometheus      False   <-- this would trigger an alert

Build a small monitoring sidecar that surfaces this as an HTTP endpoint:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: package-health-check
  namespace: glasskube-system
spec:
  schedule: "*/5 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: glasskube-controller-manager
          containers:
            - name: check
              image: bitnami/kubectl:latest
              command:
                - /bin/sh
                - -c
                - |
                  FAILED=$(kubectl get clusterpackages -A \
                    -o jsonpath='{range .items[*]}{.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}' \
                    | grep -c "False" || true)
                  if [ "$FAILED" -gt "0" ]; then
                    echo "PACKAGES_FAILED=$FAILED"
                    exit 1
                  fi
                  echo "ALL_PACKAGES_READY"
          restartPolicy: Never

For Vigilmon monitoring, combine this with the operator health check — if the operator is healthy but packages are failing, that's the signal.


Step 6: Monitor the Glasskube UI

The Glasskube web UI is the primary interface for operators to inspect and manage packages. Monitor it separately:

  1. Add MonitorHTTP(S)
  2. URL: https://glasskube.internal.example.com/
  3. Expected status: 200
  4. String assertion: response body contains Glasskube (matches the page title)
  5. Name: Glasskube – Web UI

Also monitor TLS certificate expiry for the UI's HTTPS endpoint:

  1. In the same monitor, enable SSL certificate monitoring
  2. Alert when the cert expires in fewer than 14 days

Step 7: Monitor the update pipeline

Glasskube can automatically check for and apply package updates. Verify the update check is running by monitoring a downstream signal: check that the PackageRepository lastSyncTime is recent.

kubectl get packagerepository glasskube -o jsonpath='{.status.lastSyncTime}'
# 2026-07-01T10:23:45Z

Write a probe that returns a non-200 if the last sync is more than 2 hours old:

#!/usr/bin/env python3
# sync-age-probe.py — run as a container exposing :8080
from http.server import HTTPServer, BaseHTTPRequestHandler
from datetime import datetime, timezone
import subprocess, json

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != '/healthz':
            self.send_response(404)
            self.end_headers()
            return
        result = subprocess.run(
            ['kubectl', 'get', 'packagerepository', 'glasskube',
             '-o', 'jsonpath={.status.lastSyncTime}'],
            capture_output=True, text=True)
        last_sync = result.stdout.strip()
        if last_sync:
            sync_time = datetime.fromisoformat(last_sync.replace('Z', '+00:00'))
            age_hours = (datetime.now(timezone.utc) - sync_time).seconds / 3600
            if age_hours < 2:
                self.send_response(200)
                self.end_headers()
                self.wfile.write(b'{"status":"ok","sync_age_hours":' + str(round(age_hours,2)).encode() + b'}')
                return
        self.send_response(503)
        self.end_headers()
        self.wfile.write(b'{"status":"stale"}')

HTTPServer(('', 8080), Handler).serve_forever()

In Vigilmon, add an HTTP monitor for this probe:

  • URL: https://glasskube-health.internal.example.com/update-pipeline
  • Expected status: 200
  • Name: Glasskube – Update Pipeline

Step 8: Alerts and status page

In Vigilmon → Alert Channels, add your team's Slack and email:

  1. Set Alert after: 2 consecutive failures
  2. Enable Recovery alerts
  3. Assign channels to all monitors tagged glasskube

Create a private status page for the platform team:

  1. Status PagesNew Status Page
  2. Add all four monitors
  3. Set visibility to Private
  4. Share the URL with the platform team

Monitor checklist

| Monitor | URL pattern | What it catches | |---|---|---| | Operator health | /healthz | Operator process crash or restart loop | | Repository sync | /repo-sync | Stale package catalog | | Web UI | / | Dashboard unavailable | | Update pipeline | /update-pipeline | Version checks not running |


Summary

Glasskube's declarative package management is only as reliable as the operator, repository, and update pipeline behind it. External monitoring with Vigilmon gives you continuous health checks across all four components — so you know the moment packages stop reconciling, the catalog goes stale, or the UI disappears. Sign up free at vigilmon.online and add your first Glasskube monitor today.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →