OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Deployment

Observability

Metrics, logs and the audit trail of every OpenKeel service in Grafana: an optional stack installed by okadm --grafana, the equivalent of Kolla's Prometheus, Grafana and central logging.

The observability stack

  1. 01

    OpenKeel services

    JSON logs and CADF audit events on stdout; /healthz, /readyz and /metrics on the admin port :9090

  2. 02

    Collection

    Prometheus Operator monitors scrape the services and data services; Alloy, a DaemonSet, reads every Pod log of its node

  3. 03

    Storage

    Prometheus for metrics; Loki for logs, with an app stream and an audit stream kept apart

  4. 04

    Grafana and alerts

    OpenKeel dashboards in their own folder; PrometheusRule alerts sent through Alertmanager

What each service emits

Every Go module is built from the same template, so all of them emit the same signals in the same format.

Structured JSON logs

  • log/slog JSON on stdout, in English: time (UTC), level, service, pod, msg
  • request_id and global_request_id, carried to every outgoing call and message, plus the user and project ids of the token
  • Values of keys such as password, secret, token or key are masked at any depth; request bodies are never logged
  • Log level changed at run time with SIGHUP, without a restart

CADF audit trail

  • One CADF event per API call, in the pycadf format of keystonemiddleware, checked field by field against it
  • 401 and 403 calls are audited too; Keystone adds its identity events (authentication, tokens, role assignments)
  • Never records bodies, tokens or secret query values
  • Never blocks a request: a full queue drops the event and counts it, and an alert fires

Probes and metrics

  • Admin port :9090, not exposed outside the cluster: /healthz (process alive), /readyz (database and other checks), /metrics
  • /metrics serves the audit counters, on the API Pods: events sent, dropped and failed per sink
  • Memory and CPU of each Pod come from cAdvisor, in the kubelet; restarts from kube-state-metrics

Not there yet: request rates and latencies, database, cache and message counters, Go process metrics and OpenTelemetry traces are part of the module template's design, but the services do not export them today.

Components and sizing

Everything goes in the openkeel-monitoring namespace. The chart versions are pinned in okadm's release manifest and built into the binary.

ReleaseChartWhatLabProduction
kube-prometheus-stack92.10.1 (Prometheus Operator v0.94.1)Prometheus Operator and its CRDs, Prometheus, Alertmanager, Grafana, kube-state-metrics, node-exporter, the Kubernetes dashboards and alerts1 replica of each; Prometheus keeps 2 days, without a volumePrometheus ×2 (15 days, 50 Gi), Alertmanager ×3, Grafana with a 10 Gi volume, on the block StorageClass
loki7.3.0 (Loki 3.6.12)Log store, queried by Grafana with LogQLSingle binary, 5 Gi volumeSimple scalable: 3 write, 3 read, 3 backend, gateway ×2; chunks and index in S3
alloy1.13.1 (Alloy v1.20.1)DaemonSet: every container log of its node to Loki, audit lines split out1 Pod per node1 Pod per node

What is collected

The umbrella chart adds these objects to the openkeel-infra release when monitoring is on.

ObjectCollects
PodMonitor openkeel-servicesThe admin port of every OpenKeel Pod (APIs, workers, agents), labelled by service and component
MariaDB metricsmysqld-exporter and its ServiceMonitor, added by the MariaDB operator: Galera cluster size, connections, queries, slow queries
ServiceMonitor openkeel-rabbitmqThe rabbitmq_prometheus plugin, including per-queue metrics: messages ready, consumers, alarms
ServiceMonitors openkeel-kubevirt, openkeel-longhornKubeVirt and Longhorn, when okadm plan finds them in the cluster
ConfigMaps openkeel-dashboard-*The OpenKeel dashboards, loaded by Grafana's sidecar into the OpenKeel folder

The Kustomize lab (openkeel-lab) runs its own data services, without exporters: its Data services dashboard stays empty, while okadm install --mode lab --grafana gets them all.

Logs in Loki: two streams

Alloy routes each line by its top-level log_type field, so the audit trail is kept apart from the application logs, with its own retention.

StreamLinesLabProduction
{stream="audit"}CADF audit events ("log_type": "audit")30 days400 days
{stream="app"}Every other container line, OpenKeel or not7 days31 days

Retention is enforced by Loki's compactor and can be changed in the okadm values file. Each line carries the labels namespace, pod, container, node, service and component.

Dashboards

DashboardData sourceShows
OpenKeel / Audit trailLokiEvents, failures, 401, 403, failed Keystone authentications and deletes; failures by user and source IP; deletes and updates by user and resource type; the raw events. Filters: service, outcome, user, source IP
OpenKeel / ServicesPrometheus, LokiScrape targets per service, audit counters, memory and CPU of each Pod (cAdvisor), log volume by level, errors by service, and a searchable log panel
OpenKeel / Data servicesPrometheusMariaDB Galera and RabbitMQ (queues backing up or without consumers, alarms)
Kubernetes / …PrometheusThose of kube-prometheus-stack: cluster, nodes, namespaces, Pods, workloads

