Lesson 2.2: Kubebuilder Fundamentals

Introduction

Kubebuilder is a framework for building Kubernetes operators using the controller-runtime library. It provides scaffolding, code generation, and best practices to make operator development easier. In this lesson, you’ll learn how Kubebuilder works and its architecture.

Theory: Kubebuilder Framework

Kubebuilder is a SDK and framework that simplifies operator development by providing code generation, project scaffolding, and best practices.

Core Concepts

Code Generation:

  • Generates boilerplate code (CRDs, controllers, RBAC)
  • Reduces manual coding and errors
  • Ensures consistency with Kubernetes patterns

Project Structure:

  • Standardized layout for operator projects
  • Separates API definitions from controller logic
  • Makes projects maintainable and scalable

Controller-Runtime Integration:

  • Built on controller-runtime (same library Kubernetes uses)
  • Provides Manager, Reconciler, Client abstractions
  • Handles caching, watching, and leader election

Why Kubebuilder:

  • Productivity: Generates boilerplate, focuses on business logic
  • Best Practices: Enforces Kubernetes patterns
  • Community: Widely used, well-documented
  • Tooling: Rich CLI for common tasks

Understanding Kubebuilder helps you build operators efficiently and correctly.

What is Kubebuilder?

Kubebuilder is:

  • A SDK for building operators in Go
  • A scaffolding tool that generates project structure
  • A code generator for CRDs and controllers
  • Built on controller-runtime (the library used by Kubernetes itself)
graph TB
    subgraph "Kubebuilder"
        KB[Kubebuilder CLI]
        SCAFFOLD[Scaffolding]
        GENERATE[Code Generation]
        RUNTIME[controller-runtime]
    end
    
    subgraph "Your Operator"
        CRD[CRD]
        CONTROLLER[Controller]
        MANAGER[Manager]
    end
    
    KB --> SCAFFOLD
    KB --> GENERATE
    SCAFFOLD --> CRD
    GENERATE --> CONTROLLER
    CONTROLLER --> MANAGER
    MANAGER --> RUNTIME
    
    style KB fill:#FFB6C1
    style RUNTIME fill:#90EE90

Kubebuilder Architecture

Kubebuilder uses controller-runtime, the same library that powers Kubernetes controllers:

graph LR
    subgraph "Kubebuilder Project"
        API[API Types]
        CONTROLLER[Controller]
        MAIN[main.go]
    end
    
    subgraph "controller-runtime"
        MANAGER[Manager]
        CLIENT[Client]
        CACHE[Cache]
    end
    
    subgraph "Kubernetes"
        API_SERVER[API Server]
    end
    
    API --> CONTROLLER
    CONTROLLER --> MANAGER
    MANAGER --> CLIENT
    MANAGER --> CACHE
    CLIENT --> API_SERVER
    CACHE --> API_SERVER
    
    style MANAGER fill:#FFB6C1
    style CLIENT fill:#90EE90

Kubebuilder Project Structure

When you scaffold a project, Kubebuilder creates this structure:

graph TB
    ROOT[Project Root] --> API[api/]
    ROOT --> CONTROLLERS[internal/controller/]
    ROOT --> CONFIG[config/]
    ROOT --> MAIN[main.go]
    
    API --> V1[v1/]
    V1 --> TYPES[types.go]
    V1 --> GROUPVERSION[groupversion_info.go]
    
    CONTROLLERS --> RECONCILE[reconcile.go]
    
    CONFIG --> CRD[crds/]
    CONFIG --> RBAC[rbac/]
    CONFIG --> MANAGER[manager/]
    
    style API fill:#90EE90
    style CONTROLLERS fill:#FFB6C1

Key Directories

  • api/: Your API definitions (CRD types)
  • internal/controller/: Your controller logic
  • config/: Kubernetes manifests (CRDs, RBAC, etc.)
  • main.go: Entry point that sets up the manager

