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:
- Why is PostgreSQL instantiated with a post-install hook Job rather than as a subchart?
- Why is instantiation of the PostgreSQL chart optional?
- 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.enabledfield - 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.yamlfiles 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:
-
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 -
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 -
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
-
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:
-
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 -
Resource Sharing: Multiple control planes can share PostgreSQL instance
# Multiple control planes, one PostgreSQL spec: backend: shared # All control planes use same PostgreSQL -
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
-
Security Boundaries: Clear separation between compute and data layers
Control Plane Namespace: Application logic, API servers PostgreSQL Namespace: Data persistence, database operations