Skip to main content

Project Structure

KubeZero follows a well-defined directory structure that promotes reusability, maintainability, and scalability. Understanding this structure is crucial for effectively using and extending the platform.

Overview

The KubeZero project is organized into layers of abstraction, from low-level reusable components to high-level deployment packages:

kubezero/
├── bootstrap/ # 🚀 One-time setup
├── controller/ # 🎛️ GitOps controllers
├── modules/ # 🧩 Reusable components
├── stacks/ # 📦 Environment compositions
├── packages/ # 🎁 Complete solutions
└── registry/ # 📋 Runtime state

Architectural Layers


Directory Breakdown

🚀 bootstrap/ - One-Time Setup

Purpose: Local K3d-based bootstrapper that initializes the entire KubeZero platform.

bootstrap/
├── k3d-bootstrap-cluster.yaml # K3d cluster configuration
├── kubezero-bootstrap-manifests.yaml # Initial manifests
├── kustomization.yaml # Bootstrap composition
└── README.md # Bootstrap instructions

Key Characteristics:

  • Disposable: Used once, then can be deleted
  • Self-contained: Everything needed to start the platform
  • Cloud-agnostic: Works on any machine with Docker

Think of it as: The ignition key that starts your entire platform

# Example: bootstrap/k3d-bootstrap-cluster.yaml
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: kubezero-bootstrap
servers: 1
agents: 2
ports:
- port: 80:80
nodeFilters: [loadbalancer]
- port: 443:443
nodeFilters: [loadbalancer]

🎛️ controller/ - GitOps Controllers

Purpose: Defines ArgoCD applications that manage the GitOps workflow.

controller/
├── kustomization.yaml
├── argo-cd/
│ ├── application.yaml # ArgoCD self-management
│ └── kustomization.yaml
├── crossplane/
│ ├── application.yaml # Infrastructure management
│ └── kustomization.yaml
└── namespace/
└── namespace.yaml # Required namespaces

Key Characteristics:

  • Contains only ArgoCD Applications: No actual workload manifests
  • Points to other directories: References registry/ or stacks/
  • GitOps entry points: Where the GitOps loop begins

Think of it as: The conductor's baton that orchestrates everything

# Example: controller/argo-cd/application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/kubezero/kubezero
targetRevision: HEAD
path: registry/management
destination:
server: https://kubernetes.default.svc
namespace: argocd

🧩 modules/ - Reusable Building Blocks

Purpose: Granular, self-contained components that can be used across different environments.

modules/
├── argo-cd/ # ArgoCD GitOps platform
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── values.yaml
├── cert-manager/ # Certificate management
│ ├── kustomization.yaml
│ ├── cluster-issuer.yaml
│ └── values.yaml
├── crossplane/
│ ├── controller/ # Crossplane controller
│ └── providers/ # Cloud provider configs
├── external-dns/ # DNS automation
├── external-secrets/ # Secrets management
├── ingress-nginx/ # Ingress controller
└── vcluster/ # Virtual clusters

Key Characteristics:

  • Self-contained: Each module can be deployed independently
  • Reusable: Used across multiple stacks and environments
  • Technology-focused: Each module represents a specific technology
  • No environment specifics: Generic configurations

Think of it as: LEGO blocks that you combine to build your platform

# Example: modules/cert-manager/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- namespace.yaml
- cluster-issuer.yaml

helmCharts:
- name: cert-manager
repo: https://charts.jetstack.io
version: v1.13.0
namespace: cert-manager
valuesFile: values.yaml

📦 stacks/ - Environment Compositions

Purpose: Combine multiple modules to create environment-specific configurations.

stacks/
├── k8s-essentials/ # Essential platform services
│ └── manifests/
│ └── kustomization.yaml # References multiple modules
├── virtual-cluster/ # vCluster configuration
│ └── manifests/
│ └── kustomization.yaml
├── eks-cluster/ # AWS EKS-specific stack
│ └── manifests/
│ └── kustomization.yaml
└── gke-cluster/ # GCP GKE-specific stack
└── manifests/
└── kustomization.yaml

Key Characteristics:

  • Environment-specific: Tailored for specific deployment scenarios
  • Aggregates modules: Combines multiple modules with customizations
  • Contains no raw manifests: Always references modules
  • Represents logical environments: Like "production platform" or "development setup"

Think of it as: Architectural blueprints that combine LEGO blocks into buildings

# Example: stacks/k8s-essentials/manifests/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../../modules/ingress-nginx
- ../../../modules/cert-manager
- ../../../modules/external-dns
- ../../../modules/external-secrets

patches:
- target:
kind: Service
name: ingress-nginx-controller
patch: |-
- op: replace
path: /spec/type
value: LoadBalancer

🎁 packages/ - Complete Solutions

Purpose: High-level bundles that group stacks for specific platforms, customers, or use cases.

