Skip to content

Add rpk multicluster plugin wiring#1437

Merged
andrewstucki merged 11 commits intomainfrom
as/rpk-plugin-wiring
Apr 14, 2026
Merged

Add rpk multicluster plugin wiring#1437
andrewstucki merged 11 commits intomainfrom
as/rpk-plugin-wiring

Conversation

@andrewstucki
Copy link
Copy Markdown
Contributor

@andrewstucki andrewstucki commented Apr 9, 2026

Summary

Adds an rpk plugin (.rpk.ac-k8s) that provides rpk k8s multicluster subcommands for bootstrapping and diagnosing multicluster operator deployments. Also adds a reusable vcluster-based multicluster test helper and a pluggable health check framework.

What's included

rpk plugin (operator/cmd/rpk-k8s/)

  • rpk k8s multicluster bootstrap — generates a shared CA, per-cluster TLS certificates, and kubeconfig secrets across multiple Kubernetes clusters. Supports --kubeconfig (auto-discover all contexts), --context (explicit), and --dns-override (key=value SAN overrides). Replaces the standalone bootstrap-standalone binary (removed).
  • rpk k8s multicluster status — runs a suite of health checks against each cluster and reports a summary table with per-cluster issues and cross-cluster consistency validation.
  • Autocomplete support via --help-autocomplete JSON output for rpk plugin discovery.

Check framework (operator/cmd/rpk-k8s/k8s/multicluster/checks/)

Pluggable check system with two interfaces (ClusterCheck, CrossClusterCheck) and a shared CheckContext that accumulates state as checks execute. Each check is a single file:

Per-cluster Cross-cluster
cluster_pod.go — operator pod health cross_cluster_unique_names.go — no duplicate node names
cluster_deployment.go — deployment config validation cross_cluster_peer_agreement.go — peer lists match
cluster_tls.go — CA/cert chain/expiry/key match cross_cluster_leader_agreement.go — leader consensus
cluster_raft.go — gRPC Status RPC via port-forward cross_cluster_ca_consistency.go — same CA everywhere
cluster_tls_san.go — SAN matches raft node name
cluster_deployment_raft.go — deploy flags vs raft

Operator-side Status RPC (pkg/multicluster/leaderelection/)

  • Added Status RPC to the gRPC transport proto, returning node name, raft state, leader, term, cluster names, unhealthy peers, and health status.
  • Raft state and term are tracked on the transport and updated on each Ready() cycle.
  • IDsToNames mapping passed through to the transport for human-readable peer names.

Reusable vcluster multicluster helper (pkg/vcluster/multicluster.go)

  • vcluster.Multicluster — creates N vclusters on a shared k3d cluster with cross-cluster service replication, TLS bootstrapping, and operator deployment.
  • MulticlusterNode exposes Ctl() (*kube.Ctl), APIServer(), ExternalIP(), and all vcluster.Cluster methods.
  • Uses PortForwardedRESTConfig so SPDY operations (port-forward, exec) work through the vcluster tunnel.

Build targets (taskfiles/build.yml)

  • task build:rpk-plugin — builds .build/.rpk.ac-k8s
  • task build:rpk-plugin:install — copies to ~/.local/bin/

@andrewstucki andrewstucki changed the title [WIP] Add rpk multicluster plugin wiring Add rpk multicluster plugin wiring Apr 10, 2026
@andrewstucki andrewstucki marked this pull request as ready for review April 10, 2026 14:26
@RafalKorepta
Copy link
Copy Markdown
Contributor

I'm still trying to reproduce a successful response in my environment from the rpk k8s multicluster status command.

NIT: Usage is added by cobra where the usage does not prefix command with the rpk. Maybe we could omit that to not confuse users.

rpk k8s multicluster bootstrap --help
Bootstrap TLS certificates and kubeconfig secrets across multiple
Kubernetes clusters for a Redpanda multicluster deployment.

This command connects to each specified Kubernetes context, generates a shared
CA certificate, and distributes per-cluster TLS certificates and kubeconfig
secrets so that the multicluster operator can communicate across clusters.

If --kubeconfig is provided, all contexts in the file are used automatically
and --context flags are not required. If both are provided, only the specified
contexts from the kubeconfig file are used.

Usage:
  k8s multicluster bootstrap [flags]

Examples:
  # Bootstrap all clusters from a kubeconfig file
  rpk k8s multicluster bootstrap \
    --kubeconfig /path/to/kubeconfig \
    --namespace redpanda --service-name redpanda-multicluster

  # Bootstrap specific contexts (uses default kubeconfig loading rules)
  rpk k8s multicluster bootstrap \
    --context cluster-a --context cluster-b --context cluster-c \
    --namespace redpanda --service-name redpanda-multicluster

  # Override DNS names for TLS SANs on specific clusters
  rpk k8s multicluster bootstrap \
    --context cluster-a --context cluster-b \
    --dns-override cluster-a=cluster-a.example.com \
    --dns-override cluster-b=cluster-b.example.com \
    --namespace redpanda --service-name redpanda-multicluster

  # Bootstrap only TLS certificates
  rpk k8s multicluster bootstrap \
    --kubeconfig /path/to/kubeconfig \
    --namespace redpanda --service-name redpanda-multicluster \
    --tls --kubeconfigs=false

Flags:
      --context strings            Kubernetes contexts (repeatable; if omitted with --kubeconfig, all contexts in the file are used)
      --create-namespace           Create the namespace if it does not exist (default true)
      --dns-override stringArray   DNS override for TLS SANs in context=address format (repeatable)
  -h, --help                       help for bootstrap
      --kubeconfig string          Path to a kubeconfig file (all contexts in the file are used unless --context is also specified)
      --kubeconfigs                Bootstrap kubeconfig secrets (default true)
      --namespace string           Namespace for operator resources (default "redpanda")
      --organization string        Organization name for generated TLS certificates (default "Redpanda")
      --service-name string        Service name for the multicluster operator (default "redpanda-multicluster")
      --tls                        Bootstrap TLS certificates (default true)

@andrewstucki andrewstucki merged commit fbb8308 into main Apr 14, 2026
11 checks passed
@andrewstucki andrewstucki deleted the as/rpk-plugin-wiring branch April 14, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants