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: admin@mycompany.com

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.