Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.yaml includes only actual configurable parameters.
  • File Preservation: Chart.yaml is never overwritten. Without --force, values.yaml, _helpers.tpl, .helmignore, and .github/workflows/test-chart.yml are 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

FlagDescription
–manifestsPath to YAML file containing Kubernetes manifests (default: dist/install.yaml)
–output-dir stringOutput directory for chart (default: dist)
–forceRegenerates preserved files except Chart.yaml (values.yaml, _helpers.tpl, .helmignore, test-chart.yml)