Skip to content

Commit bffe2da

Browse files
committed
wire in production setup/deployments
1 parent 62e4074 commit bffe2da

19 files changed

Lines changed: 1352 additions & 8 deletions

v2/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ build:
1616
konnector:
1717
cd konnector && go build -o bin/konnector ./cmd/konnector
1818

19+
# Container image. Build context is v2/ so the konnector's `replace ../sdk` resolves.
20+
IMAGE ?= ghcr.io/kube-bind/konnector:dev
21+
.PHONY: image
22+
image:
23+
docker build -f konnector/Dockerfile -t $(IMAGE) .
24+
25+
CHART ?= konnector/deploy/charts/konnector
26+
.PHONY: helm-lint
27+
helm-lint:
28+
helm lint $(CHART)
29+
30+
# Render the chart to stdout for review (extra flags via HELM_ARGS=...).
31+
.PHONY: helm-template
32+
helm-template:
33+
helm template konnector $(CHART) -n kube-bind $(HELM_ARGS)
34+
35+
# Refresh the chart's bundled CRDs from the generated sdk CRDs.
36+
.PHONY: helm-sync-crds
37+
helm-sync-crds: codegen
38+
cp sdk/config/crd/core.kube-bind.io_*.yaml $(CHART)/files/crds/
39+
1940
.PHONY: codegen
2041
codegen:
2142
cd sdk && $(CONTROLLER_GEN) object paths=./apis/...

v2/README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,43 @@ v2/
8484

8585
Known POC simplifications (tracked against the proposal): OpenAPI synthesis is
8686
best-effort (fidelity limits above); the `Mapper` seam exists but only `Identity`
87-
ships and `relatedResources` are not yet routed through it; and productionization
88-
(RBAC/HA/Helm) remains.
87+
ships and `relatedResources` are not yet routed through it.
8988

9089
## Build
9190

9291
```sh
9392
cd v2/konnector && go build ./... # workspace mode (go.work)
9493
```
9594

95+
## Deploy
96+
97+
The konnector runs in (or against) the **consumer** cluster — it is the only
98+
running component of the core (no backend, no provider-side controllers).
99+
100+
```sh
101+
cd v2
102+
make image IMAGE=ghcr.io/kube-bind/konnector:dev # build the image
103+
helm install konnector konnector/deploy/charts/konnector \
104+
-n kube-bind --create-namespace \
105+
--set image.repository=ghcr.io/kube-bind/konnector --set image.tag=dev
106+
```
107+
108+
The chart ([konnector/deploy/charts/konnector](konnector/deploy/charts/konnector))
109+
ships the core CRDs (`installCRDs`, default on), a `ServiceAccount`, the consumer
110+
RBAC (`ClusterRole`/`ClusterRoleBinding` + a namespaced leader-election `Role`),
111+
and the `Deployment` with liveness/readiness probes. Notable values:
112+
113+
- `replicaCount` / `leaderElect` — HA. Leader election gates all consumer-side
114+
controllers, so standby replicas engage no providers until they win the lease.
115+
It is forced on automatically when `replicaCount > 1`.
116+
- `rbac.boundResourceGroups` (default `["*"]`) — the API groups the konnector may
117+
sync. The bound APIs are open-ended, so this defaults to all groups; narrow it
118+
to the specific groups your providers export to shrink the blast radius.
119+
120+
Provider credentials are governed by the kubeconfig in each `Connection`'s
121+
Secret, **not** the konnector's ServiceAccount — the RBAC above is consumer-side
122+
only.
123+
96124
## Codegen (after editing types)
97125

98126
```sh

v2/konnector/Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2026 The Kube Bind Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# v2 slim-core konnector image.
16+
#
17+
# Build context is the v2/ directory (the konnector module's `replace
18+
# github.com/kube-bind/kube-bind/v2/sdk => ../sdk` needs the sibling sdk module):
19+
#
20+
# docker build -f konnector/Dockerfile -t kube-bind/konnector:dev .
21+
#
22+
# from inside v2/.
23+
FROM golang:1.26.2 AS builder
24+
WORKDIR /workspace
25+
26+
ARG TARGETARCH
27+
ARG TARGETOS
28+
ARG LDFLAGS
29+
30+
# Both modules are needed: konnector requires sdk via a local replace. Build
31+
# standalone (GOWORK=off) so the image does not depend on the go.work file.
32+
COPY sdk/ sdk/
33+
COPY konnector/ konnector/
34+
35+
WORKDIR /workspace/konnector
36+
ENV GOWORK=off
37+
RUN go mod download
38+
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
39+
go build -ldflags="${LDFLAGS}" -o /bin/konnector ./cmd/konnector
40+
41+
FROM gcr.io/distroless/static:nonroot
42+
COPY --from=builder /bin/konnector /bin/konnector
43+
USER 65532:65532
44+
ENTRYPOINT ["/bin/konnector"]

