Init Jobs — Platform Bootstrap¶
Overview¶
AKKO uses a set of Kubernetes Jobs to bootstrap the platform on every helm install or helm upgrade. These jobs create PostgreSQL schemas, S3 buckets, Polaris Iceberg catalogs, Keycloak OAuth clients, Superset dashboards, and AI functions. All jobs are idempotent — they can run repeatedly without side effects.
The init jobs are packaged in the akko-init sub-chart and replace the need for manual setup steps after deployment.
Architecture¶
helm install / upgrade
|
v
+------------------+
| akko-init chart |
+--------+---------+
|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | | | | |
v v v v v v v v v
postgres postgres minio polaris keycloak keycloak superset ai bootstrap
-init -data -init -init -clients -sync -bootstrap func -admin
-init
Jobs¶
| Job | Purpose | Depends On |
|---|---|---|
| postgres-init | Creates infrastructure databases (keycloak, airflow, superset, polaris, openmetadata, mlflow, jupyterhub) and extensions | PostgreSQL (infra) |
| postgres-data-init | Creates functional databases (banking, healthcare, geospatial, rag) with PostGIS + pgvector extensions and seed data | PostgreSQL (data) |
| minio-init | Creates S3 buckets (akko-warehouse, akko-production, akko-projects, akko-shared, akko-users) and access policies | object storage |
| polaris-init | Creates the akko-warehouse Iceberg catalog and namespaces (banking, healthcare, retail, telecom, manufacturing, raw, staging, analytics) |
Apache Polaris |
| keycloak-clients | Configures OAuth2 redirect URIs for all services behind oauth2-proxy, using wildcard domain patterns | Keycloak |
| keycloak-sync | Synchronizes LDAP users from directory service into Keycloak (when directory service is enabled) | Keycloak, directory service |
| superset-bootstrap | Creates datasets, charts, and the demo dashboard in Superset via the API | Superset, Trino |
| ai-functions | Installs PL/Python AI functions in PostgreSQL Data (LLM-powered SQL functions) | PostgreSQL (data), LiteLLM |
| bootstrap-admin | Creates the initial admin user and assigns RBAC roles | Keycloak |
Idempotency¶
Every job uses CREATE ... IF NOT EXISTS, PUT (not POST), or equivalent patterns. This means:
- First install: everything is created from scratch
- Subsequent upgrades: existing resources are left untouched, only missing resources are created
- No data loss: jobs never
DROPorDELETEexisting data
-- Example: postgres-init ensure.sql
CREATE DATABASE keycloak WITH OWNER = akko_admin;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE SCHEMA IF NOT EXISTS banking;
Configuration¶
Enabling / Disabling Jobs¶
Each job can be individually toggled:
akko-init:
polaris:
enabled: true
minio:
enabled: true
ollama:
enabled: true
superset:
enabled: true
keycloak:
enabled: true
aiFunctions:
enabled: true
keycloakClients:
enabled: true
Polaris Namespaces¶
The Polaris init job creates namespaces for data organization:
akko-init:
polaris:
catalog:
name: akko-warehouse
namespaces:
- banking
- healthcare
- retail
- telecom
- manufacturing
- raw
- staging
- analytics
object storage Buckets¶
akko-init:
minio:
buckets:
- akko-warehouse
- akko-production
- akko-projects
- akko-shared
- akko-users
Backup CronJobs¶
The init chart also includes optional backup CronJobs for PostgreSQL and object storage:
akko-init:
backup:
postgres:
enabled: false # Enable in production
schedule: "0 2 * * *" # 2 AM daily
retention: 7 # Keep 7 backups
minio:
enabled: false
schedule: "0 4 * * *"
retention: 7
Helm Chart¶
helm/akko/charts/akko-init/
├── Chart.yaml
├── values.yaml
├── files/ # SQL scripts, config files
└── templates/
├── _helpers.tpl
├── postgres-init-job.yaml
├── postgres-ensure-configmap.yaml
├── postgres-data-init-job.yaml
├── postgres-data-ensure-configmap.yaml
├── minio-init-job.yaml
├── polaris-init-job.yaml
├── keycloak-clients-job.yaml
├── keycloak-sync-job.yaml
├── superset-bootstrap-job.yaml
├── ai-functions-job.yaml
├── bootstrap-admin-job.yaml
├── backup-postgres-cronjob.yaml
├── backup-minio-cronjob.yaml
├── backup-pvc.yaml
└── serviceaccount.yaml
Resource Usage¶
Init jobs are ephemeral and lightweight:
Jobs run to completion and are cleaned up by Kubernetes after success (ttlSecondsAfterFinished).
Troubleshooting¶
Job Failed — Pod in Error State¶
Symptoms: A job pod shows Error or BackoffLimitExceeded. The platform is partially initialized.
Cause: The target service (PostgreSQL, object storage, Keycloak, etc.) was not ready when the job ran. Network policies or secrets may be misconfigured.
Solution:
# Check which jobs failed
kubectl get jobs -n akko -l app.kubernetes.io/instance=akko | grep -v "1/1"
# View logs of the failed job
kubectl logs -n akko job/<job-name> --tail=50
# Re-run a specific job by deleting it (Helm will recreate on next upgrade)
kubectl delete job -n akko <job-name>
helm upgrade akko helm/akko/ -n akko -f helm/examples/values-dev.yaml
PostgreSQL Init: Permission Denied¶
Symptoms: The postgres-init job fails with permission denied or role does not exist.
Cause: The PostgreSQL superuser credentials in the Helm secret do not match what is configured in the PostgreSQL pod.
Solution:
# Check the init job logs
kubectl logs -n akko job/akko-postgres-init --tail=30
# Verify the secret matches the PostgreSQL config
kubectl get secret -n akko akko-postgresql -o jsonpath='{.data.postgres-password}' | base64 -d
# If credentials changed, the PostgreSQL volume retains the old password
# You may need to ALTER USER inside the running PostgreSQL pod
kubectl exec -n akko deploy/akko-postgresql -- psql -U postgres -c "ALTER USER akko_admin WITH PASSWORD 'newpassword';"
object storage Init: Bucket Already Exists¶
This is normal and expected. The object storage init job uses mc mb --ignore-existing, so pre-existing buckets are silently skipped.
Polaris Init: Catalog Creation Failed¶
Symptoms: The polaris-init job fails with HTTP 500 or connection refused.
Cause: Polaris may still be initializing its database schema. The job needs Polaris to be fully ready.
Solution:
# Check Polaris readiness
kubectl get pods -n akko -l app.kubernetes.io/name=akko-polaris
# View polaris-init logs
kubectl logs -n akko job/akko-polaris-init --tail=30
# Re-run the job
kubectl delete job -n akko akko-polaris-init
helm upgrade akko helm/akko/ -n akko -f helm/examples/values-dev.yaml
License¶
All init job code is part of the AKKO platform: Apache 2.0.