packages/
├── README.md
├── aws-management/ # AWS management cluster
│ └── kustomization.yaml # References AWS-specific stacks
├── aws-worker/ # AWS worker cluster
│ └── kustomization.yaml
├── gcp-management/ # GCP management cluster
│ └── kustomization.yaml
├── virtual-management/ # Virtual cluster management
│ └── kustomization.yaml
└── virtual-worker/ # Virtual worker setup
└── kustomization.yaml

Key Characteristics:

  • Complete solutions: Everything needed for a specific use case
  • Customer/platform-specific: Tailored for specific scenarios
  • References stacks: Never contains raw manifests
  • Deployment units: What you actually deploy to production

Think of it as: Complete building projects that combine multiple blueprints

# Example: packages/aws-management/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../stacks/k8s-essentials/manifests
- ../../stacks/eks-cluster/manifests

patches:
- target:
kind: Deployment
name: crossplane-provider-aws
patch: |-
- op: add
path: /spec/template/metadata/annotations
value:
iam.amazonaws.com/role: arn:aws:iam::123456789:role/crossplane-aws

📋 registry/ - Runtime GitOps State

Purpose: Reflects what is actually deployed and tracked by ArgoCD in production.

registry/
└── management/ # Management cluster registry
├── _gitops.yaml # ArgoCD applications list
└── _kustomization.yaml # ArgoCD configuration

Key Characteristics:

  • Runtime state: What's actually running in production
  • ArgoCD-managed: Automatically updated by GitOps processes
  • Environment mapping: Maps logical environments to deployments
  • References only: Points to packages or stacks

Think of it as: The inventory system that tracks what's actually deployed

# Example: registry/management/_gitops.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: management-platform
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/kubezero/kubezero
targetRevision: HEAD
path: packages/aws-management
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true

Design Principles

1. 🔄 No Duplication (DRY Principle)

Don't do this:

stacks/management/manifests/argocd/
stacks/production/manifests/argocd/
stacks/staging/manifests/argocd/

Do this instead:

# In each stack's kustomization.yaml
resources:
- ../../../modules/argo-cd

2. 📚 Layered Abstraction

Each layer builds on the previous one:

  • Modules → Building blocks
  • Stacks → Combine modules for environments
  • Packages → Combine stacks for complete solutions
  • Registry → Track what's deployed

3. 🎯 Single Responsibility

Each directory has a clear, single purpose:

  • Bootstrap: Start the platform
  • Controller: Manage GitOps
  • Modules: Provide technology components
  • Stacks: Define environments
  • Packages: Deliver solutions
  • Registry: Track deployments

4. 🔌 Loose Coupling

Components can be:

  • Mixed and matched: Different combinations for different needs
  • Replaced independently: Swap out modules without affecting others
  • Extended easily: Add new modules or stacks without changing existing ones

Best Practices

Creating New Modules

# 1. Create module directory
mkdir -p modules/my-new-service

# 2. Add kustomization.yaml
cat > modules/my-new-service/kustomization.yaml <<EOF
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- namespace.yaml
- deployment.yaml
- service.yaml

commonLabels:
app.kubernetes.io/name: my-new-service
app.kubernetes.io/managed-by: kubezero
EOF

# 3. Add your Kubernetes manifests
# 4. Reference from stacks

Creating New Stacks

# 1. Create stack directory
mkdir -p stacks/my-environment/manifests

# 2. Add kustomization.yaml that references modules
cat > stacks/my-environment/manifests/kustomization.yaml <<EOF
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../../modules/ingress-nginx
- ../../../modules/my-new-service

patches:
# Environment-specific customizations
EOF

Creating New Packages

# 1. Create package directory
mkdir -p packages/my-platform

# 2. Add kustomization.yaml that references stacks
cat > packages/my-platform/kustomization.yaml <<EOF
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../stacks/k8s-essentials/manifests
- ../stacks/my-environment/manifests
EOF

Common Patterns

Module Customization in Stacks

# stacks/production/manifests/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../../modules/cert-manager

patches:
- target:
kind: ClusterIssuer
name: letsencrypt-prod
patch: |-
- op: replace
path: /spec/acme/email
value: [email protected]

Multi-Environment Stacks

# stacks/multi-env/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../../modules/my-app

# stacks/multi-env/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../base

patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/replicas
value: 5

Summary Table

DirectoryPurposeContainsThink of it as
bootstrap/One-time cluster initializationK3d config + initial manifestsIgnition key
controller/GitOps orchestrationArgoCD Applications onlyConductor's baton
modules/Reusable technology componentsHelm/Kustomize bundlesLEGO blocks
stacks/Environment-specific compositionsModule references + customizationsBlueprints
packages/Complete platform solutionsStack references + configBuilding projects
registry/Runtime deployment stateGitOps application definitionsInventory system

Next Steps

Understanding this structure is key to effectively using and extending KubeZero. Each layer serves a specific purpose and follows clear patterns that make the platform scalable and maintainable.