Help us shape the future of Go! Take the 2026 Go Developer Survey

berth

module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: MIT

README

Berth

Distributed lease coordination for Kubernetes multi-cluster workloads.

Berth gives multiple clusters one shared lease surface so only the intended holder runs a coordinated workload. It ships an HTTPS API server, a Kubernetes operator for BerthLease custom resources, a small CLI scaffold, and an OIDC token-broker sidecar for operator authentication.

Components

Component Purpose
apiserver HTTPS lease API backed by in-memory state, Kubernetes Lease objects in a coordination cluster, or a SQL database.
operator Controller that reconciles BerthLease resources and applies suspend or scale actions to target workloads.
berth CLI entrypoint. Lease commands currently exist as stubs while the Go client is the supported direct-integration path.
berth-oidc-broker Sidecar that fetches OIDC client-credentials tokens and writes them to a file consumed by the operator.

Quickstart

Choose a topology first:

Topology Backend When to use it
Cross-cluster coordination plane k8s One central Berth API server coordinates workloads across multiple tenant clusters.
Runner-local HA sql with Postgres or MariaDB Berth runs inside the runner cluster and stores lease state in an external SQL database.
Runner-local edge/dev sql with SQLite, or mem Single API server replica only. SQLite persists locally; mem is ephemeral.

Install the API server in a coordination cluster with the Kubernetes Lease backend:

helm install berth-apiserver deploy/helm/berth-apiserver \
  --namespace berth-system --create-namespace \
  --set store.backend=k8s \
  --set coordination.namespace=berth-coordination \
  --set coordination.inCluster=true \
  --set tls.certManager.enabled=true \
  --set tls.certManager.issuerRef.name=berth-ca \
  --set tls.certManager.issuerRef.kind=ClusterIssuer \
  --set auth.mode=static-keys \
  --set auth.staticKeys.secretName=berth-api-keys

For a runner-local SQL deployment, store the DSN in a Kubernetes Secret and let the chart mount it as the --sql-dsn-file input:

kubectl -n berth-system create secret generic berth-sql-dsn \
  --from-literal=dsn='postgres://berth:secret@postgres.berth.svc:5432/berth?sslmode=require'

helm install berth-apiserver deploy/helm/berth-apiserver \
  --namespace berth-system --create-namespace \
  --set store.backend=sql \
  --set store.sql.driver=postgres \
  --set store.sql.dsnSecret.name=berth-sql-dsn \
  --set tls.certManager.enabled=true \
  --set tls.certManager.issuerRef.name=berth-ca \
  --set tls.certManager.issuerRef.kind=ClusterIssuer \
  --set auth.mode=static-keys \
  --set auth.staticKeys.secretName=berth-api-keys

Install the operator in each tenant cluster with a distinct cluster identity:

helm install berth-operator deploy/helm/berth-operator \
  --namespace berth-system --create-namespace \
  --set clusterID=cluster-east \
  --set berth.apiServer=https://berth.example.com:8443 \
  --set berth.apiKey.secretName=berth-api-key \
  --set berth.tls.caBundleConfigMap=berth-ca-bundle \
  --set workloadManagement.enabled=true \
  --set injection.webhook.tls.certManager.enabled=true \
  --set injection.webhook.tls.certManager.issuerRef.name=berth-ca \
  --set injection.webhook.tls.certManager.issuerRef.kind=ClusterIssuer

The API key's tenant must own the operator's clusterID. With static-keys auth the caller's tenant is the key id, and lease requests are holder-authorized: the operator's holder is its clusterID, so that value must equal the key id or be scoped under "<key-id>/", or every acquire is rejected 403. Give each cluster its own key with key id equal to its clusterID (cluster-east, cluster-west, …) — distinct tenants contending for the same lease name is the intended cross-cluster model. See Authorization.

Managed targets require the fail-closed admission installation above. The issuer must exist in each runner cluster. For an existing TLS Secret or an upgrade, follow operator workload cleanup. Create each BerthLease before creating its target; existing targets must be drained and recreated. Use an application namespace, outside berth-system. Lease-only use can leave workloadManagement.enabled false.

Apply the same BerthLease manifest to each cluster:

apiVersion: berth.skaphos.io/v1alpha1
kind: BerthLease
metadata:
  name: ingest-worker
  namespace: pipeline
spec:
  leaseName: ingest-worker
  holderIdentity: fallback-holder
  ttlSeconds: 30
  heartbeatIntervalSeconds: 10
  semantics: at-most-once
  target:
    apiVersion: apps/v1
    kind: Deployment
    name: ingest-worker
  acquireAction:
    scale:
      replicas: 3
  releaseAction:
    scale:
      replicas: 0

