Skip to content

operator & charts/redpanda: cut release v26.2.3 / v26.2.3 - #1816

Merged
RafalKorepta merged 1 commit into
release/v26.2.xfrom
rk/operator/release-26.2.3
Sep 3, 2026
Merged

operator & charts/redpanda: cut release v26.2.3 / v26.2.3#1816
RafalKorepta merged 1 commit into
release/v26.2.xfrom
rk/operator/release-26.2.3

Conversation

@RafalKorepta

Copy link
Copy Markdown
Contributor

Cuts the operator and charts/redpanda releases on the release/v26.2.x line in a single commit.

Also bumps the default Redpanda version installed by the chart (appVersion) to v26.2.2.

operator: cut release v26.2.3

v26.2.3 - 2026-09-03

Added

  • The operator chart can add a scrape-time label identifying which Kubernetes
    cluster a metrics series came from, via monitoring.clusterLabel. Off by
    default. Applies to single-cluster and stretch-cluster deployments alike.

    Use it whenever operator metrics from more than one Kubernetes cluster land in
    the same Prometheus-compatible backend — several independent installs
    remote_writing to a shared Mimir/Thanos, or one StretchCluster spanning
    clusters. In either case nothing in the scraped series says which cluster
    produced it: job, namespace, service and pod names are identical in every
    cluster, and identical by design when each install uses the same release
    name. The series collide, and a graph of, say,
    controller_runtime_reconcile_total sums clusters together without saying so.

    monitoring.clusterLabel.enabled=true renders a relabeling on the
    ServiceMonitor endpoint that stamps redpanda_k8s_cluster onto every series
    from that operator. monitoring.clusterLabel.name and .value override the
    label and its value.

    When multicluster.enabled is true the value defaults to
    multicluster.name, which is already the cluster's identity in the
    operator's raft group, so a stretch deployment needs only the toggle.
    Otherwise .value is required — including when multicluster.name happens
    to be set but multicluster mode is off, since that name configures nothing
    else there and inheriting it would turn a stale value into a metric label.
    The render fails rather than emitting an empty label, since an empty label
    looks like data.

    Off by default because one cluster reporting to its own Prometheus has nothing
    to disambiguate, and adding a label to everyone's series would churn existing
    dashboards and recording rules.

  • Rolling restarts now wait for each broker's Schema Registry store to catch up
    on _schemas (via the auth-exempt GET /status/ready probe) before rolling the
    next broker, so overlapping SR replay windows can no longer leave a cluster
    without a consistent Schema Registry endpoint mid-upgrade. The gate applies
    to the V1 (Cluster), V2 (Redpanda), and multicluster (StretchCluster)
    controllers, is skipped on clusters without a Schema Registry listener, and
    can be disabled with --wait-for-schema-registry-sync=false.

  • Telemetry now reports id_hash for clusters licensed through their CR, not
    only for operators given their own license file.

    id_hash was previously derived solely from the operator's own
    --license-file-path (operator chart enterprise.licenseSecretRef), which
    deployers set only for the Connect controller or multicluster — so every
    install that licensed Redpanda the usual way, on the CR, reported no
    id_hash and could not be correlated to an account. The collector now
    resolves the license configured on each managed cluster
    (Redpanda .spec.clusterSpec.enterprise.license/licenseSecretRef and
    legacy Cluster .spec.licenseRef) and reports its checksum.

    The operator's own license stays authoritative when present. A new
    clusterLicenses.checksums field carries the distinct license checksums
    found across the managed clusters, sorted, so a fleet holding several
    licenses still correlates to every account it belongs to instead of to
    none; id_hash itself is left empty in that case, since no single checksum
    represents the install. clusterLicenses.licensed counts the clusters
    carrying a valid license, which the deduplicated checksum list cannot
    express — several clusters commonly share one license.

    Licenses that are expired, non-enterprise, or unreadable are skipped rather
    than failing the report, and commands that do not reconcile the legacy v1
    API do not report those clusters' licenses.

  • The single-cluster operator now supports --leader-election-lease-duration,
    --leader-election-renew-deadline, and --leader-election-retry-period for
    tuning leader election. The existing 15s, 10s, and 2s defaults remain
    unchanged.

