Skip to main content

Namespace Architecture

This document describes the namespace strategy used in the Open Service Portal platform, particularly for Crossplane resources and GitOps workflows.

Overview

The platform uses a hierarchical namespace structure to separate infrastructure resources from application workloads, providing clear boundaries for multi-tenancy and resource management.

Namespace Types

1. System Namespace (system)

Purpose: Dedicated namespace for infrastructure-level Crossplane Composite Resources (XRs)

Created by: scripts/cluster-config.sh

Label: purpose=infrastructure-xrs

Contains:

  • ManagedNamespace XRs (creates other namespaces)
  • Cluster-wide infrastructure XRs
  • Resources that affect multiple namespaces

Example:

apiVersion: openportal.dev/v1alpha1
kind: ManagedNamespace
metadata:
name: team-frontend
namespace: system # Always in system namespace
spec:
name: team-frontend

2. Platform Namespaces

These namespaces contain platform components:

  • crossplane-system: Crossplane control plane and providers
  • flux-system: Flux GitOps controllers
  • external-dns: DNS management via External-DNS
  • ingress-nginx: Ingress controller
  • default: Backstage service account and basic resources

3. Application Namespaces

Created dynamically via ManagedNamespace XRs, these contain:

  • Application deployments
  • Service-specific XRs
  • ConfigMaps and Secrets
  • Application-level resources

Naming Convention:

  • Team-based: team-<name> (e.g., team-frontend, team-backend)
  • Environment-based: <app>-<env> (e.g., api-staging, api-production)
  • Service-based: svc-<name> (e.g., svc-auth, svc-payments)

4. Demo Namespace (demo)

Purpose: Testing and demonstration of platform capabilities

Created by: scripts/cluster-config.sh

Contains:

  • Example applications (WhoAmI service)
  • Test XRs for validation
  • Development experiments

Crossplane v2 Architecture

Why Namespaced XRs?

In Crossplane v2, we moved from cluster-scoped to namespaced XRs for several reasons:

  1. API Server Cache Consistency: Eliminates cache inconsistencies between XRD definitions and API server expectations
  2. Better RBAC: Namespace-scoped resources allow finer-grained access control
  3. Multi-tenancy: Teams can manage their own XRs without cluster-wide permissions
  4. GitOps Compatibility: Flux handles namespaced resources more reliably with server-side apply

XR Placement Strategy

catalog-orders/
├── <cluster>/
│ ├── system/ # Infrastructure XRs
│ │ └── ManagedNamespace/ # Namespace management
│ │ └── *.yaml
│ └── <namespace>/ # Application XRs
│ └── <Kind>/
│ └── *.yaml

Rules:

  1. Infrastructure XRs → system namespace
  2. Application XRs → Their respective application namespace
  3. No XRs in platform namespaces (crossplane-system, flux-system, etc.)

ManagedNamespace Pattern

The ManagedNamespace XRD provides controlled namespace creation with:

Features

  • Automatic namespace creation
  • Standardized labels and annotations
  • Network policies (optional)
  • Resource quotas (optional)
  • RBAC setup (optional)

Usage

apiVersion: openportal.dev/v1alpha1
kind: ManagedNamespace
metadata:
name: team-frontend
namespace: system # Always in system namespace
spec:
name: team-frontend
labels:
team: frontend
environment: development
resourceQuota:
enabled: true
limits:
cpu: "10"
memory: "20Gi"

Composition Details

The ManagedNamespace composition creates:

  1. The actual Kubernetes namespace
  2. Default network policies (if configured)
  3. Resource quotas (if specified)
  4. RBAC roles and bindings (if needed)

GitOps Workflow

Flux Configuration

Flux watches two repositories with different namespace strategies:

  1. catalog/ - Template definitions

    apiVersion: kustomize.toolkit.fluxcd.io/v1
    kind: Kustomization
    metadata:
    name: catalog
    namespace: flux-system
    spec:
    path: ./templates
    targetNamespace: crossplane-system # Templates go to Crossplane
  2. catalog-orders/ - XR instances

    apiVersion: kustomize.toolkit.fluxcd.io/v1
    kind: Kustomization
    metadata:
    name: catalog-orders
    namespace: flux-system
    spec:
    path: ./<cluster>
    prune: true # Clean up removed XRs
    # No targetNamespace - uses namespace from each XR's metadata

Server-Side Apply

Flux uses server-side apply for XRs, which requires:

  • Correct namespace in metadata
  • Proper scope in XRD (Namespaced vs Cluster)
  • Valid API group and version

Best Practices

1. Namespace Naming

  • Use descriptive, hierarchical names
  • Include purpose in the name (team-, svc-, env-)
  • Avoid generic names like "test" or "temp"

2. Resource Isolation

  • Keep platform components in dedicated namespaces
  • Don't mix infrastructure and application resources
  • Use network policies for inter-namespace communication

3. Label Standards

All namespaces should have:

labels:
managed-by: crossplane
purpose: <infrastructure|application|demo>
team: <team-name>
environment: <dev|staging|prod>

4. Quota Management

Set appropriate resource quotas:

  • Development: Lower limits
  • Staging: Production-like limits
  • Production: Monitored limits with alerts

5. RBAC Strategy

  • Platform team: Access to system and platform namespaces
  • Development teams: Access to their team namespaces
  • CI/CD: Limited access for deployments
  • Backstage: Service account with XR creation permissions

Troubleshooting

Common Issues

  1. "namespace not specified" error from Flux

    • Ensure XR has namespace: system in metadata
    • Verify XRD scope is Namespaced
  2. XR not created after Git push

    • Check Flux logs: kubectl logs -n flux-system deploy/kustomize-controller
    • Verify path in Kustomization matches cluster name
    • Ensure proper directory structure in catalog-orders
  3. Cannot delete namespace

    • Check for finalizers on the ManagedNamespace XR
    • Ensure all resources in namespace are deleted
    • Verify Crossplane provider has permissions

Debugging Commands

# Check system namespace
kubectl get ns system -o yaml

# List all ManagedNamespace XRs
kubectl get managednamespaces.openportal.dev -n system

# Check Flux reconciliation
flux get kustomizations

# View Crossplane composition status
kubectl get compositions managednamespaces -o wide

# Check XRD scope
kubectl get xrd managednamespaces.openportal.dev -o jsonpath='{.spec.scope}'

Future Enhancements

Planned Features

  1. Namespace Templates: Pre-configured namespace types (web-app, api-service, database)
  2. Automatic Cleanup: TTL for demo/development namespaces
  3. Cost Attribution: Namespace-level cost tracking
  4. Security Policies: OPA/Gatekeeper policies per namespace type
  5. Observability: Automatic Prometheus/Grafana dashboard creation

Under Consideration

  • Hierarchical namespaces (HNC) for sub-namespace management
  • Virtual clusters (vcluster) for stronger isolation
  • Namespace-as-a-Service API for self-service provisioning

References