Skip to content

Project Structure

Reference documentation for the memcached-operator project scaffold, following the Operator SDK / Kubebuilder go.kubebuilder.io/v4 layout conventions.

Directory Layout

text
memcached-operator/
├── api/
│   ├── v1alpha1/
│   │   ├── groupversion_info.go       # API group registration (memcached.c5c3.io/v1alpha1)
│   │   ├── memcached_types.go         # CRD type definitions (Memcached, MemcachedList)
│   │   └── zz_generated.deepcopy.go   # Generated DeepCopy methods (do not edit)
│   └── v1beta1/                       # Storage version (primary API)
│       ├── groupversion_info.go       # API group registration (memcached.c5c3.io/v1beta1)
│       ├── memcached_types.go         # CRD type definitions (Memcached, MemcachedList)
│       ├── memcached_conversion.go    # Hub conversion marker (v1beta1 is the hub)
│       ├── memcached_webhook.go       # Defaulting webhook
│       ├── memcached_validation_webhook.go # Validation webhook
│       └── zz_generated.deepcopy.go   # Generated DeepCopy methods (do not edit)
├── cmd/
│   └── main.go                        # Operator entry point, manager bootstrap
├── config/
│   ├── crd/
│   │   ├── bases/                     # Generated CRD YAML manifests
│   │   └── kustomization.yaml
│   ├── default/
│   │   ├── kustomization.yaml         # Aggregates crd + rbac + manager
│   │   └── manager_metrics_patch.yaml # Metrics endpoint configuration
│   ├── manager/
│   │   ├── manager.yaml               # Controller manager Deployment
│   │   └── kustomization.yaml
│   ├── prometheus/
│   │   ├── monitor.yaml               # ServiceMonitor template
│   │   └── kustomization.yaml
│   ├── rbac/
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── role.yaml                  # Generated ClusterRole from RBAC markers
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   └── samples/
│       ├── memcached_v1alpha1_memcached.yaml  # Example Memcached CR
│       └── kustomization.yaml
├── hack/
│   └── boilerplate.go.txt             # License header for generated files
├── internal/
│   └── controller/
│       ├── memcached_controller.go       # Reconciler implementation
│       ├── memcached_controller_test.go  # Controller integration tests
│       └── suite_test.go                 # envtest bootstrap (Ginkgo/Gomega)
├── bin/                               # Tool binaries and compiled output (gitignored)
├── .golangci.yml                      # Linter configuration
├── Dockerfile                         # Multi-stage container build
├── Makefile                           # Development workflow targets
├── PROJECT                            # Operator SDK project metadata
├── go.mod                             # Go module definition
└── go.sum                             # Dependency checksums

Key Files

PROJECT

Operator SDK project metadata file declaring:

FieldValue
Domainc5c3.io
Layoutgo.kubebuilder.io/v4
Project Namememcached-operator
Repogithub.com/c5c3/memcached-operator
API Groupmemcached.c5c3.io
API Versionsv1alpha1, v1beta1 (storage)
KindMemcached
CRD Versionv1
ScopeNamespaced

api/v1beta1/ (primary)

CRD type definitions for the memcached.c5c3.io/v1beta1 API group — the storage version and hub for multi-version conversion:

  • groupversion_info.go - Declares GroupVersion, SchemeBuilder, and AddToScheme for scheme registration.
  • memcached_types.go - Defines MemcachedSpec, MemcachedStatus, Memcached, and MemcachedList with kubebuilder markers (+kubebuilder:object:root=true, +kubebuilder:subresource:status, +kubebuilder:storageversion).
  • memcached_conversion.go - Implements the conversion.Hub interface, marking v1beta1 as the hub type for spoke (v1alpha1) conversion.
  • memcached_webhook.go - Defaulting webhook that sets field defaults on create/update.
  • memcached_validation_webhook.go - Validation webhook that enforces CRD constraints.
  • zz_generated.deepcopy.go - Auto-generated by make generate. Implements runtime.Object interface via DeepCopyObject().

api/v1alpha1/ (spoke)

Legacy CRD type definitions for the memcached.c5c3.io/v1alpha1 API group. Retained for backward compatibility — resources submitted as v1alpha1 are automatically converted to v1beta1 via the conversion webhook:

  • groupversion_info.go - Declares GroupVersion, SchemeBuilder, and AddToScheme for scheme registration.
  • memcached_types.go - Defines MemcachedSpec, MemcachedStatus, Memcached, and MemcachedList. Schema is identical to v1beta1.
  • zz_generated.deepcopy.go - Auto-generated by make generate. Implements runtime.Object interface via DeepCopyObject().