Fixed

  • The sidecar's user watcher now sets the superusers cluster property once
    per sync pass, with the union of every users file, instead of once per file
    with only that file's users.
    Operator-managed clusters never saw the transient superuser revocation this
    fixes — the operator deploys the sidecar with --no-set-superusers, so the
    watcher never wrote the property there. The visible change for them is log
    hygiene: malformed users-file lines, which can contain passwords, are no
    longer echoed into the sidecar log.
    See the redpanda chart's changelog entry for the full description.

  • The multicluster command now serves its metrics endpoint over HTTPS by
    default, so the operator chart's ServiceMonitor can actually scrape a
    multicluster deployment.

    The chart renders the ServiceMonitor with scheme: https and
    insecureSkipVerify: true, which is what the run command's
    --metrics-secure default (true) produces — controller-runtime terminates
    TLS with a self-signed certificate when no certificate path is given. The
    multicluster command had no such flag and enabled secure serving only when
    --metrics-cert-path/--metrics-key-path were passed, which the chart never
    does, so it listened for plain HTTP on the metrics port and every scrape
    failed in the TLS handshake. Operator metrics from a multicluster
    installation were therefore never collected. multicluster now takes the
    same --metrics-secure flag, defaulting to true; the metrics endpoint stays
    behind bearer-token authn/authz either way.

    If you worked around this by overriding the rendered ServiceMonitor to
    scheme: http, drop that override — the scrape now needs https. To keep
    the old plain-HTTP endpoint instead, pass --metrics-secure=false to the
    operator.

    Relatedly, rpk k8s multicluster bundle now expects HTTPS unless
    --metrics-secure=false is present in the deployment's arguments, and
    retries a failed scrape with the other scheme so bundles still collect
    metrics from operators predating this change.

  • The multicluster operator now reports telemetry instead of dropping every report.

    The telemetry collector listed the legacy vectorized.io/v1alpha1 Cluster
    API unconditionally, which the multicluster command's scheme does not
    register because it does not reconcile that API. The resulting
    no kind is registered for the type v1alpha1.ClusterList is neither a
    NoMatch nor a Forbidden, so it propagated out of Collect and the reporter
    discarded the whole document on every cycle — no stretch or multicluster
    install has ever reported telemetry, in any release.

    The multicluster command now declares that it does not collect the legacy
    v1 API, so that list is skipped outright rather than attempted against a
    scheme that cannot serialize it. This keeps each command's scheme matching
    the CRDs it actually installs and saves an API server round trip per
    reporting cycle. As a backstop for any future type a command's scheme
    omits, the collector also tolerates a not-registered type the same way it
    already tolerated a missing CRD or missing RBAC: that one field degrades to
    its zero value and every other field is still reported, instead of the
    whole install vanishing from the dataset.

    One consequence worth knowing: legacy vectorized.io/v1alpha1 clusters
    running alongside a multicluster install are reported as zero. Those
    clusters are not managed by that command either.

  • An unreadable broker list no longer aborts the whole reconcile pass — the
    maintenance-mode step defers instead. Because it runs first in both the
    single-cluster and StretchCluster chains, a transient admin-API read failure
    against a broker whose pod is already gone (mid-roll, mid-decommission, or a
    BrokerPool being deleted) previously aborted decommissioning and
    cluster-config sync for that pass, so the very broker that made the read
    fail was never removed

  • The StretchCluster admin, Kafka, and Schema Registry clients no longer offer
    brokers whose pod cannot be dialed.

    Endpoints came from declared replica counts alone, so clients also tried
    deliberately absent brokers — a deleted pool, a broker mid-roll — spending
    their timeout on each. Terminating, finished, and address-less pods are now
    skipped; with none dialable, the full declared list is used as before.

  • The monitoring.rulesEnabled PrometheusRule and the shipped Grafana
    dashboard now scope every expression to this operator install by job and
    namespace, and keep both labels on the recorded series.
    controller_runtime_* and workqueue_* are exported by every
    controller-runtime operator on the cluster (Karpenter, Flux, cert-manager,
    Trivy), so unscoped rules fired the operator's alerts for foreign
    controllers and merged same-named controllers across operators. The
    dashboard gains Namespace and Job pickers plus one for the opt-in
    monitoring.clusterLabel label.

  • The monitoring.rulesEnabled alerts that read a recording rule now carry
    the same job/namespace matcher as the rest, so two operator installs sharing
    a Prometheus stop alerting on each other's controllers.

    K8S-926 scoped the recording rules and the alerts that read raw metrics, but
    left OperatorReconcileErrors, OperatorReconcileRunaway and
    OperatorReconcileStalled matching a recorded series by name alone. A
    recorded series is not namespaced to whichever install produced it, so with
    two installs rendering their PrometheusRule into one Prometheus, each
    install's copy of those alerts evaluated against both installs' series.

  • Fixed false-positive OperatorReconcileRunaway and
    OperatorWorkerPoolSaturated alerts during healthy interval reconciliation.
    A new OperatorReconcileChurn alert tracks non-interval work, Runaway
    retains a higher-threshold total-rate backstop, and saturation now measures
    sustained workqueue delay instead of worker utilization.

  • User, Role, and Group resources now reconcile on clusters with
    listeners.schemaRegistry.enabled=false. The Schema Registry client is no
    longer resolved via DNS SRV lookup (which always failed with the listener
    disabled, blocking all ACL syncs); a disabled listener is treated as "Schema
    Registry not configured", matching v1 clusters.

