tutorial

Monitoring Contour Ingress on Kubernetes with Vigilmon

Contour routes traffic to your Kubernetes services through Envoy — but when the proxy or its control plane falters, your users feel it first. Here's how to monitor Contour-managed services, TLS certificates, and ingress health with Vigilmon.

Contour is a Kubernetes ingress controller built on Envoy Proxy that introduces HTTPProxy objects for safer, multi-team ingress configuration. It replaces the limitations of the Ingress resource with namespace delegation, per-route TLS, and fine-grained traffic policies. But Contour doesn't monitor itself — when the Envoy data plane crashes, when Contour's control plane stops reconciling, or when a TLS certificate expires, your team finds out from users. Vigilmon adds the external uptime layer that catches ingress failures from the outside: HTTP checks for routed services, SSL expiry alerts, and heartbeat monitors for certificate renewal pipelines.

What You'll Set Up

  • External HTTP uptime monitors for services routed through Contour
  • SSL certificate expiry alerts for Contour TLS termination
  • Heartbeat monitoring for cert-manager certificate renewals
  • TCP port monitoring for the Envoy proxy LoadBalancer

Prerequisites

  • Contour 1.27+ installed on a Kubernetes cluster (kubectl get httpproxies)
  • At least one HTTPProxy routing traffic to a backend service
  • A free Vigilmon account

Step 1: Monitor Your HTTPProxy Endpoints

Contour's HTTPProxy objects define how external traffic reaches your services. Monitor the external URL of each critical HTTPProxy to confirm the full path — DNS, LoadBalancer, Envoy, and backend — is working:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter the external URL of your service: https://api.example.com/health.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Click Save.

This external check catches failures that Kubernetes readiness probes miss: a misconfigured HTTPProxy, a broken certificate, a LoadBalancer IP that changed, or an Envoy worker that stopped routing.

Repeat for each HTTPProxy that serves production traffic.


Step 2: Add Health Endpoints to Backend Services

For Vigilmon to verify the backend and not just the Envoy layer, expose a /health route in each service and route it through Contour:

# HTTPProxy with health check route
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: api-proxy
  namespace: production
spec:
  virtualhost:
    fqdn: api.example.com
    tls:
      secretName: api-tls
  routes:
    - conditions:
        - prefix: /health
      services:
        - name: api-service
          port: 8080
    - conditions:
        - prefix: /
      services:
        - name: api-service
          port: 8080

Add a minimal health handler to your service:

# FastAPI example
@app.get("/health")
def health():
    return {"status": "ok", "uptime": time.monotonic()}
// Go example
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    w.Write([]byte(`{"status":"ok"}`))
})

Now the Vigilmon probe at https://api.example.com/health traverses Contour's full data path and verifies the backend in one check.


Step 3: TCP Port Monitoring for the Envoy LoadBalancer