cmd/main.go

Operator entry point that:

  1. Registers clientgoscheme, memcached/v1alpha1 (for conversion support), and memcached/v1beta1 on the runtime scheme
  2. Parses CLI flags for metrics address (:8443), health probe address (:8081), leader election, and secure metrics
  3. Creates a controller-runtime Manager with leader election ID d4f3c8a2.c5c3.io
  4. Wires the MemcachedReconciler via SetupWithManager
  5. Registers /healthz and /readyz probe endpoints
  6. Starts the manager with OS signal handling

internal/controller/

  • memcached_controller.go - MemcachedReconciler struct embedding client.Client with a Scheme field. Includes RBAC markers for memcacheds (full CRUD), status, and finalizers. SetupWithManager registers watches for v1beta1.Memcached CRs. The Reconcile method fetches and reconciles v1beta1.Memcached resources.
  • suite_test.go - Ginkgo/Gomega test suite bootstrapping envtest with CRD paths pointing to config/crd/bases/. Creates a test client with the v1beta1 scheme registered.
  • memcached_controller_test.go - Integration tests validating CR creation, reconciler setup, and reconcile behavior.

config/

Kustomize-based deployment configuration following Kubebuilder v4 conventions:

DirectoryPurpose
config/crd/CRD manifests generated by controller-gen
config/rbac/ServiceAccount, ClusterRole, ClusterRoleBinding, leader election RBAC
config/manager/Controller manager Deployment manifest
config/default/Aggregation overlay referencing crd + rbac + manager
config/samples/Example Memcached CR for testing
config/prometheus/ServiceMonitor template for Prometheus integration

Dockerfile

Multi-stage build:

  • Builder stage: golang:1.25 with CGO_ENABLED=0, TARGETOS/TARGETARCH build args for cross-platform support
  • Runtime stage: gcr.io/distroless/static:nonroot running as UID 65532

Makefile Targets

Development

TargetDescription
manifestsGenerate CRD YAML (config/crd/bases/) and RBAC (config/rbac/) via controller-gen
generateGenerate DeepCopy methods in zz_generated.deepcopy.go
fmtRun go fmt ./...
vetRun go vet ./...
testRun envtest-based integration tests with coverage (depends on manifests, generate, fmt, vet)
test-e2eRun end-to-end tests against a real cluster
lintRun golangci-lint
lint-fixRun golangci-lint with --fix

Build

TargetDescription
buildCompile manager binary to bin/manager (depends on manifests, generate, fmt, vet)
runRun controller locally from host
docker-buildBuild container image tagged as ${IMG}
docker-pushPush container image to registry
docker-buildxBuild and push multi-platform image (linux/amd64, linux/arm64)

Deployment

TargetDescription
installInstall CRDs into cluster via kustomize build config/crd
uninstallRemove CRDs from cluster
deployDeploy controller manager with RBAC to cluster via kustomize build config/default
undeployRemove controller manager from cluster

Tool Dependencies

Tools are auto-downloaded to bin/ on first use via Makefile targets:

ToolVersionPurpose
controller-genv0.17.2CRD/RBAC manifest and DeepCopy generation
kustomizev5.6.0Kubernetes manifest composition
setup-envtestrelease-0.20Download envtest API server binaries
golangci-lintv2.10.1Go linter aggregator

Go Module

FieldValue
Module pathgithub.com/c5c3/memcached-operator
Go version1.25
controller-runtimev0.23.1
k8s.io/apimachineryv0.35.1
k8s.io/client-gov0.35.0
Ginkgov2.27.2
Gomegav1.38.2

Conventions

This project follows the Kubebuilder v4 / Operator SDK conventions:

  • Entry point in cmd/main.go (not project root)
  • API types in api/<version>/ with kubebuilder markers for code generation
  • Controller logic in internal/controller/ (unexported, internal to the module)
  • RBAC generated from //+kubebuilder:rbac markers on the reconciler
  • CRDs generated from struct tags and //+kubebuilder:validation markers on types
  • Secure metrics via controller-runtime's built-in authentication (no kube-rbac-proxy sidecar)
  • envtest for integration testing against an in-memory API server and etcd
  • Ginkgo/Gomega as the BDD test framework