charts/redpanda: cut release v26.2.3

v26.2.3 - 2026-09-03

Changed

  • Bump operator sidecar image tag to v26.2.3 release
  • The default Redpanda version installed by the chart is now
    v26.2.2.

Fixed

  • The sidecar's user watcher now sets the superusers cluster property once
    per sync pass, with the union of every users file, instead of once per file
    with only that file's users.
    Previously every sidecar start and every users-secret update transiently
    replaced the list with a partial one — kubelet's ..data symlink even
    parsed as an empty users file — momentarily revoking superuser status from
    connected clients. Only helm-chart deployments were affected; the operator
    deploys the sidecar with --no-set-superusers.
    The property is now written only when the list actually changes, so sidecar
    restarts no longer bump the cluster config version; when a users file can't
    be read, the patch is withheld and the pass retried with backoff instead of
    writing a partial list; and malformed users-file lines, which can contain
    passwords, are no longer echoed into the sidecar log.

🤖 Generated with Claude Code

## operator: cut release v26.2.3

## [v26.2.3](https://github.com/redpanda-data/redpanda-operator/releases/tag/operator%2Fv26.2.3) - 2026-09-03
### Added
* The operator chart can add a scrape-time label identifying which Kubernetes
  cluster a metrics series came from, via `monitoring.clusterLabel`. Off by
  default. Applies to single-cluster and stretch-cluster deployments alike.

  Use it whenever operator metrics from more than one Kubernetes cluster land in
  the same Prometheus-compatible backend — several independent installs
  remote_writing to a shared Mimir/Thanos, or one StretchCluster spanning
  clusters. In either case nothing in the scraped series says which cluster
  produced it: job, namespace, service and pod names are identical in every
  cluster, and identical by design when each install uses the same release
  name. The series collide, and a graph of, say,
  `controller_runtime_reconcile_total` sums clusters together without saying so.

  `monitoring.clusterLabel.enabled=true` renders a relabeling on the
  ServiceMonitor endpoint that stamps `redpanda_k8s_cluster` onto every series
  from that operator. `monitoring.clusterLabel.name` and `.value` override the
  label and its value.

  When `multicluster.enabled` is true the value defaults to
  `multicluster.name`, which is already the cluster's identity in the
  operator's raft group, so a stretch deployment needs only the toggle.
  Otherwise `.value` is required — including when `multicluster.name` happens
  to be set but multicluster mode is off, since that name configures nothing
  else there and inheriting it would turn a stale value into a metric label.
  The render fails rather than emitting an empty label, since an empty label
  looks like data.

  Off by default because one cluster reporting to its own Prometheus has nothing
  to disambiguate, and adding a label to everyone's series would churn existing
  dashboards and recording rules.
* Rolling restarts now wait for each broker's Schema Registry store to catch up
  on _schemas (via the auth-exempt GET /status/ready probe) before rolling the
  next broker, so overlapping SR replay windows can no longer leave a cluster
  without a consistent Schema Registry endpoint mid-upgrade. The gate applies
  to the V1 (Cluster), V2 (Redpanda), and multicluster (StretchCluster)
  controllers, is skipped on clusters without a Schema Registry listener, and
  can be disabled with --wait-for-schema-registry-sync=false.