Code Generation Flow

Kubebuilder uses markers (comments) to generate code:

sequenceDiagram
    participant Dev as Developer
    participant Code as Source Code
    participant Markers as Markers
    participant KB as Kubebuilder
    participant Gen as Generated Code
    
    Dev->>Code: Write types with markers
    Code->>Markers: // +kubebuilder:...
    Dev->>KB: Run kubebuilder generate
    KB->>Markers: Read markers
    KB->>Gen: Generate CRD YAML
    KB->>Gen: Generate RBAC manifests
    KB->>Gen: Generate deepcopy methods
    Gen->>Dev: Ready to use

Common Markers

  • // +kubebuilder:object:root=true - Marks root type
  • // +kubebuilder:subresource:status - Enables status subresource
  • // +kubebuilder:resource:path=... - Defines resource path
  • // +kubebuilder:validation:... - Adds validation rules

Kubebuilder CLI Commands

Kubebuilder provides several commands:

kubebuilder init

Initializes a new project:

  • Creates project structure
  • Sets up Go modules
  • Configures Makefile
  • Sets up controller-runtime

kubebuilder create api

Creates a new API (CRD):

  • Generates API types
  • Creates controller skeleton
  • Generates CRD manifests
  • Sets up RBAC

kubebuilder create webhook

Creates webhooks:

  • Validating webhooks
  • Mutating webhooks
  • Certificate management

make generate

Generates code:

  • CRD manifests
  • Deep copy methods
  • Client code

make manifests

Generates manifests:

  • CRD YAML files
  • RBAC manifests
  • Webhook configurations

Kubebuilder vs Operator SDK

graph LR
    subgraph "Kubebuilder"
        KB[Kubebuilder]
        KB --> GO[Go Only]
        KB --> SIMPLE[Simpler]
        KB --> NATIVE[Native K8s]
    end
    
    subgraph "Operator SDK"
        SDK[Operator SDK]
        SDK --> MULTI[Multi-Language]
        SDK --> FEATURES[More Features]
        SDK --> OLM[OLM Support]
    end
    
    style KB fill:#90EE90
    style SDK fill:#FFE4B5

Kubebuilder:

  • Go-only
  • Simpler, more focused
  • Native Kubernetes patterns
  • Used by Kubernetes project itself
  • Better for learning

Operator SDK:

  • Multiple languages (Go, Ansible, Helm)
  • More features (OLM, scorecard)
  • Larger ecosystem
  • More complex

For this course: We use Kubebuilder because it’s simpler, follows Kubernetes patterns closely, and is excellent for learning.

Understanding Generated Code

When Kubebuilder generates code, it creates:

  1. API Types (api/v1/):
    • Your Custom Resource Go structs
    • Spec and Status definitions
    • Deep copy methods
  2. Controller (internal/controller/):
    • Reconciler struct
    • Reconcile function skeleton
    • Setup with manager
  3. Manifests (config/):
    • CRD YAML files
    • RBAC rules
    • Manager deployment

Key Takeaways

  • Kubebuilder is a framework for building operators in Go
  • Uses controller-runtime (same as Kubernetes)
  • Provides scaffolding and code generation
  • Project structure is standardized and organized
  • Uses markers (comments) to generate code
  • Simpler than Operator SDK, better for learning

Understanding for Building Operators

When using Kubebuilder:

  • You’ll define API types with markers
  • Kubebuilder generates CRDs automatically
  • You’ll implement the Reconcile function
  • Kubebuilder handles the boilerplate
  • You focus on business logic

References

Official Documentation

Further Reading

  • Kubebuilder Book - Official comprehensive guide
  • Programming Kubernetes by Michael Hausenblas and Stefan Schimanski - Chapter 4: Working with Client Libraries
  • Kubebuilder GitHub - Source code and examples

Next Steps

Now that you understand Kubebuilder, let’s set up your development environment and create your first operator!