Searching the audit trail

In Grafana, Explore, data source Loki: the CADF fields are extracted with LogQL. Here, the failed Keystone authentications.

{stream="audit", service="openkeel-keystone"}
  | json outcome="payload.outcome",
         initiator="payload.initiator.id",
         ip="payload.initiator.host.address",
         event_type="event_type"
  | event_type="identity.authenticate"
  | outcome="failure"

Alerts

Shipped as the PrometheusRule openkeel, on top of the Kubernetes alerts of kube-prometheus-stack.

AlertSeverityFires when
OpenKeelAuditEventsDroppedcriticalA service's audit queue was full: the trail has a gap
OpenKeelAuditEventsFailedwarningAn audit sink failed, for example RabbitMQ unreachable
OpenKeelServiceTargetDownA service's metrics endpoint cannot be scraped
OpenKeelServiceNoTargetA service has no scrape target at all

Alertmanager sends nowhere by default: set its receivers in the okadm values file.

Enabling it

Nothing is installed without the flag. okadm installs the stack right after Multus, before openkeel-infra: namespace, a random Grafana admin password, then kube-prometheus-stack, Loki and Alloy, each waited for. It remembers the flag: later installs and upgrades keep the stack up to date. Install, upgrade and access print Grafana's URL and the command that reads the password.

okadm install --mode lab --grafana            # kind lab
okadm install --mode lab --grafana --ingress  # Grafana at grafana.127.0.0.1.nip.io
okadm install --grafana --domain cloud.example.org
# or, with the Kustomize lab
GRAFANA=1 make lab-up

In production

TopicWhat to do
Loki object storageCreate the Secret openkeel-loki-s3 (endpoint, region, keys) and the buckets openkeel-loki-chunks and openkeel-loki-ruler before the install; okadm plan blocks without it. The Ceph RGW of okadm --ceph-s3 works too
Alert routingSet Alertmanager's receivers
Control-plane targetsOn Talos, expose the metrics of etcd, the scheduler and the controller manager, or turn those targets off
Existing Prometheus Operatorokadm plan warns about it. To keep it, install without --grafana, turn on the OpenKeel monitors and let that Prometheus select them
Grafana accessIngress at grafana.<domain>, otherwise a port-forward; the admin password is random, in the Secret openkeel-grafana-admin
ValuesOne observability.<release> section per release in the same -f file as the rest of OpenKeel

Audit trail: what the platform must add

The services produce the trail; keeping it complete, intact, on time and readable for the required period is the platform's job.

DutyPCI-DSS v4.0ISO/IEC 27001:2022How
Ship the events off the node as they are written10.3.3A.8.15Alloy (or Fluent Bit, Vector, the OpenTelemetry Collector) with a disk buffer
Tamper-evident, write-once retention10.3.2, 10.3.3A.8.15A copy in object storage with object lock in compliance mode; Loki alone is not enough
12 months, the last 3 immediately available10.5.1A.5.33, A.8.15Locked bucket of 400 days; Loki keeps the audit stream 400 days in production
Restricted read access10.3.1A.8.15, A.5.15Bucket policy, a Loki tenant or Grafana team for the audit stream
Synchronised clocks10.6.1 to 10.6.3A.8.17NTP on the nodes; node-exporter alerts on drift
Detect gaps10.7.1, 10.7.2A.8.15, A.8.16The audit alerts above, and the collector's own counters
Daily review10.4.1A.8.16A SIEM fed from the bucket or the collector; the Grafana dashboard

Loki gives a searchable audit trail, not a tamper-proof archive: whoever administers the cluster can write to its storage.

Optional: openstack-exporter

The exporter Kolla uses

monitoring.openstackExporter.enabled: true deploys openstack-exporter 1.7.0. Every 2 minutes it lists the resources of each API (servers, networks, volumes, images, Placement, agents), so the community OpenStack dashboards work as they are.

Off by default, on with CloudKitty

  • It calls every API with an admin token, so its load grows with the cloud
  • It writes CADF audit events of its own
  • It repeats what the services' own signals and the audit trail already show
  • okadm turns it on when CloudKitty is installed: CloudKitty's metric file rates its openstack_* series

What else reads Prometheus

The Prometheus of the stack is also a data source for OpenKeel itself: okadm points these services at it when --grafana is on.

ReaderWhat it readsFor
CloudKitty (collector)openstack-exporter series per project (tenant_id): instances, volume capacity, image sizeHourly rating, the FinOps / GreenOps page of Skyline
openkeel-skyline (GET /extension/server_metrics)KubeVirt kubevirt_vmi_* series of the project's namespace, VMs selected by the label openkeel.io/project-idThe Metrics page: CPU, memory (balloon driver), disk usage (QEMU guest agent) and disk I/O of the VMs
openkeel-skyline (Prometheus queries)The queries of the console's monitoring pagesAdministrator views of upstream Skyline

See FinOps / GreenOps and CloudKitty and the Skyline additions.