* Telemetry now reports `id_hash` for clusters licensed through their CR, not
  only for operators given their own license file.

  `id_hash` was previously derived solely from the operator's own
  `--license-file-path` (operator chart `enterprise.licenseSecretRef`), which
  deployers set only for the Connect controller or multicluster — so every
  install that licensed Redpanda the usual way, on the CR, reported no
  `id_hash` and could not be correlated to an account. The collector now
  resolves the license configured on each managed cluster
  (`Redpanda .spec.clusterSpec.enterprise.license`/`licenseSecretRef` and
  legacy `Cluster .spec.licenseRef`) and reports its checksum.

  The operator's own license stays authoritative when present. A new
  `clusterLicenses.checksums` field carries the distinct license checksums
  found across the managed clusters, sorted, so a fleet holding several
  licenses still correlates to every account it belongs to instead of to
  none; `id_hash` itself is left empty in that case, since no single checksum
  represents the install. `clusterLicenses.licensed` counts the clusters
  carrying a valid license, which the deduplicated checksum list cannot
  express — several clusters commonly share one license.

  Licenses that are expired, non-enterprise, or unreadable are skipped rather
  than failing the report, and commands that do not reconcile the legacy v1
  API do not report those clusters' licenses.
* The single-cluster operator now supports --leader-election-lease-duration,
  --leader-election-renew-deadline, and --leader-election-retry-period for
  tuning leader election. The existing 15s, 10s, and 2s defaults remain
  unchanged.
### Fixed
* The sidecar's user watcher now sets the `superusers` cluster property once
  per sync pass, with the union of every users file, instead of once per file
  with only that file's users.
  Operator-managed clusters never saw the transient superuser revocation this
  fixes — the operator deploys the sidecar with `--no-set-superusers`, so the
  watcher never wrote the property there. The visible change for them is log
  hygiene: malformed users-file lines, which can contain passwords, are no
  longer echoed into the sidecar log.
  See the redpanda chart's changelog entry for the full description.
* The `multicluster` command now serves its metrics endpoint over HTTPS by
  default, so the operator chart's ServiceMonitor can actually scrape a
  multicluster deployment.

  The chart renders the ServiceMonitor with `scheme: https` and
  `insecureSkipVerify: true`, which is what the `run` command's
  `--metrics-secure` default (true) produces — controller-runtime terminates
  TLS with a self-signed certificate when no certificate path is given. The
  `multicluster` command had no such flag and enabled secure serving only when
  `--metrics-cert-path`/`--metrics-key-path` were passed, which the chart never
  does, so it listened for plain HTTP on the metrics port and every scrape
  failed in the TLS handshake. Operator metrics from a multicluster
  installation were therefore never collected. `multicluster` now takes the
  same `--metrics-secure` flag, defaulting to true; the metrics endpoint stays
  behind bearer-token authn/authz either way.

  If you worked around this by overriding the rendered ServiceMonitor to
  `scheme: http`, drop that override — the scrape now needs `https`. To keep
  the old plain-HTTP endpoint instead, pass `--metrics-secure=false` to the
  operator.

  Relatedly, `rpk k8s multicluster bundle` now expects HTTPS unless
  `--metrics-secure=false` is present in the deployment's arguments, and
  retries a failed scrape with the other scheme so bundles still collect
  metrics from operators predating this change.
* The multicluster operator now reports telemetry instead of dropping every report.

  The telemetry collector listed the legacy `vectorized.io/v1alpha1` `Cluster`
  API unconditionally, which the multicluster command's scheme does not
  register because it does not reconcile that API. The resulting
  `no kind is registered for the type v1alpha1.ClusterList` is neither a
  NoMatch nor a Forbidden, so it propagated out of `Collect` and the reporter
  discarded the whole document on every cycle — no stretch or multicluster
  install has ever reported telemetry, in any release.

  The `multicluster` command now declares that it does not collect the legacy
  v1 API, so that list is skipped outright rather than attempted against a
  scheme that cannot serialize it. This keeps each command's scheme matching
  the CRDs it actually installs and saves an API server round trip per
  reporting cycle. As a backstop for any future type a command's scheme
  omits, the collector also tolerates a not-registered type the same way it
  already tolerated a missing CRD or missing RBAC: that one field degrades to
  its zero value and every other field is still reported, instead of the
  whole install vanishing from the dataset.

  One consequence worth knowing: legacy `vectorized.io/v1alpha1` clusters
  running alongside a multicluster install are reported as zero. Those
  clusters are not managed by that command either.
