Why PostgreSQL is Not a Helm Subchart

This document explains the architectural decision behind using PostCreateHook Jobs for PostgreSQL installation instead of Helm subchart dependencies in KubeFlex.

Overview

PostgreSQL in KubeFlex is installed via a PostCreateHook Job mechanism rather than as a traditional Helm subchart dependency. This decision addresses several technical challenges and compatibility requirements.

Questions Addressed

This document answers the key questions raised in GitHub Issue #401:

  1. Why is PostgreSQL instantiated with a post-install hook Job rather than as a subchart?
  2. Why is instantiation of the PostgreSQL chart optional?
  3. Why does PostgreSQL get instantiated into a fixed namespace rather than the kubeflex chart’s namespace?

Technical Reasons

1. Helm Version Compatibility Issues

Problem: Older Helm versions (< 3.17.1) have a critical bug with conditional subchart dependencies.

# This configuration fails in older Helm versions
dependencies:
  - name: postgresql
    condition: postgresql.enabled
 
# values.yaml
postgresql:
  enabled: false  # Should disable PostgreSQL

What happens in old Helm:

  • Helm ignores the condition: postgresql.enabled field
  • Attempts to install PostgreSQL even when enabled: false
  • Installation fails due to missing required values
  • Referenced in Helm Issue #12637

Impact:

  • Users with Helm < 3.17.1 cannot install KubeFlex
  • Many enterprise environments still use older Helm versions
  • Would create a breaking change for existing users

2. OpenShift Platform Compatibility

Problem: OpenShift requires specific security context configurations that vary by platform.

# OpenShift requires conditional templating
 
postgresql:
  primary:
    securityContext:
      enabled: false
    containerSecurityContext:
      runAsUser: null
      runAsGroup: null
 
postgresql:
  primary:
    securityContext:
      runAsUser: 999
      runAsGroup: 999
 

Subchart Limitation:

  • Helm subchart values.yaml files do not support templating
  • Cannot conditionally set values based on platform detection
  • Would require users to manually configure all OpenShift-specific settings

Current Solution:

  • PostCreateHook templates support full Go templating
  • Automatic platform detection and configuration
  • Seamless OpenShift compatibility

3. Runtime Flexibility and Dynamic Configuration

Problem: Control planes need dynamic configuration based on runtime parameters.

# PostCreateHook supports dynamic variables
vars:
  Namespace: ""           # Generated at runtime
  ControlPlaneName: "" # Unique per control plane
  HookName: ""             # Template variable
  DATABASE_NAME: "-db" # Dynamic database naming

Subchart Limitation:

  • Static configuration
  • Values must be known at chart installation time
  • No per-control-plane customization

PostCreateHook Benefits:

  • Runtime variable substitution
  • Per-control-plane configuration
  • Dynamic resource naming

Functional Reasons

1. Optional Installation by Design

Why PostgreSQL is Optional:

  1. Multiple Backend Support: KubeFlex supports both shared and dedicated database backends

    spec:
      backend: shared     # Uses shared PostgreSQL
      # OR
      backend: dedicated  # Uses dedicated database per control plane
  2. External Database Integration: Users may want to use existing database infrastructure

    # Users can skip PostgreSQL and use external databases
    kflex create cp1 --type k8s  # No PostgreSQL hook
  3. Resource Optimization: Not all deployments need PostgreSQL

    • Development environments may use in-memory storage
    • Production may use managed database services
    • Testing scenarios may not require persistence
  4. Deployment Flexibility: Different control plane types have different requirements

    kflex create cp1 --type host      # No database needed
    kflex create cp2 --type k8s --postcreate-hook postgres  # Database needed

2. Namespace Isolation Strategy

Why PostgreSQL Uses Fixed Namespace:

  1. Control Plane Isolation: Each control plane gets its own namespace

    kflex-cp1/     # Control plane 1 resources
    kflex-cp2/     # Control plane 2 resources
    postgres/      # Shared PostgreSQL instance
  2. Resource Sharing: Multiple control planes can share PostgreSQL instance

    # Multiple control planes, one PostgreSQL
    spec:
      backend: shared  # All control planes use same PostgreSQL
  3. Lifecycle Management: PostgreSQL lifecycle independent of individual control planes

    • Control planes can be created/deleted without affecting shared database
    • Database upgrades don’t require control plane recreation
    • Backup and maintenance operations are centralized
  4. Security Boundaries: Clear separation between compute and data layers

    Control Plane Namespace: Application logic, API servers
    PostgreSQL Namespace:    Data persistence, database operations