Only the cluster whose operator holds the central lease scales the target Deployment up. Standby clusters keep their target scaled down and retry acquisition on the configured heartbeat cadence.

Documentation

Development

Requires Go 1.27.1+. Task is declared as a Go tool in tools/go.mod, so no separate Task installation is required.

go -C tools tool task --list
go -C tools tool task build
go -C tools tool task test
go -C tools tool task lint
go -C tools tool task verify-generated

SQL integration tests are DSN-driven so they can point at databases exposed from a local kind topology:

BERTH_TEST_POSTGRES_DSN='postgres://berth:secret@127.0.0.1:5432/berth?sslmode=disable' \
BERTH_TEST_MYSQL_DSN='berth:secret@tcp(127.0.0.1:3306)/berth?parseTime=true' \
go -C tools tool task test-integration

Unset DSNs skip the corresponding driver tests.

License

MIT. See LICENSE and LICENSES/MIT.txt.


Skaphos is a project of Rillan AI LLC, a Missouri limited liability company. © 2026 Rillan AI LLC. Released under the MIT License.

Directories

Path Synopsis
api
v1alpha1
Package v1alpha1 defines the Kubernetes custom resource types for the Berth lease coordination API.
Package v1alpha1 defines the Kubernetes custom resource types for the Berth lease coordination API.
cmd
apiserver command
berth command
berth-acquire command
Command berth-acquire is the injected lease helper.
Command berth-acquire is the injected lease helper.
berth-oidc-broker command
Command berth-oidc-broker is a small reference token broker for the Berth operator.
Command berth-oidc-broker is a small reference token broker for the Berth operator.
operator command
internal
acquire
Package acquire implements the berth-acquire helper: a small binary injected into workload pods (via the SKA-439 mutating webhook) that gates pod startup on a Berth lease and, in runtime-singleton mode, keeps the lease renewed and enforces at-most-once by stopping the main container when the lease is lost.
Package acquire implements the berth-acquire helper: a small binary injected into workload pods (via the SKA-439 mutating webhook) that gates pod startup on a Berth lease and, in runtime-singleton mode, keeps the lease renewed and enforces at-most-once by stopping the main container when the lease is lost.
api
Package api provides the HTTP server and routing for the Berth API server.
Package api provides the HTTP server and routing for the Berth API server.
auth
Package auth provides authentication primitives for the Berth API server.
Package auth provides authentication primitives for the Berth API server.
clientauth
Package clientauth holds the auth and TLS plumbing shared by Berth components that talk to the central API server as clients: the operator, and the injected berth-acquire helper.
Package clientauth holds the auth and TLS plumbing shared by Berth components that talk to the central API server as clients: the operator, and the injected berth-acquire helper.
console
Package console provides the web console server for Berth.
Package console provides the web console server for Berth.
k8s
Package k8s provides Kubernetes client initialization for Berth components.
Package k8s provides Kubernetes client initialization for Berth components.
lease
Package lease implements Berth's lease coordination semantics.
Package lease implements Berth's lease coordination semantics.
lease/sqlstore
Package sqlstore implements lease.Store with database/sql.
Package sqlstore implements lease.Store with database/sql.
load
Package load is the engine behind the Berth API-level load driver (test/load).
Package load is the engine behind the Berth API-level load driver (test/load).
metrics
Package metrics holds the Prometheus instrumentation for the Berth API server: RED metrics on the HTTP lease handlers and latency on the backing lease.Store calls.
Package metrics holds the Prometheus instrumentation for the Berth API server: RED metrics on the HTTP lease handlers and latency on the backing lease.Store calls.
operator
Package operator implements the Kubernetes controller for Berth lease resources.
Package operator implements the Kubernetes controller for Berth lease resources.
tenant
Package tenant provides tenant resolution for multi-tenant Berth deployments.
Package tenant provides tenant resolution for multi-tenant Berth deployments.
webhook
Package webhook implements the mutating admission webhook that injects the berth-acquire helper into opt-in workload pods (SKA-439).
Package webhook implements the mutating admission webhook that injects the berth-acquire helper into opt-in workload pods (SKA-439).
pkg
client
Package client provides a Go client library for the Berth API server.
Package client provides a Go client library for the Berth API server.
test
load command
Command berth-load is the API-level load driver for Berth (scalability Phase 3).
Command berth-load is the API-level load driver for Berth (scalability Phase 3).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL