From f6c5aa12e4980c216c9e7eac6050be88f329a354 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Thu, 21 Aug 2025 11:07:48 +0800 Subject: [PATCH] deploy metabase --- .../metabase/README.md | 126 +++++++++++++++ .../metabase/metabase-deployment.yaml | 145 ++++++++++++++++++ .../metabase/metabase-ingress.yaml | 32 ++++ .../metabase/metabase-postgres.yaml | 119 ++++++++++++++ 4 files changed, 422 insertions(+) create mode 100644 cluster/manifests/freeleaps-data-platform/metabase/README.md create mode 100644 cluster/manifests/freeleaps-data-platform/metabase/metabase-deployment.yaml create mode 100644 cluster/manifests/freeleaps-data-platform/metabase/metabase-ingress.yaml create mode 100644 cluster/manifests/freeleaps-data-platform/metabase/metabase-postgres.yaml diff --git a/cluster/manifests/freeleaps-data-platform/metabase/README.md b/cluster/manifests/freeleaps-data-platform/metabase/README.md new file mode 100644 index 00000000..4ada6a15 --- /dev/null +++ b/cluster/manifests/freeleaps-data-platform/metabase/README.md @@ -0,0 +1,126 @@ +# Metabase Deployment + +## Overview +This directory contains Kubernetes manifests for deploying Metabase, a business intelligence and analytics platform, along with its PostgreSQL database. + +## Components + +### 1. metabase-postgres.yaml +PostgreSQL database deployment: +- Persistent storage for data +- ConfigMap for database configuration +- Secret for database password +- Service for internal communication + +### 2. metabase-deployment.yaml +Metabase application deployment: +- Metabase container with latest image +- Persistent storage for application data +- Environment variables for database connection +- Health checks and resource limits +- Service for internal communication + +### 3. metabase-ingress.yaml +Ingress configuration for external access: +- Nginx ingress class +- Multiple host support (metabase.freeleaps.cluster, metabase.local) +- SSL redirect disabled for development + +## Deployment Steps + +### 1. Deploy PostgreSQL Database +```bash +kubectl apply -f metabase-postgres.yaml +``` + +### 2. Wait for PostgreSQL to be Ready +```bash +kubectl wait --for=condition=ready pod -l app=metabase-postgres -n metabase --timeout=300s +``` + +### 3. Deploy Metabase Application +```bash +kubectl apply -f metabase-deployment.yaml +``` + +### 4. Deploy Ingress (Optional) +```bash +kubectl apply -f metabase-ingress.yaml +``` + +### 5. Monitor Deployment +```bash +kubectl get pods -n metabase +kubectl get services -n metabase +kubectl get ingress -n metabase +``` + +## Configuration + +### Database Connection +- **Type**: PostgreSQL +- **Host**: metabase-postgres +- **Port**: 5432 +- **Database**: metabase +- **User**: metabase +- **Password**: metabasepassword + +### Storage +- **Metabase Data**: 10Gi persistent storage +- **PostgreSQL Data**: 5Gi persistent storage +- **Storage Class**: azure-disk-std-ssd-lrs + +### Resources +- **Metabase**: 512Mi-1Gi memory, 250m-500m CPU +- **PostgreSQL**: 256Mi-512Mi memory, 250m-500m CPU + +## Access + +### Internal Access +- **Metabase**: http://metabase.metabase.svc.cluster.local:3000 +- **PostgreSQL**: metabase-postgres.metabase.svc.cluster.local:5432 + +### External Access (with Ingress) +- **Primary**: http://metabase.freeleaps.cluster +- **Alternative**: http://metabase.local + +## Initial Setup + +1. **First Access**: Navigate to the Metabase URL +2. **Setup Wizard**: Follow the initial setup wizard +3. **Database Connection**: Use the internal PostgreSQL connection +4. **Admin User**: Create the first admin user +5. **Data Sources**: Connect to your data sources + +## Troubleshooting + +### Check Pod Status +```bash +kubectl get pods -n metabase +kubectl describe pod -n metabase +``` + +### Check Logs +```bash +kubectl logs -n metabase +kubectl logs -n metabase -c postgres # for PostgreSQL +``` + +### Check Services +```bash +kubectl get services -n metabase +kubectl describe service metabase -n metabase +``` + +### Check Storage +```bash +kubectl get pvc -n metabase +kubectl describe pvc metabase-data -n metabase +``` + +## Notes + +- **Initial Startup**: Metabase may take 2-3 minutes to start up on first deployment +- **Database**: Ensure PostgreSQL is fully ready before deploying Metabase +- **Storage**: Both Metabase and PostgreSQL use persistent storage for data persistence +- **Security**: Default password is base64 encoded, consider changing for production use diff --git a/cluster/manifests/freeleaps-data-platform/metabase/metabase-deployment.yaml b/cluster/manifests/freeleaps-data-platform/metabase/metabase-deployment.yaml new file mode 100644 index 00000000..7f413f25 --- /dev/null +++ b/cluster/manifests/freeleaps-data-platform/metabase/metabase-deployment.yaml @@ -0,0 +1,145 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: metabase + labels: + name: metabase +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: metabase + namespace: metabase +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metabase-data + namespace: metabase +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: azure-disk-std-ssd-lrs +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: metabase-config + namespace: metabase +data: + MB_DB_TYPE: "postgres" + MB_DB_DBNAME: "metabase" + MB_DB_PORT: "5432" + MB_DB_USER: "metabase" + MB_DB_HOST: "metabase-postgres" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: metabase + namespace: metabase + labels: + app: metabase +spec: + replicas: 1 + selector: + matchLabels: + app: metabase + template: + metadata: + labels: + app: metabase + spec: + serviceAccountName: metabase + containers: + - name: metabase + image: metabase/metabase:latest + ports: + - containerPort: 3000 + name: http + env: + - name: MB_DB_TYPE + valueFrom: + configMapKeyRef: + name: metabase-config + key: MB_DB_TYPE + - name: MB_DB_DBNAME + valueFrom: + configMapKeyRef: + name: metabase-config + key: MB_DB_DBNAME + - name: MB_DB_PORT + valueFrom: + configMapKeyRef: + name: metabase-config + key: MB_DB_PORT + - name: MB_DB_USER + valueFrom: + configMapKeyRef: + name: metabase-config + key: MB_DB_USER + - name: MB_DB_HOST + valueFrom: + configMapKeyRef: + name: metabase-config + key: MB_DB_HOST + - name: MB_DB_PASS + valueFrom: + secretKeyRef: + name: metabase-db-secret + key: password + volumeMounts: + - name: metabase-data + mountPath: /metabase-data + resources: + requests: + memory: "512Mi" + cpu: "250m" + limits: + memory: "1Gi" + cpu: "500m" + livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 120 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + volumes: + - name: metabase-data + persistentVolumeClaim: + claimName: metabase-data +--- +apiVersion: v1 +kind: Service +metadata: + name: metabase + namespace: metabase + labels: + app: metabase +spec: + type: ClusterIP + ports: + - port: 3000 + targetPort: 3000 + protocol: TCP + name: http + selector: + app: metabase +--- +apiVersion: v1 +kind: Secret +metadata: + name: metabase-db-secret + namespace: metabase +type: Opaque +data: + password: bWV0YWJhc2VwYXNzd29yZA== # metabasepassword in base64 diff --git a/cluster/manifests/freeleaps-data-platform/metabase/metabase-ingress.yaml b/cluster/manifests/freeleaps-data-platform/metabase/metabase-ingress.yaml new file mode 100644 index 00000000..e044071c --- /dev/null +++ b/cluster/manifests/freeleaps-data-platform/metabase/metabase-ingress.yaml @@ -0,0 +1,32 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: metabase-ingress + namespace: metabase + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/proxy-body-size: "50m" +spec: + rules: + - host: metabase.freeleaps.cluster + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: metabase + port: + number: 3000 + - host: metabase.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: metabase + port: + number: 3000 diff --git a/cluster/manifests/freeleaps-data-platform/metabase/metabase-postgres.yaml b/cluster/manifests/freeleaps-data-platform/metabase/metabase-postgres.yaml new file mode 100644 index 00000000..7c858efb --- /dev/null +++ b/cluster/manifests/freeleaps-data-platform/metabase/metabase-postgres.yaml @@ -0,0 +1,119 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metabase-postgres-data + namespace: metabase +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: azure-disk-std-ssd-lrs +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: metabase-postgres-config + namespace: metabase +data: + POSTGRES_DB: "metabase" + POSTGRES_USER: "metabase" +--- +apiVersion: v1 +kind: Secret +metadata: + name: metabase-postgres-secret + namespace: metabase +type: Opaque +data: + POSTGRES_PASSWORD: bWV0YWJhc2VwYXNzd29yZA== # metabasepassword in base64 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: metabase-postgres + namespace: metabase + labels: + app: metabase-postgres +spec: + replicas: 1 + selector: + matchLabels: + app: metabase-postgres + template: + metadata: + labels: + app: metabase-postgres + spec: + containers: + - name: postgres + image: postgres:15 + ports: + - containerPort: 5432 + name: postgres + env: + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: metabase-postgres-config + key: POSTGRES_DB + - name: POSTGRES_USER + valueFrom: + configMapKeyRef: + name: metabase-postgres-config + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: metabase-postgres-secret + key: POSTGRES_PASSWORD + - name: PGDATA + value: "/var/lib/postgresql/data/pgdata" + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + exec: + command: + - pg_isready + - -U + - metabase + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + exec: + command: + - pg_isready + - -U + - metabase + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: postgres-data + persistentVolumeClaim: + claimName: metabase-postgres-data +--- +apiVersion: v1 +kind: Service +metadata: + name: metabase-postgres + namespace: metabase + labels: + app: metabase-postgres +spec: + type: ClusterIP + ports: + - port: 5432 + targetPort: 5432 + protocol: TCP + name: postgres + selector: + app: metabase-postgres