diff --git a/charts/kubemirror/Chart.yaml b/charts/kubemirror/Chart.yaml index 6550b8a..99f851b 100644 --- a/charts/kubemirror/Chart.yaml +++ b/charts/kubemirror/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: kubemirror description: Kubernetes controller for mirroring resources across namespaces type: application -version: 0.9.22 -appVersion: "0.9.22" +version: 0.10.9 +appVersion: "0.10.9" keywords: - kubernetes - controller diff --git a/charts/kubemirror/README.md b/charts/kubemirror/README.md new file mode 100644 index 0000000..cd54edc --- /dev/null +++ b/charts/kubemirror/README.md @@ -0,0 +1,83 @@ +# kubemirror Helm chart + +Deploys the [kubemirror](https://github.com/lukaszraczylo/kubemirror) controller, +which mirrors Kubernetes resources (Secrets, ConfigMaps, and other types) across +namespaces. + +- Chart version: `0.1.0` +- App version: `0.1.0` +- Image: `ghcr.io/lukaszraczylo/kubemirror` + +## Install + +```bash +helm install kubemirror ./charts/kubemirror -n kubemirror --create-namespace +``` + +With a values override: + +```bash +helm install kubemirror ./charts/kubemirror -n kubemirror --create-namespace \ + -f my-values.yaml +``` + +## Uninstall + +```bash +helm uninstall kubemirror -n kubemirror +``` + +## What it creates + +A single-replica `Deployment`, a `ServiceAccount`, a cluster-scoped `ClusterRole` ++ `ClusterRoleBinding` (the controller watches resources across all namespaces), +and a `Service` exposing the metrics (`8080`) and health (`8081`) ports. The +container runs as non-root (uid `65532`) with a read-only root filesystem and all +Linux capabilities dropped. + +## Values + +Defaults are taken from [`values.yaml`](values.yaml). + +| Key | Default | Description | +| --- | --- | --- | +| `replicaCount` | `1` | Number of controller replicas. | +| `image.repository` | `ghcr.io/lukaszraczylo/kubemirror` | Controller image. | +| `image.tag` | `"0.1.0"` | Image tag (falls back to chart `appVersion` if empty). | +| `image.pullPolicy` | `IfNotPresent` | Image pull policy. | +| `serviceAccount.create` | `true` | Create a ServiceAccount. | +| `serviceAccount.name` | `""` | Override the generated ServiceAccount name. | +| `controller.metricsBindAddress` | `":8080"` | `--metrics-bind-address`. | +| `controller.healthProbeBindAddress` | `":8081"` | `--health-probe-bind-address`. | +| `controller.leaderElect` | `true` | Enable leader election (`--leader-elect`). | +| `controller.leaderElectionID` | `"kubemirror-controller-leader"` | Lease name (`--leader-election-id`). | +| `controller.resourceTypes` | `[]` | Resource types to mirror (`--resource-types`). Empty enables auto-discovery. | +| `controller.discoveryInterval` | `"5m"` | Auto-discovery interval (`--discovery-interval`). | +| `controller.resyncPeriod` | `"1h"` | Cache resync period, safety net only (`--resync-period`). | +| `controller.maxTargets` | `100` | Max target namespaces per resource (`--max-targets`). | +| `controller.workerThreads` | `5` | Concurrent reconcile workers (`--worker-threads`). | +| `controller.rateLimitQPS` | `50.0` | API QPS limit (`--rate-limit-qps`). | +| `controller.rateLimitBurst` | `100` | API burst limit (`--rate-limit-burst`). | +| `controller.verifySourceFreshness` | `false` | Verify cache against a direct API read (`--verify-source-freshness`). | +| `controller.lazyWatcherInit` | `false` | Only watch resource types actually in use (`--lazy-watcher-init`). Lowers memory; recommended for production. | +| `controller.watcherScanInterval` | `"5m"` | Scan interval for new types in lazy mode (`--watcher-scan-interval`). | +| `controller.excludedNamespaces` | `""` | Comma-separated namespaces never mirrored to (`--excluded-namespaces`). | +| `controller.includedNamespaces` | `""` | Comma-separated namespace patterns to include (`--included-namespaces`). | +| `service.type` | `ClusterIP` | Service type. | +| `service.metricsPort` | `8080` | Metrics port. | +| `service.healthPort` | `8081` | Health-probe port. | +| `resources.requests` | `100m` CPU / `128Mi` | Container requests. | +| `resources.limits` | `500m` CPU / `512Mi` | Container limits. | +| `nodeSelector` / `tolerations` / `affinity` | `{}` / `[]` / `{}` | Standard scheduling controls. | +| `priorityClassName` | `""` | Pod priority class. | + +> **Memory tip:** setting `controller.resourceTypes` to the exact types you mirror +> (e.g. `["Secret.v1", "ConfigMap.v1"]`), or enabling `controller.lazyWatcherInit`, +> avoids creating watchers for unused resource types and cuts memory use +> substantially versus full auto-discovery. + +## Usage + +After install, mark a source resource for mirroring and opt a target namespace +in. See the [project README](../../README.md) and [examples](../../examples/) for +the full annotation/label reference and worked scenarios. diff --git a/charts/kubemirror/templates/deployment.yaml b/charts/kubemirror/templates/deployment.yaml index b0f897f..704dc08 100644 --- a/charts/kubemirror/templates/deployment.yaml +++ b/charts/kubemirror/templates/deployment.yaml @@ -43,9 +43,7 @@ spec: - --worker-threads={{ .Values.controller.workerThreads }} - --rate-limit-qps={{ .Values.controller.rateLimitQPS }} - --rate-limit-burst={{ .Values.controller.rateLimitBurst }} - {{- if .Values.controller.verifySourceFreshness }} - - --verify-source-freshness=true - {{- end }} + - --verify-source-freshness={{ .Values.controller.verifySourceFreshness }} {{- if .Values.controller.lazyWatcherInit }} - --lazy-watcher-init=true {{- end }} diff --git a/charts/kubemirror/values.yaml b/charts/kubemirror/values.yaml index dd98715..f84db2a 100644 --- a/charts/kubemirror/values.yaml +++ b/charts/kubemirror/values.yaml @@ -3,7 +3,7 @@ replicaCount: 1 image: repository: ghcr.io/lukaszraczylo/kubemirror pullPolicy: IfNotPresent - tag: "0.9.22" + tag: "0.10.9" imagePullSecrets: [] nameOverride: "" @@ -54,10 +54,11 @@ controller: # How often to rediscover available resources in the cluster discoveryInterval: "5m" - # Cache resync period - how often to refresh all cached resources + # Cache resync period - safety net for missed watch events; mirror drift + # is repaired event-driven, so this can stay long # Higher values reduce memory churn and API load # Default: 10m (was 30s in earlier versions) - resyncPeriod: "10m" + resyncPeriod: "1h" # Resource limits maxTargets: 100 diff --git a/charts/packages/kubemirror-0.10.9.tgz b/charts/packages/kubemirror-0.10.9.tgz new file mode 100644 index 0000000..4b5695c Binary files /dev/null and b/charts/packages/kubemirror-0.10.9.tgz differ diff --git a/index.yaml b/index.yaml index eaf12c0..8b2d874 100644 --- a/index.yaml +++ b/index.yaml @@ -5304,6 +5304,28 @@ entries: - https://github.com/lukaszraczylo/helm-charts/releases/download/kube-images-sync-0.1.5/kube-images-sync-0.1.5.tgz version: 0.1.5 kubemirror: + - apiVersion: v2 + appVersion: 0.10.9 + created: "2026-10-02T03:28:58.862053405Z" + description: Kubernetes controller for mirroring resources across namespaces + digest: 330ccfb3dbfec1f25e2413368ad39394a860eddeeb61ccb80f7b30b7cfad4019 + home: https://github.com/lukaszraczylo/kubemirror + keywords: + - kubernetes + - controller + - mirror + - secrets + - configmaps + maintainers: + - email: lukasz@raczylo.com + name: Lukasz Raczylo + name: kubemirror + sources: + - https://github.com/lukaszraczylo/kubemirror + type: application + urls: + - https://github.com/lukaszraczylo/helm-charts/releases/download/kubemirror-0.10.9/kubemirror-0.10.9.tgz + version: 0.10.9 - apiVersion: v2 appVersion: 0.9.22 created: "2026-06-11T04:55:10.159104138Z" @@ -5986,4 +6008,4 @@ entries: urls: - https://github.com/lukaszraczylo/helm-charts/releases/download/kubemirror-0.2.8/kubemirror-0.2.8.tgz version: 0.2.8 -generated: "2026-10-02T03:14:57.94666578Z" +generated: "2026-10-02T03:28:58.861515958Z"