Installation on Kubernetes
DBmarlin Server can run on Kubernetes as a single-replica StatefulSet. The installation uses Kustomize overlays for storage providers and keeps the server installation, PostgreSQL data, and configuration on a persistent volume.
This installation is stateful and is intended for one server replica. Back up the database and configuration before changing the image, storage, or workload.
Prerequisites​
- Kubernetes with
kubectland Kustomize support (kubectl apply -k). - A container registry reachable by the cluster.
- A StorageClass that can provision a ReadWriteOnce volume for persistent installs.
- Network connectivity from the server pod to every database target it monitors.
- A namespace and context selected in
kubectlbefore deploying.
DBmarlin's recommended disk size is approximately 20GB per monitored database instance. See the server hardware requirements for the profile recommendations.
Container image​
The public image is available at
Docker Hub. The Kubernetes
overlays select a version with the images.newTag field. Edit that field before a
new installation or upgrade.
To build your own image, use the server Dockerfile and build scripts from the DBmarlin Docker repository, then push the image to a registry visible from the cluster.
Kubernetes layout​
The server manifests are in the dbmarlin-docker repository:
k8s/server-k8s/
├── k8s/base/ # PVC and LoadBalancer Service
├── k8s/components/ # StatefulSet, size, security, and Service components
├── k8s/overlays/ # Platform-specific Kustomize overlays
└── storage/ # Optional StorageClass/PV examples
The available overlays are:
| Overlay | StorageClass | Use |
|---|---|---|
stateful-localpath | local-path | Local-path provisioner and lab clusters |
stateful-eks | gp3 | AWS EKS with the EBS CSI driver |
stateful-aks | managed-csi | Azure AKS |
stateful-gke | standard-rwo | Google GKE |
stateful-civo | civo-volume | Civo |
stateful-openshift | ibmc-vpc-block-10iops-tier | IBM Cloud ROKS/OpenShift; edit for other OpenShift storage |
dev | emptyDir | Evaluation only; data is lost when the pod is replaced |
The example StorageClass and PersistentVolume files are examples only. Review and adapt them to your cluster before applying them.
Platform-specific guidance​
Local-path Kubernetes​
Use stateful-localpath when the cluster has the Rancher local-path provisioner or
another provisioner that provides a local-path StorageClass:
./server-k8s-deploy.sh stateful-localpath
This is suitable for kubeadm, Rancher Desktop, and lab clusters. Local-path
storage is tied to a worker node by the provisioner; it is not a replacement for
replicated cloud block storage. If you create a static local PersistentVolume,
adapt the example files in storage/ to your node name and filesystem path.
Amazon EKS​
Use stateful-eks with the EBS CSI driver and a gp3 StorageClass:
./server-k8s-deploy.sh stateful-eks
The repository includes example gp3 StorageClasses for standard EKS and EKS Auto
Mode. Use the provisioner that matches the cluster, and apply only one of those
examples. The standard EKS example uses ebs.csi.aws.com; EKS Auto Mode uses
ebs.csi.eks.amazonaws.com.
The EKS Service defaults to an internal Network Load Balancer. Private subnets
must be tagged kubernetes.io/role/internal-elb, and the AWS Load Balancer
Controller must be installed. To avoid a load balancer, use
DBMARLIN_SERVICE=nodeport. To expose a public NLB, replace the internal Service
component with service-aws-nlb-internet only after configuring authentication,
HTTPS, and the required public-subnet tags.
Azure AKS​
Use stateful-aks with AKS's built-in managed-csi StorageClass:
./server-k8s-deploy.sh stateful-aks
Confirm that the cluster has a suitable Azure disk quota and that the selected node pool can attach the requested volume. The base Service is a LoadBalancer; use NodePort or port forwarding for a test installation.
Google GKE​
Use stateful-gke with the standard-rwo StorageClass:
./server-k8s-deploy.sh stateful-gke
Confirm that the Compute Engine Persistent Disk CSI driver and the requested disk quota are available. If the cluster spans zones, let the StorageClass choose the volume zone and keep the single StatefulSet replica with its attached disk.
Civo Kubernetes​
Use stateful-civo with Civo's civo-volume StorageClass:
./server-k8s-deploy.sh stateful-civo
Confirm that the account has enough block-volume capacity for the PVC and that the cluster can attach a volume to the selected worker node. The Service defaults to a LoadBalancer; NodePort is available for lower-cost testing.
OpenShift and IBM Cloud ROKS​
Use stateful-openshift for IBM Cloud ROKS/OpenShift. The example selects
ibmc-vpc-block-10iops-tier; edit storageclass-patch.yaml if your cluster uses a
different StorageClass, such as a classic IBM Cloud block-storage class:
./server-k8s-deploy.sh stateful-openshift
The overlay is compatible with OpenShift's restricted Security Context Constraint
and arbitrary namespace UID. It does not request the fixed UID used by the
optional Kubernetes nonroot component. Apply the generated file with oc, or
paste it into the OpenShift console as described in Deploy without
Kustomize. You can expose
the UI with an OpenShift Route instead of a cloud LoadBalancer:
oc create route edge dbmarlin --service=dbmarlin-service --port=9090
Development and evaluation​
Use dev only for evaluation:
./server-k8s-deploy.sh dev
The overlay uses the local registry image
localhost:5000/dbmarlin-server:latest, imagePullPolicy: Always, an emptyDir
volume, and reduced CPU requests. The local registry must be reachable from the
cluster. Replacing the pod deletes the server data, so do not use this overlay for
monitoring that must survive a restart.
Choose a profile size​
The default profile is Small. You can select a profile with DBMARLIN_SIZE when
using the deployment wrapper:
| Profile | Monitored instances | CPU | Memory | Recommended disk |
|---|---|---|---|---|
| XSmall | 1 | 1 vCPU | 2Gi | 20Gi |
| Small | <5 | 1 vCPU | 4Gi | 100Gi |
| Medium | <20 | 2 vCPU | 8Gi | 400Gi |
| Large | <50 | 4 vCPU | 16Gi | 1Ti |
| XLarge | <100 | 8 vCPU | 32Gi | 2Ti |
The size component changes the configure.sh profile and the pod CPU/memory
requests and limits together. Disk is not resized automatically. The wrapper warns
when the rendered PVC or an existing PVC is smaller than the selected profile's
recommendation.
DBMARLIN_SIZE=Medium ./server-k8s-deploy.sh stateful-eks
For a lasting configuration, add the matching component to the overlay's
kustomization.yaml:
components:
- ../../components/statefulset
- ../../components/size-medium
Deploy the server​
Choose the overlay for your cluster and render it first:
kubectl kustomize k8s/overlays/stateful-localpath
Make sure the rendered image tag, storage class, PVC size, and Service exposure are correct. Then use the wrapper, which checks the current context and namespace and asks for confirmation:
./server-k8s-deploy.sh stateful-localpath
Or apply directly:
kubectl apply -k k8s/overlays/stateful-localpath
Check the StatefulSet, pod, claim, and Service:
kubectl get statefulset,pod,pvc,service
kubectl logs statefulset/dbmarlin-server -c dbmarlin-copy
kubectl logs statefulset/dbmarlin-server -c dbmarlin-server
The application Service listens on port 9090. Tomcat and PostgreSQL use ports 9080 and 9070 inside the pod. A headless Service is created for the StatefulSet and is not the public UI endpoint.
Deploy without Kustomize​
Kustomize is only needed to assemble the platform-specific files. You can generate
one standalone, multi-document YAML file and then deploy that file with any normal
Kubernetes tool. kubectl kustomize renders locally; it does not contact the
cluster or apply anything.
From the root of the cloned dbmarlin-docker repository, render the overlay for
your platform:
kubectl kustomize k8s/server-k8s/k8s/overlays/stateful-eks > dbmarlin-server-eks.yaml
Review dbmarlin-server-eks.yaml before applying it. Check the image tag, PVC
storage class and size, Service type, and any security settings. To choose a
different profile or Service type, add the corresponding component to the overlay
first, then render again. For example, add these entries under components: for a
Medium profile and NodePort Service:
- ../../components/statefulset
- ../../components/size-medium
- ../../components/service-nodeport
Apply the generated file with the command-line client:
kubectl apply -f dbmarlin-server-eks.yaml
The same file can be applied with the OpenShift CLI:
oc apply -f dbmarlin-server-eks.yaml
Paste the generated YAML into the OpenShift console​
-
Render the OpenShift overlay and save the output:
kubectl kustomize k8s/server-k8s/k8s/overlays/stateful-openshift > dbmarlin-server-openshift.yaml -
Open the OpenShift project where DBmarlin should run and choose Import YAML (or +Add → Import YAML, depending on the console version).
-
Paste the complete contents of
dbmarlin-server-openshift.yamlinto the editor. The file contains several YAML documents separated by---; the console can create them together. If the console accepts only one document at a time, paste each document separately and create them in this order: Services and PVC first, then the StatefulSet. -
Review the namespace, image, storage class, PVC size, and Service exposure, then choose Create or Apply.
-
Check the resulting pod, PVC, and Service from the console or with:
oc get statefulset,pod,pvc,serviceoc logs pod/dbmarlin-server-0 -c dbmarlin-copy
The generated YAML is a snapshot. If you change the source overlay later, render a new file and apply it again. Keep the source overlay and the generated file under version control when using a Git-based deployment process; do not commit real credentials or private certificates.
Service exposure and security​
The base UI Service is a LoadBalancer on port 9090. The EKS overlay explicitly
uses an internal NLB. Private subnets need the
kubernetes.io/role/internal-elb tag and the AWS Load Balancer Controller must be
installed and configured.
A new DBmarlin installation has authentication disabled. Keep the Service private
while configuring authentication and HTTPS. To opt in to an internet-facing EKS
NLB, replace the service-aws-nlb-internal component with
service-aws-nlb-internet after reviewing subnet tags and access controls.
For test clusters, avoid a cloud load balancer with the NodePort component:
DBMARLIN_SERVICE=nodeport ./server-k8s-deploy.sh stateful-eks
Alternatively, use port forwarding without exposing a node port:
kubectl port-forward service/dbmarlin-service 9090:9090
On clusters enforcing the restricted Pod Security Standard, add the nonroot
component after the StatefulSet component. The OpenShift overlay has its own
arbitrary-UID-compatible patch; do not combine it with nonroot.
Upgrades​
The StatefulSet uses OnDelete, so changing an image tag does not restart the pod
automatically. For a normal upgrade:
-
Back up the database and configuration and check the release upgrade notes.
-
Change
images.newTagin the selected overlay. -
Re-apply with the same profile and Service settings used by the installation. Environment overrides are temporary and must be supplied on every apply.
-
Delete the pod only after the apply succeeds:
kubectl delete pod dbmarlin-server-0 -
Check the init-container logs, pod readiness, and monitoring data.
Migrating from the old Deployment layout​
Older versions used k8s/prod and k8s/dev Deployments. Before migrating a
persistent installation:
-
Back up and verify the backup.
-
Inspect the existing PVC's storage class, requested size, and capacity.
-
Preserve the existing storage class in the selected overlay. A bound PVC's storage class cannot be changed in place; the old production example used
gp2, while the current EKS example usesgp3. -
Set the base PVC request to the existing claim's size. Do not apply a smaller request over an expanded claim.
-
Set the overlay image tag to the currently running version and render the result.
-
Delete only the old Deployment and wait for its pod to terminate:
kubectl delete deployment dbmarlin-server --cascade=foreground --wait=true -
Apply the prepared StatefulSet overlay. Do not use the removal script during migration because it deletes the PVC and its data.
The old dev Deployment used emptyDir; export anything needed before replacing
it because its data is ephemeral.
Remove the server​
The removal script deletes the PVC and all DBmarlin data. Back up first.
./server-k8s-remove-all.sh stateful-localpath
For a non-destructive workload removal, delete the StatefulSet while retaining the PVC and specify the appropriate retention behavior for your storage provider:
kubectl delete statefulset dbmarlin-server
Troubleshooting​
- PVC Pending: check that the selected StorageClass exists, supports the requested access mode and size, and has a provisioner. For local volumes, check node affinity and the local path.
- Pod stuck in Init: inspect
kubectl logs pod/dbmarlin-server-0 -c dbmarlin-copy. Check image access, volume permissions, and available disk space. - Service has no endpoint: check that the pod is Ready and that the Service
selector is
app: dbmarlin-server. - LoadBalancer Pending: inspect Service events and cloud-controller logs. For EKS, check subnet tags and the AWS Load Balancer Controller.
- Upgrade did not happen: the StatefulSet is
OnDelete; deletedbmarlin-server-0after applying the new image tag. - Data is missing: confirm that the pod still mounts
dbmarlin-pvcand that the PVC was not deleted or replaced during migration.