BYO Addons is a simple Kubernetes operator project. It introduces a custom resource called AddonSet, where a platform engineer can define which cluster addons should exist, such as CNI and CSI providers.
In this version, the operator does not install real Helm charts automatically. Instead, it records the desired addon configuration as Kubernetes ConfigMap objects and updates AddonSet.status.
- Go
- Kubebuilder-style operator layout
- controller-runtime
- Kubernetes CRDs
- Kubernetes RBAC
- Kustomize
- Helm
- Docker
- Optional Argo CD GitOps examples
Kubernetes clusters usually need a few common platform addons before application workloads can run properly:
- π CNI for networking, for example Cilium
- πΎ CSI for storage, for example OpenEBS
Without a consistent process, every cluster can end up configured differently. This project creates a declarative contract called AddonSet, so a cluster owner can describe the expected addon stack in one YAML file.
In this version, the operator records that desired state and reports reconciliation status. A future version could use that recorded state to generate Argo CD Application resources or install Helm charts directly.
- Defines an
AddonSetCustom Resource Definition - Runs a controller manager inside Kubernetes
- Watches
AddonSetresources - Adds a finalizer so cleanup happens before deletion
- Creates one desired-state
ConfigMapper enabled addon component - Updates
AddonSet.statuswith desired and ready component counts - Provides Kustomize manifests for local/operator deployment
- Provides a Helm chart for packaged installation
- Provides optional Argo CD examples for GitOps-style installation
- It does not create a Kubernetes cluster
- It does not directly install Cilium or OpenEBS
- It does not generate Argo CD
Applicationresources fromAddonSet - It does not perform real health checks on CNI/CSI workloads
flowchart LR
User["User applies AddonSet YAML"] --> API["Kubernetes API Server"]
API --> Operator["BYO Addons Operator"]
Operator --> ConfigMaps["Desired-state ConfigMaps"]
Operator --> Status["AddonSet Status"]
Optional GitOps example:
flowchart LR
Git["Git repository"] --> Argo["Argo CD"]
Argo --> OperatorChart["Operator Helm chart"]
Argo --> AddonCharts["Cilium/OpenEBS Helm charts"]
This project follows the structure Kubebuilder creates for an operator:
api/ API type definitions
cmd/ controller manager entrypoint
internal/controller/ reconciliation logic
config/ CRD, RBAC, manager, and sample YAML
The equivalent starting commands are:
kubebuilder init --domain byoaddons.io --repo github.com/example/byo-addons
kubebuilder create api --group platform --version v1alpha1 --kind AddonSetKubebuilder gives:
- standard operator project structure
- API type files
- controller files
- CRD generation setup
- RBAC marker support
- manager bootstrap code
- Kustomize-based config layout
After scaffolding, the main work is editing the API type and controller logic.
Main file:
api/v1alpha1/addonset_types.go
This file defines the custom resource schema.
Important types:
AddonSetSpec: desired stateAddonComponent: one addon, such as Cilium or OpenEBSAddonSource: where the addon would come from, usually a Helm repo/chartAddonSetStatus: observed state written by the operatorAddonComponentStatus: status of each component
Important fields:
spec.clusterName: logical cluster name, for exampledev-kindspec.gitOpsEngine: custom project field, for exampleArgoCD,Flux, orNonespec.components: list of desired addons
spec.gitOpsEngine is not a Kubernetes built-in field. It is defined by this project to record which external GitOps engine is expected to apply addon manifests in a future or optional flow.
Kubebuilder/controller-gen generates:
config/crd/bases/platform.byoaddons.io_addonsets.yaml
This CRD teaches Kubernetes about:
apiVersion: platform.byoaddons.io/v1alpha1
kind: AddonSetAfter the CRD is installed, these commands work:
kubectl get addonsets
kubectl get asetaset works because the CRD defines it as a short name.
Main file:
cmd/main.go
This starts the operator process. It:
- creates the runtime scheme
- registers Kubernetes built-in APIs
- registers the
AddonSetAPI - creates the controller-runtime manager
- configures health/readiness probes
- configures the metrics endpoint
- enables leader election when requested
- registers the
AddonSetReconciler
Main file:
internal/controller/addonset_controller.go
Reconciliation flow:
- Kubernetes sends a request when an
AddonSetis created, updated, or deleted - The controller fetches the
AddonSet - If it is not being deleted, the controller adds a finalizer
- If it is being deleted, the controller deletes owned desired-state
ConfigMaps and removes the finalizer - The controller loops through
spec.components - Disabled components are skipped
- Enabled components are written into desired-state
ConfigMaps - The controller updates
AddonSet.status
This is idempotent, so running the same reconcile loop many times should lead to the same cluster state.
Sample file:
config/samples/platform_v1alpha1_addonset.yaml
It creates an AddonSet named:
baseline-oss
Meaning:
baseline: default starting addon setoss: open source software
The sample has two components:
cilium, typeCNIopenebs-localpv, typeCSI
For the Cilium component, the operator creates a ConfigMap named:
baseline-oss-cilium-desired
The ConfigMap contains:
addon.json: JSON version of the component specengine: value ofspec.gitOpsEngine, for exampleArgoCDcluster: value ofspec.clusterName, for exampledev-kind
This ConfigMap is a desired-state record. It says:
For cluster
dev-kind, this addon stack wants Cilium with these source and values.
It does not install Cilium.
The operator adds this finalizer:
addonset.platform.byoaddons.io/finalizer
A finalizer prevents Kubernetes from deleting the object immediately. It gives the controller time to clean up related resources.
In this project:
- User deletes the
AddonSet - Kubernetes marks it for deletion but keeps it because the finalizer exists
- The controller sees the deletion timestamp
- The controller deletes the desired-state ConfigMaps
- The controller removes the finalizer
- Kubernetes finishes deleting the
AddonSet
Kustomize is used for raw Kubernetes deployment manifests.
Main entrypoint:
config/default/kustomization.yaml
It includes:
config/crdfor installing theAddonSetCRDconfig/rbacfor creating the ServiceAccount, ClusterRole, and bindingsconfig/managerfor deploying the controller manager
Commands:
make installInstalls only the CRD.
make deployDeploys the full operator stack using Kustomize.
Helm packages the operator for configurable installation.
Chart path:
charts/byo-addons-operator/
Kubernetes can install raw YAML, so Helm is not mandatory. Helm is useful because users can change values without editing YAML directly:
- image repository
- image tag
- replica count
- resource requests and limits
- leader election
- whether to create a sample
AddonSet
Install with Helm:
helm upgrade --install byo-addons charts/byo-addons-operator \
--namespace byo-addons-system \
--create-namespaceArgo CD is optional in this simplified project.
Files:
gitops/argocd/
Purpose:
- show how the operator Helm chart could be installed from Git
- show how addon charts like Cilium and OpenEBS could be installed through GitOps
Important: the operator does not currently generate these Argo CD Application objects. They are examples.
App-of-apps means one root Argo CD Application points to a folder containing other Application YAML files. The root app creates and syncs the child apps.
brew install go kubectl kustomize helm kindOptional, only if you want to regenerate CRDs:
go install sigs.k8s.io/controller-tools/cmd/controller-gen@latestkind create cluster --name byo-addonsCheck access:
kubectl cluster-info
kubectl get nodesgo mod download
make test
make buildmake docker-build
kind load docker-image byo-addons-operator:0.1.0 --name byo-addonsIf you change the image name, use the same image in both commands.
make renderThis creates:
/tmp/byo-addons-kustomize.yaml
/tmp/byo-addons-helm.yaml
make installmake deployCheck the pod:
kubectl get pods -n byo-addons-systemkubectl apply -f config/samples/platform_v1alpha1_addonset.yamlkubectl get addonsets -n byo-addons-system
kubectl get addonset baseline-oss -n byo-addons-system -o yamlExpected idea:
DESIRED = 2
READY = 2
kubectl get configmaps -n kube-system -l platform.byoaddons.io/managed-by=byo-addons-operator
kubectl get configmaps -n openebs -l platform.byoaddons.io/managed-by=byo-addons-operatorView one:
kubectl get configmap baseline-oss-cilium-desired -n kube-system -o yamlkubectl delete -f config/samples/platform_v1alpha1_addonset.yaml
make undeploy
kind delete cluster --name byo-addons| File | Purpose |
|---|---|
api/v1alpha1/addonset_types.go |
Defines the AddonSet API: spec, components, source, status, validation markers |
api/v1alpha1/groupversion_info.go |
Registers API group platform.byoaddons.io/v1alpha1 |
api/v1alpha1/zz_generated.deepcopy.go |
Generated Kubernetes deep-copy code |
cmd/main.go |
Starts the controller manager |
internal/controller/addonset_controller.go |
Main reconcile loop |
config/crd/bases/platform.byoaddons.io_addonsets.yaml |
Generated CRD |
config/rbac/role.yaml |
Operator permissions |
config/manager/manager.yaml |
Operator Deployment and Service |
config/default/kustomization.yaml |
Main Kustomize deployment entrypoint |
config/samples/platform_v1alpha1_addonset.yaml |
Sample AddonSet |
charts/byo-addons-operator/ |
Helm chart for installing the operator |
gitops/argocd/ |
Optional GitOps examples |
addons/catalog/ |
Simple provider catalog examples for CNI and CSI |
| Command | Purpose |
|---|---|
make help |
Shows available commands |
make fmt |
Formats Go code |
make vet |
Runs Go static checks |
make test |
Runs format, vet, and tests |
make manifests |
Regenerates CRD/RBAC if controller-gen is installed |
make build |
Builds bin/manager |
make docker-build |
Builds the operator image |
make install |
Installs the CRD |
make deploy |
Deploys the operator using Kustomize |
make undeploy |
Removes the operator using Kustomize |
make helm-lint |
Validates the Helm chart |
make render |
Renders Kustomize and Helm YAML into /tmp |
- Generate Argo CD
Applicationresources fromAddonSet - Install Helm charts directly from
AddonSetusing the Helm SDK - Validate selected providers against the catalog
- Add real health checks for CNI/CSI resources
- Add e2e tests with a
kindcluster