Skip to content

Deploy on Kubernetes

This page walks through deploying KMI on Kubernetes with Helm. Complete the prerequisites first.

  1. Extract the package.

    Terminal window
    tar -xzf kmi-airgap-kubernetes-vX.x-amd64.tar.gz
    cd kmi-airgap-kubernetes-vX.x-amd64
  2. Create the configuration file.

    Copy the Kubernetes-specific example configuration and edit it:

    Terminal window
    cp .env-k8s.example .env

    Open .env in your preferred editor and configure all required values.

  3. Configure the container registry.

    Add your container registry details to .env:

    Terminal window
    # =============================================================================
    # CONTAINER REGISTRY CONFIGURATION
    # =============================================================================
    # Supported: ECR, GCR, ACR, Docker Hub, Harbor, Nexus, JFrog, GitLab, Quay
    REGISTRY_URL=your-registry-url
    IMAGE_TAG=your-image-tag
    IMAGE_PULL_SECRET=your-pull-secret # Required for Docker Hub, Harbor, Nexus, JFrog
  4. Configure a secret manager (recommended) or set secrets in .env.

    For production deployments, a cloud secret manager is recommended for storing sensitive values (passwords, keys, tokens). If not configured, the deployment script falls back to reading sensitive values directly from the .env file.

    Terminal window
    # =============================================================================
    # SECRET MANAGER CONFIGURATION (Optional - recommended for production)
    # =============================================================================
    # Supported: aws, gcp, azure, vault
    # Set to 'false' to read all sensitive values from this .env file instead
    SECRET_MANAGER=false
    SECRET_PREFIX=kmi
    SECRET_REGION= # AWS only (optional)
    GCP_PROJECT_ID= # GCP only (auto-detected from gcloud config if not set)
    AZURE_KEY_VAULT_NAME= # Azure Key Vault only
    # VAULT_ADDR=https://vault.example.com:8200 # HashiCorp Vault only

    For the full secret-manager setup, see Secret Managers.

  5. Configure application settings.

    Terminal window
    # =============================================================================
    # APPLICATION CONFIGURATION
    # =============================================================================
    NAMESPACE=kmi
    RELEASE_NAME=kafka-mobility-intelligence
    PLATFORM= # Auto-detect if empty (eks, gke, aks, openshift, onprem)
    # Service emails (update with your domain)
    DATA_REPLICATION_SERVICE_EMAIL=datarepl@yourcompany.com
    MONITORING_SERVICE_EMAIL=monitoring@yourcompany.com
    COLLECTOR_SERVICE_EMAIL=collector@yourcompany.com
    # Deployment options
    AUTO_LOGIN=false # Auto-login to cloud registries
    AUTO_CREATE_REPO=false # Auto-create registry repos
    KEEP_VALUES=false # Keep Helm values on upgrade
    SKIP_LOAD=false # Skip loading images
    SKIP_PUSH=false # Skip pushing images
  6. Configure OIDC / SSO (optional).

    To enable Single Sign-On via OpenID Connect, add the following to your .env:

    Terminal window
    # =============================================================================
    # OIDC / SSO CONFIGURATION (Optional)
    # =============================================================================
    # Supported providers: Azure AD (Entra ID), Keycloak, Okta, Auth0, etc.
    OIDC_ENABLED=true
    OIDC_ISSUER_URL=https://login.microsoftonline.com/<tenant-id>/v2.0
    OIDC_CLIENT_ID=your_client_id
    OIDC_REDIRECT_URI=https://your-app-url/api/auth/oidc/callback
    OIDC_SCOPES=openid email profile
    OIDC_BUTTON_LABEL=Sign in with SSO
    NEXTAUTH_URL=https://your-app-url
  7. Configure sensitive values.

    Generate secure values and store them in your secret manager or directly in your .env file:

    Terminal window
    # Generate JWT secret (16 bytes hex)
    openssl rand -hex 16
    # Generate AES key (32 bytes hex)
    openssl rand -hex 32

    Required secrets:

    Secret KeyDescription
    MONGO_USERNAMEMongoDB root username
    MONGO_PASSWORDMongoDB root password
    ADMIN_PASSWORDKMI admin user password
    JWT_SECRETJWT signing secret (16 bytes hex)
    AES_KEYAES encryption key (32 bytes hex)
    OIDC_CLIENT_SECRETOIDC client secret (only if OIDC_ENABLED=true)

    If not using a secret manager, set these directly in .env:

    Terminal window
    # =============================================================================
    # SENSITIVE VALUES (set here if not using a secret manager)
    # =============================================================================
    MONGO_USERNAME=your_mongo_username
    MONGO_PASSWORD=your_mongo_password
    ADMIN_PASSWORD=your_admin_password
    JWT_SECRET=your_generated_jwt_secret
    AES_KEY=your_generated_aes_key
    # OIDC_CLIENT_SECRET=your_oidc_client_secret # Only if OIDC_ENABLED=true
  8. Authenticate to the registry.

    For cloud registries (no IMAGE_PULL_SECRET needed):

    Terminal window
    # AWS ECR
    aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <registry>
    # GCP Artifact Registry / GCR
    gcloud auth configure-docker
    # Azure ACR
    az acr login --name <registry-name>

    For private registries (Docker Hub, Harbor, Nexus, JFrog), also create a pull secret:

    Terminal window
    docker login <registry-url>
    kubectl create namespace kmi
    kubectl create secret docker-registry <your-pull-secret> \
    --namespace=kmi \
    --docker-server=<registry-url> \
    --docker-username=<username> \
    --docker-password=<password>
  9. Run the deployment script.

    Simple deployment, everything from .env:

    Terminal window
    ./k8s-deploy.sh

    With custom options (rarely needed):

    Terminal window
    ./k8s-deploy.sh --env-file /path/to/custom.env --chart /path/to/custom-chart

    The script loads Docker images from images.tar.gz, pushes images to your registry (if needed), auto-detects the platform and applies the correct values overlay, updates configuration from .env, creates Kubernetes secrets, and deploys the application using Helm.

