Operator Framework vs. Kubebuilder: What Is the Difference?
Kubebuilder is a Go framework for building Kubernetes controllers and Operators. The Operator SDK (part of the Operator Framework) wraps Kubebuilder and adds support for Ansible and Helm-based Operators, plus OLM integration for lifecycle management.
Detailed Answer
The Kubernetes Operator ecosystem has two primary frameworks for building Operators: Kubebuilder and the Operator SDK (part of the Operator Framework). Understanding how they relate helps you choose the right tool for your project.
The Relationship
controller-runtime (Go library)
↑
Kubebuilder (Go scaffolding framework)
↑
Operator SDK (wraps Kubebuilder + adds Helm/Ansible + OLM)
Both Kubebuilder and Operator SDK use controller-runtime under the hood. Operator SDK actually embeds Kubebuilder's scaffolding and extends it.
Feature Comparison
| Feature | Kubebuilder | Operator SDK |
|---------|------------|--------------|
| Go-based Operators | Yes | Yes (uses Kubebuilder) |
| Helm-based Operators | No | Yes |
| Ansible-based Operators | No | Yes |
| CRD generation | Yes | Yes |
| RBAC scaffolding | Yes | Yes |
| Testing framework | envtest | envtest + scorecard |
| OLM integration | Manual | Built-in |
| Bundle/catalog generation | No | Yes |
| Project scaffolding | kubebuilder init | operator-sdk init |
| Maintained by | Kubernetes SIG | Operator Framework (Red Hat) |
Kubebuilder
Kubebuilder is the standard Go framework maintained by Kubernetes SIG API Machinery:
# Initialize project
kubebuilder init --domain example.com --repo github.com/myorg/operator
# Create API
kubebuilder create api --group cache --version v1 --kind Redis
# Generate manifests
make manifests
# Run locally
make run
# Deploy
make deploy IMG=myorg/operator:v1
Kubebuilder generates a clean, idiomatic Go project that uses controller-runtime directly.
Operator SDK (Go Type)
The Operator SDK's Go type is essentially Kubebuilder with extra features:
# Initialize project (same flags as Kubebuilder)
operator-sdk init --domain example.com --repo github.com/myorg/operator
# Create API (same as Kubebuilder)
operator-sdk create api --group cache --version v1 --kind Redis
# Additional features:
# Generate OLM bundle
make bundle
# Run scorecard tests
operator-sdk scorecard ./bundle
# Create catalog for OLM
operator-sdk run bundle myorg/operator-bundle:v1
Operator SDK (Helm Type)
For teams that want an Operator without writing Go — just wrap an existing Helm chart:
# Scaffold a Helm-based Operator
operator-sdk init --plugins helm --domain example.com
# Create API from a Helm chart
operator-sdk create api \
--helm-chart=bitnami/redis \
--helm-chart-version=17.0.0 \
--group cache --version v1 --kind Redis
This generates an Operator that:
- Creates a
RedisCRD - Maps CRD spec fields to Helm values
- Runs
helm install/upgrade/deletein response to CR changes
# Users create this CR instead of running helm install
apiVersion: cache.example.com/v1
kind: Redis
metadata:
name: my-redis
spec:
# These map directly to Helm values
architecture: replication
replica:
replicaCount: 3
auth:
enabled: true
Operator SDK (Ansible Type)
For teams with Ansible expertise:
operator-sdk init --plugins ansible --domain example.com
operator-sdk create api --group cache --version v1 --kind Redis
This generates an Operator that runs Ansible playbooks/roles when CRs are created, updated, or deleted:
# watches.yaml — maps CRDs to Ansible roles
- version: v1
group: cache.example.com
kind: Redis
role: redis
reconcilePeriod: 30s
# roles/redis/tasks/main.yml
- name: Create Redis Deployment
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ ansible_operator_meta.name }}-redis"
namespace: "{{ ansible_operator_meta.namespace }}"
spec:
replicas: "{{ replicas | default(1) }}"
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: "redis:{{ redis_version | default('7') }}"
OLM (Operator Lifecycle Manager)
OLM manages Operators like a package manager:
# Install OLM
operator-sdk olm install
# Create an OLM bundle
make bundle IMG=myorg/operator:v1
# Build and push the bundle image
make bundle-build bundle-push BUNDLE_IMG=myorg/operator-bundle:v1
# Deploy via OLM
operator-sdk run bundle myorg/operator-bundle:v1
OLM provides:
- CatalogSource: A repository of available Operators
- Subscription: Automatic updates for installed Operators
- InstallPlan: Approval workflow for Operator installations
- CSV (ClusterServiceVersion): Rich metadata about the Operator
Decision Matrix
| Scenario | Recommended Tool | |----------|-----------------| | Full-featured Go Operator with custom logic | Kubebuilder | | Go Operator with OLM distribution | Operator SDK (Go) | | Wrap an existing Helm chart as an Operator | Operator SDK (Helm) | | Team knows Ansible, not Go | Operator SDK (Ansible) | | Simple CRUD Operator | Operator SDK (Helm) | | Complex stateful application management | Kubebuilder or Operator SDK (Go) | | Enterprise distribution via OperatorHub | Operator SDK (any type) + OLM |
Migration Between Frameworks
Since both frameworks use controller-runtime, migration is straightforward:
# Kubebuilder → Operator SDK: re-scaffold and copy controller code
operator-sdk init --domain example.com --repo github.com/myorg/operator
# Copy api/ and internal/controller/ directories
# Operator SDK → Kubebuilder: re-scaffold and copy controller code
kubebuilder init --domain example.com --repo github.com/myorg/operator
# Copy api/ and internal/controller/ directories
Best Practices
- Choose Go for complex Operators — Helm and Ansible types are limited in what they can reconcile
- Start with Kubebuilder if you do not need OLM or Helm/Ansible support
- Use Operator SDK if you plan to publish on OperatorHub.io
- Test with scorecard (Operator SDK) for conformance validation
- Consider Helm Operators for Day 1 tasks and graduate to Go for Day 2 operations
- Do not over-engineer — if a Helm chart suffices, use a Helm Operator rather than writing Go
Why Interviewers Ask This
Teams starting an Operator project need to choose a framework. This question tests your understanding of the ecosystem and ability to make practical tooling decisions.
Common Follow-Up Questions
Key Takeaways
- Kubebuilder is the foundation — both Kubebuilder and Operator SDK use controller-runtime under the hood.
- Operator SDK adds Helm and Ansible Operator types for teams that do not write Go.
- OLM is a separate component for managing Operator installations and upgrades in production.