* An unreadable broker list no longer aborts the whole reconcile pass — the
  maintenance-mode step defers instead. Because it runs first in both the
  single-cluster and StretchCluster chains, a transient admin-API read failure
  against a broker whose pod is already gone (mid-roll, mid-decommission, or a
  BrokerPool being deleted) previously aborted decommissioning and
  cluster-config sync for that pass, so the very broker that made the read
  fail was never removed
* The StretchCluster admin, Kafka, and Schema Registry clients no longer offer
  brokers whose pod cannot be dialed.

  Endpoints came from declared replica counts alone, so clients also tried
  deliberately absent brokers — a deleted pool, a broker mid-roll — spending
  their timeout on each. Terminating, finished, and address-less pods are now
  skipped; with none dialable, the full declared list is used as before.
* The `monitoring.rulesEnabled` PrometheusRule and the shipped Grafana
  dashboard now scope every expression to this operator install by `job` and
  `namespace`, and keep both labels on the recorded series.
  `controller_runtime_*` and `workqueue_*` are exported by every
  controller-runtime operator on the cluster (Karpenter, Flux, cert-manager,
  Trivy), so unscoped rules fired the operator's alerts for foreign
  controllers and merged same-named controllers across operators. The
  dashboard gains Namespace and Job pickers plus one for the opt-in
  `monitoring.clusterLabel` label.
* The `monitoring.rulesEnabled` alerts that read a recording rule now carry
  the same job/namespace matcher as the rest, so two operator installs sharing
  a Prometheus stop alerting on each other's controllers.

  K8S-926 scoped the recording rules and the alerts that read raw metrics, but
  left `OperatorReconcileErrors`, `OperatorReconcileRunaway` and
  `OperatorReconcileStalled` matching a recorded series by name alone. A
  recorded series is not namespaced to whichever install produced it, so with
  two installs rendering their PrometheusRule into one Prometheus, each
  install's copy of those alerts evaluated against both installs' series.
* Fixed false-positive `OperatorReconcileRunaway` and
  `OperatorWorkerPoolSaturated` alerts during healthy interval reconciliation.
  A new `OperatorReconcileChurn` alert tracks non-interval work, Runaway
  retains a higher-threshold total-rate backstop, and saturation now measures
  sustained workqueue delay instead of worker utilization.
* User, Role, and Group resources now reconcile on clusters with
  `listeners.schemaRegistry.enabled=false`. The Schema Registry client is no
  longer resolved via DNS SRV lookup (which always failed with the listener
  disabled, blocking all ACL syncs); a disabled listener is treated as "Schema
  Registry not configured", matching v1 clusters.

## charts/redpanda: cut release v26.2.3

## [v26.2.3](https://github.com/redpanda-data/redpanda-operator/releases/tag/charts%2Fredpanda%2Fv26.2.3) - 2026-09-03
### Changed
* Bump operator sidecar image tag to v26.2.3 release
* The default Redpanda version installed by the chart is now
  [v26.2.2](https://github.com/redpanda-data/redpanda/releases/tag/v26.2.2).
### Fixed
* The sidecar's user watcher now sets the `superusers` cluster property once
  per sync pass, with the union of every users file, instead of once per file
  with only that file's users.
  Previously every sidecar start and every users-secret update transiently
  replaced the list with a partial one — kubelet's `..data` symlink even
  parsed as an empty users file — momentarily revoking superuser status from
  connected clients. Only helm-chart deployments were affected; the operator
  deploys the sidecar with `--no-set-superusers`.
  The property is now written only when the list actually changes, so sidecar
  restarts no longer bump the cluster config version; when a users file can't
  be read, the patch is withheld and the pass retried with backoff instead of
  writing a partial list; and malformed users-file lines, which can contain
  passwords, are no longer echoed into the sidecar log.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@secpanda

secpanda commented Sep 3, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@RafalKorepta
RafalKorepta merged commit 6d3617f into release/v26.2.x Sep 3, 2026
14 checks passed
@RafalKorepta
RafalKorepta deleted the rk/operator/release-26.2.3 branch September 3, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants