Helm Plugin (helm/v2-alpha)
The Helm plugin v2-alpha provides a way to package your project as a Helm chart, enabling distribution in Helm’s native format.
Instead of using static templates, this plugin dynamically generates Helm charts from your project’s kustomize output (via make build-installer).
It keeps your custom settings such as environment variables, labels, annotations, and security contexts.
This lets you deliver your Kubebuilder project in two ways:
- As a bundle (
dist/install.yaml) generated with kustomize - As a Helm chart that matches the same output
Why Helm?
By default, you can create a bundle of manifests with:
make build-installer IMG=<registry>/<project-name:tag>
Users can install it directly:
kubectl apply -f https://raw.githubusercontent.com/<org>/project-v4/<tag-or-branch>/dist/install.yaml
But many people prefer Helm for packaging, upgrades, and distribution.
The helm/v2-alpha plugin converts the bundle (dist/install.yaml) into a Helm chart that mirrors your project.
Key Features
- Dynamic Generation: Charts are built from real kustomize output, not boilerplate.
- Preserves Customizations: Keeps env vars, labels, annotations, and patches.
- Structured Output: Templates follow your
config/directory layout. - Smart Values:
values.yamlincludes only actual configurable parameters. - File Preservation:
Chart.yamlis never overwritten. Without--force,values.yaml,_helpers.tpl,.helmignore, and.github/workflows/test-chart.ymlare preserved. - Handles Custom Resources: Resources not matching standard layout (custom Services, ConfigMaps, etc.) are placed in
templates/extras/with proper templating.
When to Use It
Use the helm/v2-alpha plugin if:
- You want Helm charts that stay true to your kustomize setup
- You need charts that update with your project automatically
- You want a clean template layout similar to
config/ - You want to distribute your solution using either this format
Usage
Basic Workflow
# Create a new project
kubebuilder init
# Build the installer bundle
make build-installer IMG=<registry>/<project:tag>
# Create Helm chart from kustomize output
kubebuilder edit --plugins=helm/v2-alpha
# Regenerate preserved files (Chart.yaml never overwritten)
kubebuilder edit --plugins=helm/v2-alpha --force
Advanced Options
# Use a custom manifests file
kubebuilder edit --plugins=helm/v2-alpha --manifests=manifests/custom-install.yaml
# Write chart to a custom output directory
kubebuilder edit --plugins=helm/v2-alpha --output-dir=charts
# Combine manifests and output
kubebuilder edit --plugins=helm/v2-alpha \
--manifests=manifests/install.yaml \
--output-dir=helm-charts
Chart Structure
The plugin creates a chart layout that matches your config/:
<output-dir>/chart/
├── Chart.yaml
├── values.yaml
└── templates/
├── _helpers.tpl
├── rbac/ # Individual RBAC files (examples)
│ ├── controller-manager.yaml
│ ├── leader-election-role.yaml
│ ├── leader-election-rolebinding.yaml
│ ├── manager-role.yaml
│ ├── manager-rolebinding.yaml
│ ├── metrics-auth-role.yaml
│ ├── metrics-auth-rolebinding.yaml
│ ├── metrics-reader.yaml
│ ├── memcached-admin-role.yaml
│ ├── memcached-editor-role.yaml
│ ├── memcached-viewer-role.yaml
│ ├── busybox-admin-role.yaml
│ ├── busybox-editor-role.yaml
│ ├── busybox-viewer-role.yaml
│ └── ...
├── crd/ # Individual CRD files (examples)
│ ├── busyboxes.example.com.testproject.org.yaml
│ └── ...
├── cert-manager/
│ ├── metrics-certs.yaml
│ ├── selfsigned-issuer.yaml
│ └── serving-cert.yaml
├── manager/
│ └── manager.yaml
├── metrics/
│ └── controller-manager-metrics-service.yaml
├── webhook/
│ ├── validating-webhook-configuration.yaml
│ └── webhook-service.yaml
├── monitoring/
│ └── servicemonitor.yaml
└── extras/ # Custom resources (if any)
├── my-service.yaml
└── my-config.yaml
Values Configuration
The generated values.yaml provides configuration options extracted from your actual deployment.
Namespace creation is not managed by the chart; use Helm’s --namespace and --create-namespace flags when installing.
Example
## String to partially override chart.fullname template (will maintain the release name)
##
# nameOverride: ""
## String to fully override chart.fullname template
##
# fullnameOverride: ""
## Configure the controller manager deployment
##
manager:
replicas: 1
image:
repository: controller
tag: latest
pullPolicy: IfNotPresent
## Arguments
##
args:
- --leader-elect
## Environment variables
##
env:
- name: BUSYBOX_IMAGE
value: busybox:1.36.1
- name: MEMCACHED_IMAGE
value: memcached:1.6.26-alpine3.19
## Image pull secrets
##
imagePullSecrets: []
# Example:
# imagePullSecrets:
# - name: myregistrykey
## Pod-level security settings
##
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Container-level security settings
##
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
## Resource limits and requests
##
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
## Manager pod's affinity
##
affinity: {}
# Example:
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: kubernetes.io/arch
# operator: In
# values:
# - amd64
# - arm64
## Manager pod's node selector
##
nodeSelector: {}
# Example:
# nodeSelector:
# kubernetes.io/os: linux
# disktype: ssd
## Manager pod's tolerations
##
tolerations: []
# Example:
# tolerations:
# - key: "node.kubernetes.io/unreachable"
# operator: "Exists"
# effect: "NoExecute"
# tolerationSeconds: 6000
## Helper RBAC roles for managing custom resources
##
rbacHelpers:
# Install convenience admin/editor/viewer roles for CRDs
enable: false
## Custom Resource Definitions
##
crd:
# Install CRDs with the chart
enable: true
# Keep CRDs when uninstalling
keep: true
## Controller metrics endpoint.
## Enable to expose /metrics endpoint with RBAC protection.
##
metrics:
enable: true
# Metrics server port
port: 8443
## Cert-manager integration for TLS certificates.
## Required for webhook certificates and metrics endpoint certificates.
##
certManager:
enable: true
## Webhook server configuration
##
webhook:
enable: true
# Webhook server port
port: 9443
## Prometheus ServiceMonitor for metrics scraping.
## Requires prometheus-operator to be installed in the cluster.
##
prometheus:
enable: false
Installation
Install the chart into a namespace using Helm flags (the chart does not create namespaces):
helm install my-release ./dist/chart \
--namespace my-project-system \
--create-namespace
Flags
| Flag | Description |
|---|---|
| –manifests | Path to YAML file containing Kubernetes manifests (default: dist/install.yaml) |
| –output-dir string | Output directory for chart (default: dist) |
| –force | Regenerates preserved files except Chart.yaml (values.yaml, _helpers.tpl, .helmignore, test-chart.yml) |