tutorial

Monitoring KCL Kubernetes Configurations with Vigilmon: Deployed Service Health, Schema Drift, Ingress Availability & SSL Certificate Alerts

How to monitor KCL (KusionStack Configuration Language) Kubernetes deployments with Vigilmon — service health checks, ingress availability, schema-driven configuration drift, and SSL certificate expiry alerts.

KCL (KusionStack Configuration Language) is a constraint-based record and functional language designed for Kubernetes and cloud-native configuration at scale. Teams use KCL to write typed, composable Kubernetes configurations with schema enforcement — ensuring that Deployments, Services, and Ingresses conform to organizational standards before ever reaching the cluster. When a KCL schema validation passes but the underlying configuration produces a Deployment with the wrong container port, the pods start but traffic cannot reach them. When a KCL module update changes a Service type from LoadBalancer to ClusterIP in a shared schema, all services inheriting that schema lose their external IPs silently. When the kcl-operator (running in-cluster to reconcile KCLRun CRs) crashes or falls behind, Kubernetes resources drift from their KCL-defined desired state without any alert. Vigilmon gives you external visibility into the services your KCL configurations deploy: continuous HTTP health monitoring, SSL certificate expiry tracking, and TCP-level connectivity checks that catch configuration drift, schema-induced failures, and cluster-level events the moment they affect your users.

What You'll Build

  • HTTP monitors on the health endpoints of services produced by KCL configurations
  • SSL certificate monitoring for every hostname in KCL-managed Ingress resources
  • TCP monitors on service ports to detect port or type changes from KCL schema updates
  • An alerting runbook that maps KCL configuration failure modes to Kubernetes inspection commands

Prerequisites

  • A Kubernetes cluster receiving configurations generated by KCL (applied via kcl run, Kusion, or the kcl-operator)
  • At least one service exposed externally (Ingress or LoadBalancer)
  • HTTPS configured for production services
  • A free account at vigilmon.online

Step 1: Understand KCL's Monitoring Surface

KCL is a configuration language and compiler — it produces Kubernetes YAML that is applied to the cluster via kubectl, kusion apply, or the kcl-operator. After configuration is applied, KCL itself has no ongoing runtime health endpoint to monitor. What you monitor are the Kubernetes resources that KCL's output created.

Check the state of KCL-generated resources:

# Generate KCL configuration and preview it
kcl run main.k

# Apply with Kusion (if using KusionStack)
kusion apply -y

# Apply directly with kubectl
kcl run main.k | kubectl apply -f -

# Inspect deployed resources
kubectl get deployments,services,ingresses -n production -l "app.kubernetes.io/managed-by=kusion"

When using the kcl-operator with KCLRun CRs:

# Check KCLRun CR status
kubectl get kclrun -n production -o yaml | grep -A 20 "status:"

# Check kcl-operator controller pod health
kubectl get pods -n kcl-system -l app=kcl-operator

KCL's type system and schema validation catch configuration errors at compile time — but runtime monitoring catches what happens after the YAML is applied:

  1. A KCL schema default value that sets containerPort: 8080 while the application listens on 3000
  2. A KCL module update that changes a Service's type from LoadBalancer to ClusterIP
  3. A KCL constraint that allows replicas: 0 in non-production environments but was applied to production
  4. The kcl-operator failing to reconcile a KCLRun CR after a cluster upgrade

Step 2: Monitor the Primary Service Health Endpoint

The most reliable health signal for a KCL-managed service is an HTTP check against the application's health endpoint. This validates the complete path: KCL produced valid Kubernetes YAML, the Deployment reached its desired state, pods passed readiness checks, and the application is responding.

A KCL schema for a service with a health endpoint:

# main.k
import models.v1 as models

appName = "my-service"
namespace = "production"

# KCL schema for a web service
schema WebService:
    name: str
    namespace: str
    image: str
    port: int = 8080
    healthPath: str = "/healthz"
    replicas: int = 2

    check:
        replicas > 0, "replicas must be positive"
        port > 0 and port < 65536, "port must be a valid TCP port"

myService = WebService {
    name = appName
    namespace = namespace
    image = "my-org/my-service:v1.3.0"
    port = 8080
    replicas = 3
}