All platforms use the same deployment process. Configure your platform-specific settings in .env, then run ./k8s-deploy.sh.

Terminal window
# In .env file
REGISTRY_URL=123456789.dkr.ecr.us-west-2.amazonaws.com
PLATFORM=eks
AUTO_LOGIN=true
AUTO_CREATE_REPO=true
# Then run
./k8s-deploy.sh
  1. Verify pod status.

    Wait approximately 30-60 seconds for all services to initialize, then verify:

    Terminal window
    kubectl get pods -n kmi

    You should see these pods running:

    • kafka-mobility-intelligence-mongodb-0
    • kafka-mobility-intelligence-frontend-xxxxxxxxxx-xxxxx
    • kafka-mobility-intelligence-backend-xxxxxxxxxx-xxxxx
  2. Check services.

    Terminal window
    kubectl get services -n kmi

    Expected services:

    • kafka-mobility-intelligence-mongodb (ClusterIP, Port 27017)
    • kafka-mobility-intelligence-frontend (ClusterIP, Port 3000)
    • kafka-mobility-intelligence-backend (ClusterIP, Ports 18002-18004)
  3. Check ingress.

    Terminal window
    kubectl get ingress -n kmi
  4. Access the application.

    The application is accessible only from within your private network.

    Via ingress (from VPN or internal network):

    Terminal window
    INGRESS_URL=$(kubectl get ingress kafka-mobility-intelligence-frontend -n kmi -o jsonpath='{.spec.rules[0].host}')
    echo "Access URL: http://$INGRESS_URL"

    Via port forward (for local testing):

    Terminal window
    kubectl port-forward svc/kafka-mobility-intelligence-frontend 3000:3000 -n kmi
    # Open http://localhost:3000
  5. Verify application health.

    Terminal window
    kubectl logs -f deployment/kafka-mobility-intelligence-frontend -n kmi
    kubectl logs -f deployment/kafka-mobility-intelligence-backend -n kmi

    Log in with username admin (or your configured ADMIN_USER_ID) and your configured admin password.