Contour deploys Envoy as a LoadBalancer service (or a NodePort if you're using a bare-metal setup). Monitor the underlying TCP port to detect failures before HTTP-level checks fire:

  1. Click Add Monitor in Vigilmon.
  2. Set Type to TCP.
  3. Enter the LoadBalancer IP or hostname and port: <EXTERNAL-IP>:443.
  4. Set Check interval to 1 minute.
  5. Click Save.

Get the external IP:

kubectl get svc envoy -n projectcontour
# NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)
# envoy   LoadBalancer   10.96.1.1       203.0.113.10    80:31234/TCP,443:31235/TCP

Add monitors for both port 80 and port 443. A TCP failure when HTTP is responding usually means a LoadBalancer health check misconfiguration. A TCP failure when HTTP is also failing confirms the Envoy Pod is down.


Step 4: SSL Certificate Expiry Alerts

Contour supports TLS termination using Kubernetes Secrets referenced in HTTPProxy virtualhost.tls sections. Add SSL monitoring for each TLS-enabled virtual host:

  1. Open the HTTP / HTTPS monitor for your endpoint (from Step 1).
  2. Enable Monitor SSL certificate.
  3. Set Alert when certificate expires in less than 21 days.
  4. Click Save.

For virtual hosts that use Contour's TLSCertificateDelegation to share certificates across namespaces, verify that each namespace's monitors cover the delegated certificate:

# TLSCertificateDelegation sharing a cert across namespaces
apiVersion: projectcontour.io/v1
kind: TLSCertificateDelegation
metadata:
  name: tls-delegation
  namespace: cert-team
spec:
  delegations:
    - secretName: wildcard-tls
      targetNamespaces:
        - production
        - staging

Add one Vigilmon SSL monitor for each hostname that uses the delegated certificate so expiry is caught regardless of which namespace triggers it.


Step 5: Heartbeat Monitor for cert-manager Renewals

Contour integrates tightly with cert-manager for automatic certificate provisioning. Monitor the renewal pipeline with a Kubernetes CronJob that pings Vigilmon after confirming certificate freshness:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: contour-cert-heartbeat
  namespace: production
spec:
  schedule: "0 */6 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: cert-checker
          containers:
            - name: check
              image: bitnami/kubectl:latest
              command:
                - /bin/sh
                - -c
                - |
                  # Verify the TLS secret exists and is recent
                  kubectl get secret api-tls -n production -o name || exit 1

                  # Confirm certificate is not expiring within 30 days
                  EXPIRY=$(kubectl get secret api-tls -n production \
                    -o jsonpath='{.data.tls\.crt}' \
                    | base64 -d \
                    | openssl x509 -noout -checkend 2592000 2>&1)
                  echo "$EXPIRY"

                  # Ping Vigilmon heartbeat
                  wget -q -O- https://vigilmon.online/heartbeat/abc123
          restartPolicy: OnFailure

Set the Vigilmon heartbeat interval to 7 hours. Two missed runs (14 hours) trigger an alert — enough lead time to investigate before a certificate expires.


Step 6: Monitor Contour's Status API

Contour exposes a status API on each HTTPProxy object. While you can't hit this from Vigilmon directly, you can build a lightweight probe service that checks proxy status and exposes a public health endpoint:

#!/bin/bash
# Check all HTTPProxy resources are valid (not in error state)
INVALID=$(kubectl get httpproxies --all-namespaces -o json \
  | jq '[.items[] | select(.status.currentStatus != "valid")] | length')

if [ "$INVALID" -gt 0 ]; then
  echo "ERROR: $INVALID HTTPProxy resources are not valid"
  exit 1
fi

echo "All HTTPProxy resources are valid"
curl -s https://vigilmon.online/heartbeat/def456

Run this as a Kubernetes CronJob every 5 minutes with a Vigilmon heartbeat interval of 10 minutes. An invalid HTTPProxy — caused by a missing backend service, a TLS reference error, or a conflicting route — gets caught before it causes visible downtime.


Step 7: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a webhook.
  2. For external endpoint monitors, set Consecutive failures before alert to 2 — Contour rolling restarts can cause a single probe to fail.
  3. For SSL monitors, set it to 1 — a failed TLS handshake is always actionable.
  4. For heartbeat monitors, set it to 1 — a missed cert check warrants immediate investigation.
  5. Use Maintenance windows in Vigilmon during Contour upgrades to suppress expected restart noise.

Summary

| Monitor | Target | What It Catches | |---|---|---| | HTTPProxy endpoint | https://api.example.com/health | Data plane failure, route misconfiguration | | TCP port | <LB-IP>:443 | Envoy Pod down, LoadBalancer failure | | SSL certificate | Each virtual host hostname | cert-manager failure, manual cert expiry | | cert-manager heartbeat | CronJob ping | Renewal pipeline failure, ACME challenge issue | | HTTPProxy status | CronJob + Vigilmon heartbeat | Invalid proxy objects causing silent routing errors |

Contour gives you expressive, namespace-safe ingress routing — Vigilmon gives you the external perspective that confirms it's working from your users' point of view. Together they close the gap between "the HTTPProxy is valid" and "requests are actually getting through."

Monitor your app with Vigilmon

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

Start free →