diff --git a/documentation/web/docs/user/grafana-dashboards.md b/documentation/web/docs/user/grafana-dashboards.md index 4a02de38..c7536216 100644 --- a/documentation/web/docs/user/grafana-dashboards.md +++ b/documentation/web/docs/user/grafana-dashboards.md @@ -100,7 +100,7 @@ When you route metrics through an OpenTelemetry Collector, enable `resource_to_telemetry_conversion` on the Prometheus exporter so that resource attributes such as the pod and namespace become Prometheus labels. The sample collector under -`operator/config/samples/opentelemetry/otel_collector.yaml` already does +`operator/config/samples/opentelemetry/base/otel_collector.yaml` already does this. ::: @@ -138,7 +138,7 @@ helm upgrade --install \ Ensure Prometheus scrapes Klio's metrics by deploying a `ServiceMonitor` (or a `PodMonitor`, if the collector's `Service` has no labels) for the OpenTelemetry collector's Prometheus exporter — see -`operator/config/samples/opentelemetry/otel_collector_svc_monitor.yaml`. +`operator/config/samples/opentelemetry/base/otel_collector_svc_monitor.yaml`. Port-forward Grafana and log in with `admin` / `prom-operator`: diff --git a/observability/grafana/README.md b/observability/grafana/README.md index c7a1efab..6263232c 100644 --- a/observability/grafana/README.md +++ b/observability/grafana/README.md @@ -91,7 +91,7 @@ helm upgrade --install \ Make Prometheus scrape Klio's metrics by deploying a `ServiceMonitor` — or a `PodMonitor` if the collector's `Service` has no labels — for the OTel collector (see -[`operator/config/samples/opentelemetry/otel_collector_svc_monitor.yaml`](../../operator/config/samples/opentelemetry/otel_collector_svc_monitor.yaml) +[`operator/config/samples/opentelemetry/base/otel_collector_svc_monitor.yaml`](../../operator/config/samples/opentelemetry/base/otel_collector_svc_monitor.yaml) and the [OpenTelemetry guide](../../documentation/web/docs/user/opentelemetry.md)). Port-forward Grafana (log in with `admin` / `prom-operator`): diff --git a/operator/config/samples/opentelemetry/README.md b/operator/config/samples/opentelemetry/README.md index 14fb8cdb..6a19b7ab 100644 --- a/operator/config/samples/opentelemetry/README.md +++ b/operator/config/samples/opentelemetry/README.md @@ -1,7 +1,45 @@ # README -This directory contains sample configurations for the a klio server and a -CNPG cluster with OpenTelemetry enabled. +This directory contains two sample environments exercising Klio's +OpenTelemetry integration, both sharing the OTel collector / Jaeger / +Prometheus stack defined in `base/`. Every CNPG cluster also gets its own +`PodMonitor` (see `single/cluster/cluster_pod_monitor.yaml`), so Prometheus +scrapes CloudNativePG's own `cnpg_pg_stat_replication_*` metrics in +addition to what the OTel collector exports — the Grafana dashboard's WAL +Replication Lag row needs this (see +`documentation/web/docs/user/grafana-dashboards.md`): + +- [`single/`](single): one Klio server and one CNPG cluster. Start here if + you just want to see OpenTelemetry wired up. +- [`multi/`](multi): two Klio servers and four CNPG clusters distributed + across them, one of which lives in a different namespace than the + servers. It reuses `single/`'s Server and Cluster/PluginConfiguration + definitions (see `multi/team-a`) rather than duplicating them, and exists + to validate the Grafana dashboard's `$namespace`, `$server` and `$cluster` + template variables and its per-tier/per-cluster aggregations against more + than one server, cluster or namespace — something `single/` can't + exercise. + +## Topology + +`multi/`'s four clusters: + +| Cluster | Namespace | Backed by | +|-------------|-----------|-----------| +| cluster-a | default | klio-a | +| cluster-b | default | klio-b | +| cluster-c | team-c | klio-b | +| cluster-d | team-d | klio-a (independent server also named "klio-a") | + +`klio-b` intentionally backs clusters in two different namespaces, since a +single shared backup server serving multiple application namespaces is a +realistic multi-tenant deployment and the case most likely to expose +dashboard attribution bugs. `cluster-d` is backed by a *second*, independent +Klio server that happens to also be named "klio-a" (see `multi/team-d`): +since a Server's StatefulSet pod name is derived from the Server's own name +alone, both servers' pods are named "klio-a-klio-0", giving them an +identical host_name label — a case the dashboard's `$server` variable +cannot disambiguate on its own. ## Prerequisites @@ -13,6 +51,19 @@ A running Kubernetes cluster with the following operators installed: - OpenTelemetry - Prometheus +`jq` must also be available locally (used by `multi/copy-cross-namespace-secrets.sh` +and `multi/bootstrap-remote-server.sh`). + +All of `multi`'s client certificates (cluster-a's through cluster-d's) are +issued through a `ClusterIssuer`, which always resolves its backing CA +secret in cert-manager's `--cluster-resource-namespace`, regardless of +which namespace the requesting `Certificate` lives in: this is a single, +fixed lookup location for the whole cert-manager installation, not a +per-request one, so it affects cluster-a's and cluster-b's certificates +(both in `default`) exactly as much as cluster-c's and cluster-d's. This +sample assumes that namespace is `default` (where `base/klio_server_ca.yaml` +is deployed); see the next section for the command that configures it. + ## Deploying a Kubernetes cluster with the required operators Assuming an environment with CloudNativePG, Klio and cert-manager @@ -23,6 +74,16 @@ the klio task KIND_CLUSTER_NAME=$(kind get clusters | grep pg-operator-e2e) task integration:deploy-to-kind ``` +That task's cert-manager install does not set `--cluster-resource-namespace`, +so it defaults to the `cert-manager` namespace, not `default`. Reconfigure +it, or every client certificate in this sample fails to issue: + +```shell +helm upgrade cert-manager jetstack/cert-manager \ + --namespace cert-manager --reuse-values \ + --set clusterResourceNamespace=default +``` + you can install the OpenTelemetry operator by running: ```shell @@ -42,8 +103,90 @@ helm upgrade --install \ prometheus-community prometheus-community/kube-prometheus-stack ``` -## Deploying the sample configuration +## Deploying the "single" sample ```shell -kubectl apply -k operator/config/samples/opentelemetry +kubectl apply -k operator/config/samples/opentelemetry/single ``` + +Wait for `klio` and `cluster-example` to become ready, then trigger a base +backup so the Grafana dashboard has backup/snapshot data to show: + +```shell +kubectl apply -f operator/config/samples/opentelemetry/single/backups-example.yaml +``` + +## Deploying the "multi" sample + +1. Deploy the two servers, the two same-namespace clusters (cluster-a, + cluster-b) and the shared OTel/Jaeger stack, all in `default`: + + ```shell + kubectl apply -k operator/config/samples/opentelemetry/multi + ``` + + Wait for `klio-a`, `klio-b`, `cluster-a` and `cluster-b` to become ready + before continuing. + +1. cluster-c's own client certificate is requested directly in `team-c` + through the cluster-scoped `klio-server-ca` `ClusterIssuer`, so it needs + no copying. klio-b's server certificate and the OTel collector's + certificate are pinned by exact bytes rather than CA-validated (see the + script's comments), so those still have to be copied from `default` + into the `team-c` namespace: + + ```shell + ./operator/config/samples/opentelemetry/multi/copy-cross-namespace-secrets.sh + ``` + +1. Deploy cluster-c into `team-c`: + + ```shell + kubectl apply -k operator/config/samples/opentelemetry/multi/team-c + ``` + +1. cluster-d's own client certificate is likewise requested directly in + `team-d` through the `klio-server-ca` `ClusterIssuer`. `team-d`'s server + (its own "klio-a") is independently self-signed rather than a copy of + `default`'s CA-issued certificate, but it still needs to validate + clients signed by the shared `klio-server-ca` and to export telemetry to + the shared collector. Copy the CA's public certificate and the OTel + collector's trust anchor into the `team-d` namespace: + + ```shell + ./operator/config/samples/opentelemetry/multi/bootstrap-remote-server.sh team-d + ``` + +1. Deploy cluster-d (and its own klio-a server) into `team-d`: + + ```shell + kubectl apply -k operator/config/samples/opentelemetry/multi/team-d + ``` + +## Validating the Grafana dashboard with the "multi" sample + +Trigger one base backup per cluster (needed before any backup/snapshot panel +has data to show): + +```shell +kubectl apply -f operator/config/samples/opentelemetry/multi/backups-example.yaml +``` + +Once all backups complete and Prometheus has scraped a metrics-collection +cycle, open the Klio Grafana dashboard and confirm: + +- The `$namespace` variable offers `default`, `team-c` and `team-d`. +- The `$server` variable offers `klio-a-klio-0` (twice, once per namespace) + and `klio-b-klio-0` (the value is each server's pod hostname). +- The `$cluster` variable offers `cluster-a`, `cluster-b`, `cluster-c` and + `cluster-d`, and narrows correctly when `$namespace`/`$server` are + filtered (e.g. selecting `$namespace=team-c` should only ever offer + `cluster-c`). +- Per-cluster and per-server panels correctly attribute data instead of + aggregating everything together, and in particular that the two + same-named `klio-a` servers (in `default` and in `team-d`) are not + conflated. + +Any panel that fails to distinguish between clusters/servers/namespaces +here is a dashboard bug to file separately; this sample's job is only to +make that determination possible. diff --git a/operator/config/samples/opentelemetry/cluster_klio_otel_config.yaml b/operator/config/samples/opentelemetry/base/cluster_klio_otel_config.yaml similarity index 100% rename from operator/config/samples/opentelemetry/cluster_klio_otel_config.yaml rename to operator/config/samples/opentelemetry/base/cluster_klio_otel_config.yaml diff --git a/operator/config/samples/opentelemetry/issuer.yaml b/operator/config/samples/opentelemetry/base/issuer.yaml similarity index 100% rename from operator/config/samples/opentelemetry/issuer.yaml rename to operator/config/samples/opentelemetry/base/issuer.yaml diff --git a/operator/config/samples/opentelemetry/jaeger.yaml b/operator/config/samples/opentelemetry/base/jaeger.yaml similarity index 100% rename from operator/config/samples/opentelemetry/jaeger.yaml rename to operator/config/samples/opentelemetry/base/jaeger.yaml diff --git a/operator/config/samples/opentelemetry/base/klio_encryption.yaml b/operator/config/samples/opentelemetry/base/klio_encryption.yaml new file mode 100644 index 00000000..a60d4b7e --- /dev/null +++ b/operator/config/samples/opentelemetry/base/klio_encryption.yaml @@ -0,0 +1,18 @@ +# Shared encryption identity for every Klio server in these samples. +# Reusing the same identity across servers is fine for this demo; production +# deployments would normally give each server its own. +apiVersion: v1 +stringData: + secret-key: AGE-SECRET-KEY-1P7TWJ8H837DPVLSRVHAP0ZCZVHXJRTUS7S0A5VZAR49URW0Z9Q0SFW4HVM + public-key: age16y2zu5qptkzateyuarcahs0am75qjpu0xd2ty2dvm5jusnfzxg0scjh5uu + encryption-key: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyMzJERW1QTUhjNGdlNmdi + WmFLZ3FLL1lZclduUWEvZkJncGdJZmtVd1FzCmZwSHVTcWNMRFN6a2xpY0NHNVRv + MlltSlNRY1B4bmNoOUxuZzZ5RENSSmsKLS0tIGNYUUNzSGVqNUZhS3VodnZ1cXNP + T3JHS3JRSUNkR1RyeEROYnZYNnNSV00KUd3HyxvvqCyW6hC1sWNDn/xeptHsoz/e + hxCgWoSJvfSfNk174njMwEeW+ic= + -----END AGE ENCRYPTED FILE----- +kind: Secret +metadata: + name: klio-encryption diff --git a/operator/config/samples/opentelemetry/base/klio_server_ca.yaml b/operator/config/samples/opentelemetry/base/klio_server_ca.yaml new file mode 100644 index 00000000..43cc936e --- /dev/null +++ b/operator/config/samples/opentelemetry/base/klio_server_ca.yaml @@ -0,0 +1,31 @@ +# Root CA shared by every Klio server in these samples, and by every +# client-auth certificate issued through the klio-server-ca ClusterIssuer +# (see ../base/klio_server_ca_issuer.yaml), including cluster-c's and +# cluster-d's — requested directly in their own namespaces (see +# ../multi/team-c, ../multi/team-d) rather than generated in "default" and +# copied cross-namespace. Sharing a single CA lets any client certificate it +# signs be trusted by any server's caSecretName. +# +# The resulting secret must live in cert-manager's +# --cluster-resource-namespace (see the README's Prerequisites section) for +# the ClusterIssuer to find it — this sample assumes that's "default", +# where ../base (and therefore this Certificate) is deployed. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: klio-server-ca +spec: + commonName: klio-server + secretName: klio-server-ca + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: true + usages: + - cert sign + + issuerRef: + name: selfsigned-issuer + kind: Issuer + group: cert-manager.io diff --git a/operator/config/samples/opentelemetry/base/klio_server_ca_issuer.yaml b/operator/config/samples/opentelemetry/base/klio_server_ca_issuer.yaml new file mode 100644 index 00000000..1dd72613 --- /dev/null +++ b/operator/config/samples/opentelemetry/base/klio_server_ca_issuer.yaml @@ -0,0 +1,16 @@ +# A ClusterIssuer (not a namespace-scoped Issuer) so client-auth +# certificates can be requested directly in whatever namespace their +# cluster lives in (see ../multi/team-c, ../multi/team-d) instead of being +# generated in "default" and copied cross-namespace. +# +# cert-manager looks up a ClusterIssuer's `ca.secretName` in its configured +# --cluster-resource-namespace (see the README's Prerequisites section), +# which must therefore be set to "default" for this to resolve to the +# klio-server-ca secret created by ../base/klio_server_ca.yaml. +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: klio-server-ca +spec: + ca: + secretName: klio-server-ca diff --git a/operator/config/samples/opentelemetry/klio_server_otel_client_certificate.yaml b/operator/config/samples/opentelemetry/base/klio_server_otel_client_certificate.yaml similarity index 100% rename from operator/config/samples/opentelemetry/klio_server_otel_client_certificate.yaml rename to operator/config/samples/opentelemetry/base/klio_server_otel_client_certificate.yaml diff --git a/operator/config/samples/opentelemetry/klio_server_otel_config.yaml b/operator/config/samples/opentelemetry/base/klio_server_otel_config.yaml similarity index 100% rename from operator/config/samples/opentelemetry/klio_server_otel_config.yaml rename to operator/config/samples/opentelemetry/base/klio_server_otel_config.yaml diff --git a/operator/config/samples/opentelemetry/kustomization.yaml b/operator/config/samples/opentelemetry/base/kustomization.yaml similarity index 62% rename from operator/config/samples/opentelemetry/kustomization.yaml rename to operator/config/samples/opentelemetry/base/kustomization.yaml index fe7c2feb..b4817b7e 100644 --- a/operator/config/samples/opentelemetry/kustomization.yaml +++ b/operator/config/samples/opentelemetry/base/kustomization.yaml @@ -1,16 +1,17 @@ +# Shared infrastructure for both the "single" and "multi" OpenTelemetry +# samples: the OTel collector, Jaeger, the self-signed CA/issuer chain, the +# shared encryption identity, and the default-namespace OTel ConfigMaps used +# by the Klio server(s) and cluster(s) that live in "default". +# # REQUIRES: # kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml resources: - cluster_klio_otel_config.yaml - - cluster.yaml - - cluster_klio_client_auth.yaml - issuer.yaml - jaeger.yaml - klio_encryption.yaml - - klio_server.yaml - klio_server_ca.yaml - klio_server_ca_issuer.yaml - - klio_server_certificate.yaml - klio_server_otel_client_certificate.yaml - klio_server_otel_config.yaml - otel_collector.yaml @@ -18,5 +19,4 @@ resources: - otel_collector_clusterrole.yaml - otel_collector_clusterrolebinding.yaml - otel_collector_sa.yaml - - otel_collector_svc_monitor.yaml - - plugin_configuration.yaml + - otel_collector_svc_monitor.yaml \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/otel_collector.yaml b/operator/config/samples/opentelemetry/base/otel_collector.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector.yaml rename to operator/config/samples/opentelemetry/base/otel_collector.yaml diff --git a/operator/config/samples/opentelemetry/otel_collector_certificate.yaml b/operator/config/samples/opentelemetry/base/otel_collector_certificate.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector_certificate.yaml rename to operator/config/samples/opentelemetry/base/otel_collector_certificate.yaml diff --git a/operator/config/samples/opentelemetry/otel_collector_clusterrole.yaml b/operator/config/samples/opentelemetry/base/otel_collector_clusterrole.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector_clusterrole.yaml rename to operator/config/samples/opentelemetry/base/otel_collector_clusterrole.yaml diff --git a/operator/config/samples/opentelemetry/otel_collector_clusterrolebinding.yaml b/operator/config/samples/opentelemetry/base/otel_collector_clusterrolebinding.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector_clusterrolebinding.yaml rename to operator/config/samples/opentelemetry/base/otel_collector_clusterrolebinding.yaml diff --git a/operator/config/samples/opentelemetry/otel_collector_sa.yaml b/operator/config/samples/opentelemetry/base/otel_collector_sa.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector_sa.yaml rename to operator/config/samples/opentelemetry/base/otel_collector_sa.yaml diff --git a/operator/config/samples/opentelemetry/otel_collector_svc_monitor.yaml b/operator/config/samples/opentelemetry/base/otel_collector_svc_monitor.yaml similarity index 100% rename from operator/config/samples/opentelemetry/otel_collector_svc_monitor.yaml rename to operator/config/samples/opentelemetry/base/otel_collector_svc_monitor.yaml diff --git a/operator/config/samples/opentelemetry/klio_server_ca.yaml b/operator/config/samples/opentelemetry/klio_server_ca.yaml deleted file mode 100644 index f8d1eb3c..00000000 --- a/operator/config/samples/opentelemetry/klio_server_ca.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: klio-server-ca -spec: - commonName: klio-server - secretName: klio-server-ca - - duration: 2160h # 90d - renewBefore: 360h # 15d - - isCA: true - usages: - - cert sign - - issuerRef: - name: selfsigned-issuer - kind: Issuer - group: cert-manager.io diff --git a/operator/config/samples/opentelemetry/klio_server_ca_issuer.yaml b/operator/config/samples/opentelemetry/klio_server_ca_issuer.yaml deleted file mode 100644 index 0c06112f..00000000 --- a/operator/config/samples/opentelemetry/klio_server_ca_issuer.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: klio-server-ca -spec: - ca: - secretName: klio-server-ca diff --git a/operator/config/samples/opentelemetry/multi/backups-example.yaml b/operator/config/samples/opentelemetry/multi/backups-example.yaml new file mode 100644 index 00000000..acc58e71 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/backups-example.yaml @@ -0,0 +1,57 @@ +# Triggers one base backup on each of the four clusters, so the Grafana +# dashboard has backup/snapshot data to show for all four (namespace, +# server, cluster) combinations. Apply after cluster-a, cluster-b, +# cluster-c and cluster-d are all healthy: +# +# kubectl apply -f operator/config/samples/opentelemetry/multi/backups-example.yaml +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: cluster-a-backup-1 + namespace: default +spec: + method: plugin + target: primary + cluster: + name: cluster-a + pluginConfiguration: + name: klio.cnpg.io +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: cluster-b-backup-1 + namespace: default +spec: + method: plugin + target: primary + cluster: + name: cluster-b + pluginConfiguration: + name: klio.cnpg.io +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: cluster-c-backup-1 + namespace: team-c +spec: + method: plugin + target: primary + cluster: + name: cluster-c + pluginConfiguration: + name: klio.cnpg.io +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: cluster-d-backup-1 + namespace: team-d +spec: + method: plugin + target: primary + cluster: + name: cluster-d + pluginConfiguration: + name: klio.cnpg.io diff --git a/operator/config/samples/opentelemetry/multi/bootstrap-remote-server.sh b/operator/config/samples/opentelemetry/multi/bootstrap-remote-server.sh new file mode 100755 index 00000000..18046d89 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/bootstrap-remote-server.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Bootstraps a namespace that runs its OWN local Klio server (self-signed, +# not copied from "default") which nonetheless needs to: (a) validate client +# certs signed by the shared klio-server-ca, and (b) export OTel data to the +# shared collector in "default". This copies the CA's public cert so any +# locally-issued server certificate can validate against it, plus the shared +# OTel collector/client certs — all three are pinned by exact bytes rather +# than validated through a CA (see +# core/internal/client/klioclient/grpcclient/connection.go), so there is no +# ClusterIssuer shortcut for them. The destination namespace's own client +# certificate (e.g. cluster_d_klio_client_auth.yaml) needs no such copy: it +# is requested directly there via the cluster-scoped klio-server-ca +# ClusterIssuer. +# +# Usage: bootstrap-remote-server.sh +# +# Run this after `kubectl apply -k .` and before applying the destination +# namespace's kustomization, e.g.: +# ./bootstrap-remote-server.sh team-d +set -euo pipefail + +if [ $# -ne 1 ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +SOURCE_NS=default +DEST_NS="$1" + +echo "Waiting for cert-manager to issue the secrets in ${SOURCE_NS}..." +kubectl wait --for=create secret/klio-server-ca -n "${SOURCE_NS}" --timeout=120s +kubectl wait --for=create secret/otel-collector-tls -n "${SOURCE_NS}" --timeout=120s +kubectl wait --for=create secret/klio-server-otel-client-tls -n "${SOURCE_NS}" --timeout=120s + +kubectl create namespace "${DEST_NS}" --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying the shared CA's public certificate (so a locally-issued server cert can validate clients signed by it)..." +kubectl get secret klio-server-ca -n "${SOURCE_NS}" -o jsonpath='{.data.tls\.crt}' | base64 -d | + kubectl create secret generic klio-server-ca -n "${DEST_NS}" --from-file=tls.crt=/dev/stdin \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying the OTel collector's certificate (public cert only, used as the trust anchor)..." +kubectl get secret otel-collector-tls -n "${SOURCE_NS}" -o jsonpath='{.data.ca\.crt}' | base64 -d | + kubectl create secret generic otel-collector-ca -n "${DEST_NS}" --from-file=ca.crt=/dev/stdin \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying the shared OTel client certificate (full secret; not verified by the collector)..." +kubectl get secret klio-server-otel-client-tls -n "${SOURCE_NS}" -o json | + jq 'del(.metadata.namespace,.metadata.resourceVersion,.metadata.uid,.metadata.creationTimestamp,.metadata.ownerReferences,.metadata.annotations)' | + kubectl apply -n "${DEST_NS}" -f - + +echo "Done. You can now apply ${DEST_NS}'s kustomization." \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/cluster_a_klio_client_auth.yaml b/operator/config/samples/opentelemetry/multi/cluster_a_klio_client_auth.yaml new file mode 100644 index 00000000..ea8c9c58 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/cluster_a_klio_client_auth.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cluster-a-klio-user +spec: + commonName: klio@cluster-a + secretName: cluster-a-klio-user + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: false + usages: + - client auth + + issuerRef: + name: klio-server-ca + kind: ClusterIssuer + group: cert-manager.io diff --git a/operator/config/samples/opentelemetry/multi/cluster_b_klio_client_auth.yaml b/operator/config/samples/opentelemetry/multi/cluster_b_klio_client_auth.yaml new file mode 100644 index 00000000..7d8906dc --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/cluster_b_klio_client_auth.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cluster-b-klio-user +spec: + commonName: klio@cluster-b + secretName: cluster-b-klio-user + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: false + usages: + - client auth + + issuerRef: + name: klio-server-ca + kind: ClusterIssuer + group: cert-manager.io diff --git a/operator/config/samples/opentelemetry/multi/copy-cross-namespace-secrets.sh b/operator/config/samples/opentelemetry/multi/copy-cross-namespace-secrets.sh new file mode 100755 index 00000000..447ef020 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/copy-cross-namespace-secrets.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Copies the secrets cluster-c (namespace "team-c") needs from klio-b and the +# shared OTel collector, both of which live in "default". klio-b's server +# certificate and the OTel collector's certificate are pinned by exact bytes +# rather than validated through a CA (see +# core/internal/client/klioclient/grpcclient/connection.go), so only their +# public half needs copying — there is no ClusterIssuer shortcut for these, +# unlike cluster-c's own client certificate (see +# cluster_c_klio_client_auth.yaml), which is requested directly in "team-c" +# via the cluster-scoped klio-server-ca ClusterIssuer and needs no copy. +# +# Run this after `kubectl apply -k .` and before `kubectl apply -k team-c`. +set -euo pipefail + +SOURCE_NS=default +DEST_NS=team-c + +echo "Waiting for cert-manager to issue the secrets in ${SOURCE_NS}..." +kubectl wait --for=create secret/klio-b-tls -n "${SOURCE_NS}" --timeout=120s +kubectl wait --for=create secret/otel-collector-tls -n "${SOURCE_NS}" --timeout=120s +kubectl wait --for=create secret/klio-server-otel-client-tls -n "${SOURCE_NS}" --timeout=120s + +kubectl create namespace "${DEST_NS}" --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying klio-b's server certificate (public cert only, pinned by the client)..." +kubectl get secret klio-b-tls -n "${SOURCE_NS}" -o jsonpath='{.data.tls\.crt}' | base64 -d | + kubectl create secret generic klio-b-tls -n "${DEST_NS}" --from-file=tls.crt=/dev/stdin \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying the OTel collector's certificate (public cert only, used as the trust anchor)..." +kubectl get secret otel-collector-tls -n "${SOURCE_NS}" -o jsonpath='{.data.ca\.crt}' | base64 -d | + kubectl create secret generic otel-collector-ca -n "${DEST_NS}" --from-file=ca.crt=/dev/stdin \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Copying the shared OTel client certificate (full secret; not verified by the collector)..." +kubectl get secret klio-server-otel-client-tls -n "${SOURCE_NS}" -o json | + jq 'del(.metadata.namespace,.metadata.resourceVersion,.metadata.uid,.metadata.creationTimestamp,.metadata.ownerReferences,.metadata.annotations)' | + kubectl apply -n "${DEST_NS}" -f - + +echo "Done. You can now run: kubectl apply -k team-c" \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/kustomization.yaml b/operator/config/samples/opentelemetry/multi/kustomization.yaml new file mode 100644 index 00000000..b8a32ac3 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/kustomization.yaml @@ -0,0 +1,16 @@ +# Deploys two Klio servers (klio-a, klio-b) and two CNPG clusters +# (cluster-a -> klio-a, cluster-b -> klio-b) into the "default" namespace, +# reusing ../single's Server/Cluster definitions (see ./team-a, ./team-b), +# and shares the OTel collector / Jaeger / Prometheus stack defined in +# ../base. ./team-a and ./team-b are named for consistency with ./team-c +# and ./team-d, but — unlike those two — both still deploy into "default", +# not a namespace of their own. See: +# ./team-c for a third cluster in a different namespace, backed by klio-b +# ./team-d for a second, independent server also named "klio-a" (so its +# StatefulSet pod, and therefore host_name, collides with the original) +resources: + - ../base + - team-a + - team-b + - cluster_a_klio_client_auth.yaml + - cluster_b_klio_client_auth.yaml \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-a/kustomization.yaml b/operator/config/samples/opentelemetry/multi/team-a/kustomization.yaml new file mode 100644 index 00000000..2aa5f5f9 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-a/kustomization.yaml @@ -0,0 +1,78 @@ +# Instantiates ../../single's Klio server and CNPG cluster a second time, +# as "klio-a"/"cluster-a" in the "default" namespace. Only the fields that +# derive from the resource's own name are patched here; everything else +# (PVC templates, volumes, cert usages/issuerRef, plugin container list...) +# is inherited unchanged from ../../single. +namespace: default +resources: + - ../../single/server + - ../../single/cluster +patches: + - target: + kind: Server + name: klio + patch: |- + - op: replace + path: /metadata/name + value: klio-a + - op: replace + path: /spec/tlsSecretName + value: klio-a-tls + - op: replace + path: /spec/template/spec/containers/0/env/2/value + value: klio-server-a + - target: + kind: Certificate + name: klio-server + patch: |- + - op: replace + path: /metadata/name + value: klio-a + - op: replace + path: /spec/secretName + value: klio-a-tls + - op: replace + path: /spec/commonName + value: klio-a + - op: replace + path: /spec/dnsNames + value: [klio-a, klio-a.default, klio-a.default.svc] + - target: + kind: Cluster + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-a + - op: replace + path: /spec/plugins/0/parameters/pluginConfigurationRef + value: client-config-cluster-a + - target: + kind: PluginConfiguration + name: client-config-cluster-example + patch: |- + - op: replace + path: /metadata/name + value: client-config-cluster-a + - op: replace + path: /spec/serverAddress + value: klio-a.default + - op: replace + path: /spec/clientSecretName + value: cluster-a-klio-user + - op: replace + path: /spec/serverSecretName + value: klio-a-tls + - op: replace + path: /spec/clusterName + value: cluster-a + - target: + kind: PodMonitor + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-a + - op: replace + path: /spec/selector/matchLabels/cnpg.io~1cluster + value: cluster-a \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-b/kustomization.yaml b/operator/config/samples/opentelemetry/multi/team-b/kustomization.yaml new file mode 100644 index 00000000..c8de9414 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-b/kustomization.yaml @@ -0,0 +1,85 @@ +# Instantiates ../../single's Klio server and CNPG cluster a third time, as +# "klio-b"/"cluster-b" in the "default" namespace. klio-b is also reached +# from cluster-c (namespace "team-c", see ../team-c), so its dnsNames must +# cover both the short in-namespace form and the fully-qualified +# cross-namespace form used as PluginConfiguration.serverAddress by +# cluster-c. +namespace: default +resources: + - ../../single/server + - ../../single/cluster +patches: + - target: + kind: Server + name: klio + patch: |- + - op: replace + path: /metadata/name + value: klio-b + - op: replace + path: /spec/tlsSecretName + value: klio-b-tls + - op: replace + path: /spec/template/spec/containers/0/env/2/value + value: klio-server-b + - target: + kind: Certificate + name: klio-server + patch: |- + - op: replace + path: /metadata/name + value: klio-b + - op: replace + path: /spec/secretName + value: klio-b-tls + - op: replace + path: /spec/commonName + value: klio-b + - op: replace + path: /spec/dnsNames + value: + [ + klio-b, + klio-b.default, + klio-b.default.svc, + klio-b.default.svc.cluster.local, + ] + - target: + kind: Cluster + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-b + - op: replace + path: /spec/plugins/0/parameters/pluginConfigurationRef + value: client-config-cluster-b + - target: + kind: PluginConfiguration + name: client-config-cluster-example + patch: |- + - op: replace + path: /metadata/name + value: client-config-cluster-b + - op: replace + path: /spec/serverAddress + value: klio-b.default + - op: replace + path: /spec/clientSecretName + value: cluster-b-klio-user + - op: replace + path: /spec/serverSecretName + value: klio-b-tls + - op: replace + path: /spec/clusterName + value: cluster-b + - target: + kind: PodMonitor + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-b + - op: replace + path: /spec/selector/matchLabels/cnpg.io~1cluster + value: cluster-b \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-c/cluster_c_klio_client_auth.yaml b/operator/config/samples/opentelemetry/multi/team-c/cluster_c_klio_client_auth.yaml new file mode 100644 index 00000000..b9f8b9e1 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-c/cluster_c_klio_client_auth.yaml @@ -0,0 +1,25 @@ +# cluster-c's client certificate, requested directly in "team-c" via the +# cluster-scoped klio-server-ca ClusterIssuer (see ../../base). Unlike +# klio-b's own certificate (which cluster-c's PluginConfiguration pins by +# exact bytes, see ../copy-cross-namespace-secrets.sh), this is a genuinely +# separate certificate signed by the shared CA — no cross-namespace copy +# needed. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cluster-c-klio-user +spec: + commonName: klio@cluster-c + secretName: cluster-c-klio-user + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: false + usages: + - client auth + + issuerRef: + name: klio-server-ca + kind: ClusterIssuer + group: cert-manager.io \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-c/cluster_klio_otel_config.yaml b/operator/config/samples/opentelemetry/multi/team-c/cluster_klio_otel_config.yaml new file mode 100644 index 00000000..d7cbbdad --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-c/cluster_klio_otel_config.yaml @@ -0,0 +1,20 @@ +# Same settings as ../cluster_klio_otel_config.yaml, but the endpoint is +# fully-qualified since the otel-collector Service lives in "default", not +# in this namespace. +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-klio-otel-config + namespace: team-c +data: + OTEL_RESOURCE_DETECTORS: "telemetry.sdk,host,os.type,process.executable.name" + OTEL_TRACES_EXPORTER: "otlp" + OTEL_METRICS_EXPORTER: "otlp" + OTEL_EXPORTER_OTLP_PROTOCOL: "grpc" + OTEL_EXPORTER_OTLP_ENDPOINT: "https://otel-collector.default.svc.cluster.local:4317" + OTEL_EXPORTER_OTLP_COMPRESSION: "gzip" + OTEL_EXPORTER_OTLP_TIMEOUT: "10000" + OTEL_EXPORTER_OTLP_INSECURE: "false" + OTEL_EXPORTER_OTLP_CERTIFICATE: "/projected/ca.crt" + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: "/projected/tls.crt" + OTEL_EXPORTER_OTLP_CLIENT_KEY: "/projected/tls.key" diff --git a/operator/config/samples/opentelemetry/multi/team-c/kustomization.yaml b/operator/config/samples/opentelemetry/multi/team-c/kustomization.yaml new file mode 100644 index 00000000..4973e2e9 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-c/kustomization.yaml @@ -0,0 +1,67 @@ +# Apply ../kustomization.yaml first, then run ../copy-cross-namespace-secrets.sh +# to populate the secrets this kustomization expects to already exist +# (klio-b-tls, otel-collector-ca, klio-server-otel-client-tls), then apply +# this one. +# +# cluster-c reuses ../../single's Cluster/PluginConfiguration (see ../team-a +# for how that reuse looks); it is backed by klio-b, which lives in the +# "default" namespace, not here. This exercises a single Klio server +# serving clusters from more than one namespace. serverSecretName above +# (klio-b-tls) and the OTel client secret are NOT created by this +# kustomization: klio-b's certificate is pinned by exact bytes rather than +# CA-validated (see connection.go, referenced from +# ../copy-cross-namespace-secrets.sh), so its public half has to be copied +# in from "default" by that script, which must be run before applying this +# kustomization. cluster-c's OWN client certificate +# (cluster_c_klio_client_auth.yaml) has no such requirement: it is signed +# by the cluster-scoped klio-server-ca ClusterIssuer (see ../../base) and +# requested directly in this namespace. +namespace: team-c +resources: + - namespace.yaml + - cluster_klio_otel_config.yaml + - cluster_c_klio_client_auth.yaml + - ../../single/cluster +patches: + - target: + kind: Cluster + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-c + - op: replace + path: /spec/plugins/0/parameters/pluginConfigurationRef + value: client-config-cluster-c + - op: replace + path: /spec/projectedVolumeTemplate/sources/0/secret/name + value: otel-collector-ca + - target: + kind: PluginConfiguration + name: client-config-cluster-example + patch: |- + - op: replace + path: /metadata/name + value: client-config-cluster-c + - op: replace + path: /spec/serverAddress + value: klio-b.default.svc.cluster.local + - op: replace + path: /spec/clientSecretName + value: cluster-c-klio-user + - op: replace + path: /spec/serverSecretName + value: klio-b-tls + - op: replace + path: /spec/clusterName + value: cluster-c + - target: + kind: PodMonitor + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-c + - op: replace + path: /spec/selector/matchLabels/cnpg.io~1cluster + value: cluster-c diff --git a/operator/config/samples/opentelemetry/multi/team-c/namespace.yaml b/operator/config/samples/opentelemetry/multi/team-c/namespace.yaml new file mode 100644 index 00000000..3375cd25 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-c/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: team-c diff --git a/operator/config/samples/opentelemetry/multi/team-d/cluster_d_klio_client_auth.yaml b/operator/config/samples/opentelemetry/multi/team-d/cluster_d_klio_client_auth.yaml new file mode 100644 index 00000000..a846b41b --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/cluster_d_klio_client_auth.yaml @@ -0,0 +1,28 @@ +# Client cert for cluster-d, backed by a SECOND Klio server also named +# "klio-a" (see ../team-d), living in a different namespace than the +# original klio-a in "default". Since a Server's StatefulSet pod name +# equals the Server's own name, this second klio-a's pod is ALSO named +# "klio-a-klio-0" -- an identical host_name to the original, but in a +# different namespace. Requested directly here via the cluster-scoped +# klio-server-ca ClusterIssuer (see ../../base) — no cross-namespace copy +# needed for this one, unlike the CA's own public cert and the OTel trust +# anchor (see ../bootstrap-remote-server.sh). +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cluster-d-klio-user +spec: + commonName: klio@cluster-d + secretName: cluster-d-klio-user + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: false + usages: + - client auth + + issuerRef: + name: klio-server-ca + kind: ClusterIssuer + group: cert-manager.io \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-d/cluster_klio_otel_config.yaml b/operator/config/samples/opentelemetry/multi/team-d/cluster_klio_otel_config.yaml new file mode 100644 index 00000000..fff353d4 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/cluster_klio_otel_config.yaml @@ -0,0 +1,20 @@ +# Same settings as ../cluster_klio_otel_config.yaml, but the endpoint is +# fully-qualified since the otel-collector Service lives in "default", not +# in this namespace. +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-klio-otel-config + namespace: team-d +data: + OTEL_RESOURCE_DETECTORS: "telemetry.sdk,host,os.type,process.executable.name" + OTEL_TRACES_EXPORTER: "otlp" + OTEL_METRICS_EXPORTER: "otlp" + OTEL_EXPORTER_OTLP_PROTOCOL: "grpc" + OTEL_EXPORTER_OTLP_ENDPOINT: "https://otel-collector.default.svc.cluster.local:4317" + OTEL_EXPORTER_OTLP_COMPRESSION: "gzip" + OTEL_EXPORTER_OTLP_TIMEOUT: "10000" + OTEL_EXPORTER_OTLP_INSECURE: "false" + OTEL_EXPORTER_OTLP_CERTIFICATE: "/projected/ca.crt" + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: "/projected/tls.crt" + OTEL_EXPORTER_OTLP_CLIENT_KEY: "/projected/tls.key" diff --git a/operator/config/samples/opentelemetry/multi/team-d/issuer.yaml b/operator/config/samples/opentelemetry/multi/team-d/issuer.yaml new file mode 100644 index 00000000..57400914 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/issuer.yaml @@ -0,0 +1,10 @@ +# Local self-signed issuer for this namespace's OWN Klio server identity +# (cert-manager Issuers are namespace-scoped, so ../issuer.yaml in "default" +# can't be reused here). +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: team-d +spec: + selfSigned: {} diff --git a/operator/config/samples/opentelemetry/klio_encryption.yaml b/operator/config/samples/opentelemetry/multi/team-d/klio_encryption.yaml similarity index 82% rename from operator/config/samples/opentelemetry/klio_encryption.yaml rename to operator/config/samples/opentelemetry/multi/team-d/klio_encryption.yaml index 1938bc40..e6c2a9e7 100644 --- a/operator/config/samples/opentelemetry/klio_encryption.yaml +++ b/operator/config/samples/opentelemetry/multi/team-d/klio_encryption.yaml @@ -1,3 +1,5 @@ +# Same content as ../klio_encryption.yaml: reusing the same encryption +# identity across servers is fine for this demo. apiVersion: v1 stringData: secret-key: AGE-SECRET-KEY-1P7TWJ8H837DPVLSRVHAP0ZCZVHXJRTUS7S0A5VZAR49URW0Z9Q0SFW4HVM @@ -13,3 +15,4 @@ stringData: kind: Secret metadata: name: klio-encryption + namespace: team-d diff --git a/operator/config/samples/opentelemetry/multi/team-d/klio_server_otel_config.yaml b/operator/config/samples/opentelemetry/multi/team-d/klio_server_otel_config.yaml new file mode 100644 index 00000000..33e1568d --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/klio_server_otel_config.yaml @@ -0,0 +1,28 @@ +# Same settings as ../klio_server_otel_config.yaml, but the endpoint is +# fully-qualified since the otel-collector Service lives in "default", not +# in this namespace. +apiVersion: v1 +kind: ConfigMap +metadata: + name: klio-server-otel-config + namespace: team-d +data: + OTEL_RESOURCE_DETECTORS: "telemetry.sdk,host,os.type,process.executable.name" + OTEL_TRACES_EXPORTER: "otlp" + OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: "grpc" + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "https://otel-collector.default.svc.cluster.local:4317" + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip" + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10000" + OTEL_EXPORTER_OTLP_TRACES_INSECURE: "false" + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: "/otel/ca.crt" + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: "/otel/tls.crt" + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: "/otel/tls.key" + OTEL_METRICS_EXPORTER: "otlp" + OTEL_METRIC_EXPORT_INTERVAL: "60000" + OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: "grpc" + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "https://otel-collector.default.svc.cluster.local:4317" + OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "60000" + OTEL_EXPORTER_OTLP_METRICS_INSECURE: "false" + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: "/otel/ca.crt" + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: "/otel/tls.crt" + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: "/otel/tls.key" diff --git a/operator/config/samples/opentelemetry/multi/team-d/kustomization.yaml b/operator/config/samples/opentelemetry/multi/team-d/kustomization.yaml new file mode 100644 index 00000000..8861e3b3 --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/kustomization.yaml @@ -0,0 +1,101 @@ +# Apply ../kustomization.yaml first, then run: +# ../bootstrap-remote-server.sh team-d +# to populate the secrets this kustomization expects to already exist +# (klio-server-ca, otel-collector-ca, klio-server-otel-client-tls), then +# apply this one. Those three are all pinned-by-exact-bytes copies of +# secrets that live in "default" (see the script's comments); cluster-d's +# OWN client certificate (cluster_d_klio_client_auth.yaml) has no such +# requirement, since it is signed by the cluster-scoped klio-server-ca +# ClusterIssuer (see ../../base) and requested directly in this namespace. +# +# Reuses ../../single's Server and Cluster/PluginConfiguration (see +# ../team-a for how that reuse looks). The server keeps the name "klio-a" +# (same as ../team-a's), deliberately colliding with it: since a Server's +# StatefulSet pod name equals the Server's own name, this second klio-a's +# pod is ALSO named "klio-a-klio-0" -- an identical host_name to the +# original, but in a different namespace. The cluster is named "cluster-d". +namespace: team-d +resources: + - namespace.yaml + - issuer.yaml + - klio_encryption.yaml + - klio_server_otel_config.yaml + - cluster_klio_otel_config.yaml + - cluster_d_klio_client_auth.yaml + - ../../single/server + - ../../single/cluster +patches: + - target: + kind: Server + name: klio + patch: |- + - op: replace + path: /metadata/name + value: klio-a + - op: replace + path: /spec/tlsSecretName + value: klio-a-tls + - op: replace + path: /spec/template/spec/containers/0/env/2/value + value: klio-server-a-team-d + - op: replace + path: /spec/template/spec/volumes/0/projected/sources/0/secret/name + value: otel-collector-ca + - target: + kind: Certificate + name: klio-server + patch: |- + - op: replace + path: /metadata/name + value: klio-a + - op: replace + path: /spec/secretName + value: klio-a-tls + - op: replace + path: /spec/commonName + value: klio-a + - op: replace + path: /spec/dnsNames + value: [klio-a, klio-a.team-d, klio-a.team-d.svc] + - target: + kind: Cluster + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-d + - op: replace + path: /spec/plugins/0/parameters/pluginConfigurationRef + value: client-config-cluster-d + - op: replace + path: /spec/projectedVolumeTemplate/sources/0/secret/name + value: otel-collector-ca + - target: + kind: PluginConfiguration + name: client-config-cluster-example + patch: |- + - op: replace + path: /metadata/name + value: client-config-cluster-d + - op: replace + path: /spec/serverAddress + value: klio-a + - op: replace + path: /spec/clientSecretName + value: cluster-d-klio-user + - op: replace + path: /spec/serverSecretName + value: klio-a-tls + - op: replace + path: /spec/clusterName + value: cluster-d + - target: + kind: PodMonitor + name: cluster-example + patch: |- + - op: replace + path: /metadata/name + value: cluster-d + - op: replace + path: /spec/selector/matchLabels/cnpg.io~1cluster + value: cluster-d \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/multi/team-d/namespace.yaml b/operator/config/samples/opentelemetry/multi/team-d/namespace.yaml new file mode 100644 index 00000000..641c44af --- /dev/null +++ b/operator/config/samples/opentelemetry/multi/team-d/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: team-d diff --git a/operator/config/samples/opentelemetry/single/backups-example.yaml b/operator/config/samples/opentelemetry/single/backups-example.yaml new file mode 100644 index 00000000..293db777 --- /dev/null +++ b/operator/config/samples/opentelemetry/single/backups-example.yaml @@ -0,0 +1,16 @@ +# Triggers one base backup on cluster-example, so the Grafana dashboard has +# backup/snapshot data to show. Apply after cluster-example is healthy: +# +# kubectl apply -f operator/config/samples/opentelemetry/single/backups-example.yaml +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: cluster-example-backup-1 + namespace: default +spec: + method: plugin + target: primary + cluster: + name: cluster-example + pluginConfiguration: + name: klio.cnpg.io \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/cluster.yaml b/operator/config/samples/opentelemetry/single/cluster/cluster.yaml similarity index 100% rename from operator/config/samples/opentelemetry/cluster.yaml rename to operator/config/samples/opentelemetry/single/cluster/cluster.yaml diff --git a/operator/config/samples/opentelemetry/single/cluster/cluster_pod_monitor.yaml b/operator/config/samples/opentelemetry/single/cluster/cluster_pod_monitor.yaml new file mode 100644 index 00000000..fa21a9c9 --- /dev/null +++ b/operator/config/samples/opentelemetry/single/cluster/cluster_pod_monitor.yaml @@ -0,0 +1,13 @@ +# Exposes the CNPG cluster's own metrics (including cnpg_pg_stat_replication_*, +# which the Grafana dashboard's WAL Replication Lag row reads) to Prometheus. +# See ../../../../../documentation/web/docs/user/grafana-dashboards.md. +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: cluster-example +spec: + selector: + matchLabels: + cnpg.io/cluster: cluster-example + podMetricsEndpoints: + - port: metrics \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/single/cluster/kustomization.yaml b/operator/config/samples/opentelemetry/single/cluster/kustomization.yaml new file mode 100644 index 00000000..979cb9b4 --- /dev/null +++ b/operator/config/samples/opentelemetry/single/cluster/kustomization.yaml @@ -0,0 +1,7 @@ +# The CNPG cluster + its PluginConfiguration, as their own buildable unit so +# ../../multi can reuse them (as cluster-a, cluster-b, ...) without +# duplicating their spec. See ../../multi/team-a for how that reuse looks. +resources: + - cluster.yaml + - plugin_configuration.yaml + - cluster_pod_monitor.yaml diff --git a/operator/config/samples/opentelemetry/plugin_configuration.yaml b/operator/config/samples/opentelemetry/single/cluster/plugin_configuration.yaml similarity index 100% rename from operator/config/samples/opentelemetry/plugin_configuration.yaml rename to operator/config/samples/opentelemetry/single/cluster/plugin_configuration.yaml diff --git a/operator/config/samples/opentelemetry/cluster_klio_client_auth.yaml b/operator/config/samples/opentelemetry/single/cluster_klio_client_auth.yaml similarity index 93% rename from operator/config/samples/opentelemetry/cluster_klio_client_auth.yaml rename to operator/config/samples/opentelemetry/single/cluster_klio_client_auth.yaml index b3f8935b..a572cde5 100644 --- a/operator/config/samples/opentelemetry/cluster_klio_client_auth.yaml +++ b/operator/config/samples/opentelemetry/single/cluster_klio_client_auth.yaml @@ -15,5 +15,5 @@ spec: issuerRef: name: klio-server-ca - kind: Issuer + kind: ClusterIssuer group: cert-manager.io diff --git a/operator/config/samples/opentelemetry/single/kustomization.yaml b/operator/config/samples/opentelemetry/single/kustomization.yaml new file mode 100644 index 00000000..43989f76 --- /dev/null +++ b/operator/config/samples/opentelemetry/single/kustomization.yaml @@ -0,0 +1,9 @@ +# One Klio server + one CNPG cluster, sharing the OTel collector / Jaeger / +# Prometheus stack defined in ../base. See ../multi for a scenario covering +# more than one server/cluster/namespace, which reuses ./server and +# ./cluster rather than duplicating them. +resources: + - ../base + - server + - cluster + - cluster_klio_client_auth.yaml \ No newline at end of file diff --git a/operator/config/samples/opentelemetry/single/server/kustomization.yaml b/operator/config/samples/opentelemetry/single/server/kustomization.yaml new file mode 100644 index 00000000..c60d99f7 --- /dev/null +++ b/operator/config/samples/opentelemetry/single/server/kustomization.yaml @@ -0,0 +1,6 @@ +# The Klio server + its self-signed Certificate, as their own buildable unit +# so ../../multi can reuse them (as klio-a, klio-b, ...) without duplicating +# their spec. See ../../multi/team-a for how that reuse looks. +resources: + - server.yaml + - server_certificate.yaml diff --git a/operator/config/samples/opentelemetry/klio_server.yaml b/operator/config/samples/opentelemetry/single/server/server.yaml similarity index 100% rename from operator/config/samples/opentelemetry/klio_server.yaml rename to operator/config/samples/opentelemetry/single/server/server.yaml diff --git a/operator/config/samples/opentelemetry/klio_server_certificate.yaml b/operator/config/samples/opentelemetry/single/server/server_certificate.yaml similarity index 100% rename from operator/config/samples/opentelemetry/klio_server_certificate.yaml rename to operator/config/samples/opentelemetry/single/server/server_certificate.yaml