The complete .env file structure:

Terminal window
# =============================================================================
# MONGODB CONFIGURATION
# =============================================================================
MONGODB_DATABASE=kmimigration
# =============================================================================
# ADMIN USER
# =============================================================================
ADMIN_USER_ID=admin
ADMIN_EMAIL=admin@yourcompany.com
# =============================================================================
# SERVICE EMAILS
# =============================================================================
DATA_REPLICATION_SERVICE_EMAIL=datarepl@yourcompany.com
MONITORING_SERVICE_EMAIL=monitoring@yourcompany.com
COLLECTOR_SERVICE_EMAIL=collector@yourcompany.com
# =============================================================================
# APPLICATION SETTINGS
# =============================================================================
JWT_EXPIRES_IN=8h
JWT_EXPIRES_INT=8
USE_SECURE_COOKIES=false
# =============================================================================
# SERVICE PORTS
# =============================================================================
MONGODB_PORT=27017
FRONTEND_PORT=3000
DATA_REPLICATOR_PORT=18002
MONITORING_SERVICE_PORT=18003
MONITORING_SOCKET_PORT=18004
# =============================================================================
# CONTAINER REGISTRY
# =============================================================================
REGISTRY_URL=your-registry-url
IMAGE_TAG=your-image-tag
IMAGE_PULL_SECRET=your-pull-secret
# =============================================================================
# KUBERNETES SETTINGS
# =============================================================================
NAMESPACE=kmi
RELEASE_NAME=kafka-mobility-intelligence
PLATFORM= # Auto-detect if empty
# =============================================================================
# DEPLOYMENT OPTIONS
# =============================================================================
AUTO_LOGIN=false
AUTO_CREATE_REPO=false
KEEP_VALUES=false
RECREATE_MONGODB_STATEFULSET=false
SKIP_LOAD=false
SKIP_PUSH=false
# =============================================================================
# SECRET MANAGER (Optional - recommended for production)
# =============================================================================
SECRET_MANAGER=false # aws, gcp, azure, vault, or false (.env fallback)
SECRET_PREFIX=kmi
SECRET_REGION=
GCP_PROJECT_ID=
AZURE_KEY_VAULT_NAME=
VAULT_ADDR=
# =============================================================================
# SENSITIVE VALUES (secret manager or .env - secret manager takes priority)
# =============================================================================
MONGO_USERNAME=
MONGO_PASSWORD=
ADMIN_PASSWORD=
JWT_SECRET=
AES_KEY=
OIDC_CLIENT_SECRET= # Only if OIDC_ENABLED=true
# =============================================================================
# OIDC / SSO CONFIGURATION (Optional)
# =============================================================================
OIDC_ENABLED=false
OIDC_ISSUER_URL=
OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET - set above in SENSITIVE VALUES, or in secret manager as: kmi-OIDC_CLIENT_SECRET
OIDC_REDIRECT_URI=
OIDC_SCOPES=openid email profile
OIDC_BUTTON_LABEL=Sign in with SSO
NEXTAUTH_URL=
Terminal window
kubectl get pods,svc,ingress -n kmi
Terminal window
# Frontend logs
kubectl logs -f deployment/kafka-mobility-intelligence-frontend -n kmi
# Backend logs
kubectl logs -f deployment/kafka-mobility-intelligence-backend -n kmi
# MongoDB logs
kubectl logs -f statefulset/kafka-mobility-intelligence-mongodb -n kmi
Terminal window
# Scale frontend
kubectl scale deployment kafka-mobility-intelligence-frontend --replicas=2 -n kmi
# Scale backend
kubectl scale deployment kafka-mobility-intelligence-backend --replicas=2 -n kmi
Terminal window
# Edit the .env file with new values, then redeploy
./k8s-deploy.sh
Terminal window
helm uninstall kafka-mobility-intelligence -n kmi
kubectl delete namespace kmi

To deploy new images to a running cluster without downtime, see Rolling Updates.