v2/konnector/cmd/konnector/main.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"k8s.io/apimachinery/pkg/runtime"
3131
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
3232
ctrl "sigs.k8s.io/controller-runtime"
33+
"sigs.k8s.io/controller-runtime/pkg/healthz"
3334
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3435
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
3536
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
@@ -49,21 +50,34 @@ func init() {
4950
utilRuntimeMust(corev1alpha1.AddToScheme(scheme))
5051
}
5152

53+
// options holds the konnector's runtime flags.
54+
type options struct {
55+
metricsAddr string
56+
probeAddr string
57+
leaderElect bool
58+
leaderElectionID string
59+
}
60+
5261
func main() {
53-
var metricsAddr string
54-
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8085", "address the metric endpoint binds to")
62+
var o options
63+
flag.StringVar(&o.metricsAddr, "metrics-bind-address", ":8085", "address the metric endpoint binds to")
64+
flag.StringVar(&o.probeAddr, "health-probe-bind-address", ":8081", "address the health/readiness probe endpoint binds to")
65+
flag.BoolVar(&o.leaderElect, "leader-elect", false,
66+
"enable leader election, ensuring only one active konnector replica (required for HA / multiple replicas)")
67+
flag.StringVar(&o.leaderElectionID, "leader-election-id", "konnector.kube-bind.io",
68+
"name of the Lease used for leader election")
5569
opts := zap.Options{Development: true}
5670
opts.BindFlags(flag.CommandLine)
5771
flag.Parse()
5872
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
5973

60-
if err := run(metricsAddr); err != nil {
74+
if err := run(o); err != nil {
6175
ctrl.Log.Error(err, "konnector exited with error")
6276
os.Exit(1)
6377
}
6478
}
6579

66-
func run(metricsAddr string) error {
80+
func run(o options) error {
6781
ctx := ctrl.SetupSignalHandler()
6882
log := ctrl.Log.WithName("konnector")
6983

@@ -73,13 +87,25 @@ func run(metricsAddr string) error {
7387
}
7488

7589
// Local (consumer) manager: owns the core CRDs and the consumer-side caches.
90+
// Leader election gates all consumer-side controllers, so standby replicas
91+
// engage no provider clusters and run no syncers until they win the lease.
7692
localMgr, err := ctrl.NewManager(cfg, ctrl.Options{
77-
Scheme: scheme,
78-
Metrics: metricsserver.Options{BindAddress: metricsAddr},
93+
Scheme: scheme,
94+
Metrics: metricsserver.Options{BindAddress: o.metricsAddr},
95+
HealthProbeBindAddress: o.probeAddr,
96+
LeaderElection: o.leaderElect,
97+
LeaderElectionID: o.leaderElectionID,
98+
LeaderElectionReleaseOnCancel: true,
7999
})
80100
if err != nil {
81101
return err
82102
}
103+
if err := localMgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
104+
return err
105+
}
106+
if err := localMgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
107+
return err
108+
}
83109

84110
// Connection provider: each ready Connection becomes an engaged provider cluster.
85111
connProvider, err := provider.New(localMgr, provider.Options{})
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Patterns to ignore when building Helm packages.
2+
.DS_Store
3+
.git/
4+
.gitignore
5+
*.tmpl
6+
*.gotmpl
7+
.idea/
8+
*.tgz
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: v2
2+
name: konnector
3+
description: kube-bind v2 slim-core konnector — the consumer-side sync engine.
4+
type: application
5+
6+
# version / appVersion are placeholders bumped by the release tooling.
7+
version: 0.0.0
8+
appVersion: "0.0.0"
9+
10+
home: https://kube-bind.io
11+
sources:
12+
- https://github.com/kube-bind/kube-bind
13+
keywords:
14+
- kube-bind
15+
- multicluster
16+
- api-binding

0 commit comments

Comments
 (0)