The compiled output produces a Deployment with a readiness probe at /healthz:8080. Add a Vigilmon monitor:

  1. Log in to VigilmonAdd Monitor → HTTP.
  2. URL: https://my-service.example.com/healthz.
  3. Check interval: 60 seconds.
  4. Response timeout: 10 seconds.
  5. Expected status: 200.
  6. Keyword: your health response value (e.g., ok, healthy).
  7. Label: my-service (KCL config).
  8. Click Save.

One monitor per KCL-rendered service exposed externally. When using KCL in a monorepo with multiple service definitions, add monitors for each service independently — a KCL schema constraint failure may affect only services inheriting a specific base schema.


Step 3: Monitor for Service Type and Port Changes

KCL's schema inheritance model makes it easy to change many services at once by updating a base schema — but a base schema change that alters a Service's type or port propagates to every inheriting service simultaneously.

# Base schema change that affects all inheriting services
schema BaseService:
    serviceType: str = "ClusterIP"  # Changed from "LoadBalancer" — breaks all external access
    port: int = 80

schema ProductionService(BaseService):
    # Inherits serviceType = "ClusterIP" after base schema change
    serviceType = "LoadBalancer"  # Must be overridden explicitly now

Monitor TCP connectivity to detect Service type and port changes:

# Check the Service type and external IP after a KCL schema update
kubectl get svc my-service -n production \
  -o jsonpath='{.spec.type} {.status.loadBalancer.ingress[0].ip}'
# Expected: LoadBalancer 203.0.113.45
# After bad schema update: ClusterIP <none>
  1. Add Monitor → TCP.
  2. Host: my-service.example.com.
  3. Port: 443.
  4. Check interval: 2 minutes.
  5. Label: my-service TCP (KCL schema).
  6. Click Save.

Schema inheritance and silent failures: A KCL base schema that changes a Service's targetPort default propagates to all inheriting schemas unless explicitly overridden. TCP-level monitoring catches this class of failure within 2 minutes of the schema update being applied — the TCP monitor fires because the cloud load balancer's target port no longer matches the Service backend.


Step 4: Monitor Ingress Resources from KCL Configurations

KCL configurations commonly define Ingress resources with parameterized hostnames, TLS settings, and annotation maps. When a KCL schema update changes the Ingress annotations map or the host field defaults, the Ingress controller silently applies the change — potentially removing TLS, changing the hostname, or altering routing behavior.

# KCL Ingress schema
schema IngressConfig:
    host: str
    tlsSecretName: str
    certIssuer: str = "letsencrypt-prod"
    servicePort: int = 80

    check:
        host != "", "Ingress host must not be empty"

myIngress = IngressConfig {
    host = "my-service.example.com"
    tlsSecretName = "my-service-tls"
    servicePort = 80
}

Monitor the Ingress-routed URL:

  1. Add Monitor → HTTP.
  2. URL: https://my-service.example.com.
  3. Check interval: 2 minutes.
  4. Response timeout: 15 seconds.
  5. Expected status: 200.
  6. Label: my-service Ingress (KCL config).
  7. Click Save.

Per-environment monitoring: KCL often uses different value files per environment (e.g., values.dev.k, values.prod.k) with different hostnames. Create separate Vigilmon monitors for each environment's hostnames, using monitor groups to organize them.


Step 5: Monitor SSL Certificates for KCL-Managed Ingresses

KCL configurations that include cert-manager annotations in their Ingress schema create a dependency on certificate auto-renewal. A KCL schema update that changes the annotation key (e.g., from cert-manager.io/cluster-issuer to cert-manager.io/issuer) causes cert-manager to stop managing the certificate — renewal silently stops.

# Find all Ingress hostnames from KCL-generated configurations
kubectl get ingress -A -l "app.kubernetes.io/managed-by=kusion" \
  -o jsonpath='{range .items[*]}{.spec.tls[*].hosts[*]}{"\n"}{end}'

For each hostname:

  1. Add Monitor → SSL Certificate.
  2. Domain: my-service.example.com.
  3. Alert when expiry is within: 30 days.
  4. Alert again: 14 days, 7 days, 3 days, 1 day.
  5. Click Save.

KCL constraint validation vs. cert-manager: KCL can enforce that every Ingress resource must have a cert-manager.io/cluster-issuer annotation — this prevents deployment of an Ingress without TLS. But KCL validation runs at compile time, not at certificate renewal time. A certificate issued 90 days ago by Let's Encrypt still needs renewal, regardless of KCL schema validity. Vigilmon's SSL monitor provides the runtime certificate health check that KCL's compile-time validation cannot.


Step 6: Monitor the kcl-operator

When using the kcl-operator to apply KCL configurations in-cluster via KCLRun CRs, a crashed or backlogged operator means configuration updates are not being reconciled. Resources in the cluster drift from their KCL-defined desired state without any alert:

# Check kcl-operator pod health
kubectl get pods -n kcl-system

# Check KCLRun CR reconciliation status
kubectl get kclrun -A -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,READY:.status.conditions[0].status'

# Describe a specific KCLRun CR to see events
kubectl describe kclrun my-app-config -n production

If the kcl-operator metrics endpoint is exposed externally:

  1. Add Monitor → HTTP.
  2. URL: https://kcl-operator-metrics.example.com/metrics.
  3. Check interval: 5 minutes.
  4. Expected status: 200.
  5. Label: kcl-operator metrics.
  6. Click Save.

Additionally, monitor the kcl-operator via TCP if it exposes a webhook:

  1. Add Monitor → TCP.
  2. Host: kcl-operator.kcl-system.svc (internal) or the webhook's external hostname.
  3. Port: 443.
  4. Check interval: 5 minutes.
  5. Label: kcl-operator webhook TCP.
  6. Click Save.

Step 7: Configure Alerting

In Vigilmon under Settings → Notifications, configure alert channels with a KCL-aware runbook:

| Monitor | Trigger | Immediate action | |---|---|---| | Service health endpoint | Non-200 or timeout | Check kubectl get pods -n production; run kcl run main.k --dry-run to verify schema | | TCP service port | Connection refused | Check kubectl get svc -n production; look for Service type change in last KCL commit | | Ingress HTTP | Non-200 or timeout | Check Ingress: kubectl describe ingress -n production; verify KCL schema did not change host | | SSL certificate | < 30 days | Check cert-manager: kubectl get certificates -n production; verify KCL Ingress annotation | | kcl-operator metrics | Non-200 | Check operator pod: kubectl logs -n kcl-system -l app=kcl-operator; check KCLRun CR status |

Alert grouping: Organize monitors by KCL module or service (e.g., a payment-service-kcl group). When all monitors in a group fire simultaneously after a KCL schema update, the schema change is the probable cause — roll back the last KCL commit and reapply.


Common KCL Configuration Failure Modes and What Vigilmon Catches

| Scenario | Vigilmon signal | |---|---| | KCL base schema changes Service type to ClusterIP | TCP monitor fires; HTTP monitor returns connection refused | | KCL schema default containerPort changed, mismatches application | HTTP health endpoint fails; pods show as running | | KCL schema update removes cert-manager annotation from Ingress | SSL monitor fires at 30-day threshold; HTTP fails on expiry | | kcl-operator KCLRun CR reconciliation failure | HTTP monitors detect stale/drifted resource behavior | | KCL constraint allows replicas: 0 applied to production | HTTP monitor times out; no pods running | | KCL module update changes Ingress host field | HTTP monitor fires for old hostname; new hostname not yet in DNS | | KCL compilation succeeds but wrong environment values applied | HTTP monitor fires for unexpected hostname or broken config | | kcl-operator crashes during rolling update | KCLRun CRs not reconciling; resource drift accumulates silently | | KCL schema changes targetPort but not port | TCP passes; HTTP returns connection refused from pod | | Image tag pinned in KCL schema updated to broken version | Health endpoint fails after rollout |


KCL's type system and schema constraints give you confidence at configuration authoring time — but the gap between "KCL compiled successfully" and "your services are actually serving users" is where Vigilmon operates. External monitoring catches the runtime failures that schema validation cannot: a default value that mismatches the application's listening port, a Service type change that removes the external LoadBalancer IP, an expired SSL certificate that cert-manager failed to renew, or an kcl-operator reconciliation failure that lets cluster resources drift from their KCL-defined desired state. Vigilmon gives your KCL-managed Kubernetes deployments the runtime health visibility that complements KCL's compile-time safety guarantees.

Start monitoring your KCL Kubernetes deployments in under 5 minutes — register free at vigilmon.online.

Monitor your app with Vigilmon

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

Start free →