📦 OpenShift Setup
This guide explains how to deploy a small GermainUX environment on an existing Red Hat OpenShift cluster.
Testing environments only
The configuration supplied with the GermainUX OpenShift distribution is intended for development, evaluation, and testing. It is not a production reference architecture. Production deployments require environment-specific sizing, high availability, persistent storage, security, monitoring, backup, and disaster-recovery planning.
📋 Requirements
Before starting, confirm that you have:
|
Requirement |
|---|
|
A supported OpenShift cluster |
|
Access to create resources in the target OpenShift project |
|
The OpenShift CLI ( |
|
|
|
A default or explicitly configured StorageClass |
|
Access to the GermainUX container images |
|
A valid GermainUX license |
|
Network connectivity to any external database, SMTP server, identity provider, or datastore |
|
Sufficient permissions to create Routes, Services, ConfigMaps, Secrets, workloads, and persistent-volume claims |
Cluster-administrator access may be required if the deployment needs custom Security Context Constraints, cluster-wide resources, or storage configuration.
🖥️ Example lab capacity
The original GermainUX lab environment used:
|
Resource |
Example value |
|---|---|
|
Minimum node-group size |
8 |
|
Maximum node-group size |
16 |
|
Desired node-group size |
8 |
|
Node volume type |
GP3 |
|
Minimum CPU |
2 cores |
|
Minimum memory |
4 GB |
|
Minimum disk |
20 GB |
These are sample lab values—not production requirements. Confirm whether the CPU, memory, and disk values apply per node in your OpenShift environment.
⚙️ Production sizing must account for
|
Consideration |
|---|
|
Number of monitored users and applications |
|
Telemetry volume |
|
Data-retention period |
|
Elasticsearch indexing and query activity |
|
Kafka throughput |
|
Database workload |
|
Replication and high availability |
|
JVM heap requirements |
|
Expected growth |
⬇️ Obtain the GermainUX package
Download the OpenShift deployment package provided for your licensed GermainUX release and extract it:
tar xzf germainux-openshift-<version>-binary.tar.gz
cd germainux-openshift-<version>
Obtain the current package and supported component-version matrix from GermainUX Support.
Do not deploy manifests generated for a different GermainUX release without reviewing their compatibility.
🔗 Connect to OpenShift
Sign in using your organization’s approved authentication method:
oc login <openshift-api-url>
Confirm the connected cluster and user:
oc whoami
oc whoami --show-server
📁 Create or select a project
Create a dedicated project when appropriate:
oc new-project germainux
Or select an existing project:
oc project <project-name>
Verify the active project before deploying:
oc project
Use separate projects for development, QA, staging, and production unless your organization has approved another isolation model.
🔑 Configure the GermainUX license
Locate the license configuration supplied in the extracted package. In packages following the Kubernetes structure, it may be located under:
<EXTRACTED_FILES>/templates/config/license/
germain.apm.monitoringConfig.systemConfig.license.json
Update the encrypted license value with the content supplied by Germain Software.
Do not:
|
Do not |
|---|
|
Commit the license to a public repository. |
|
Embed it in an unprotected container image. |
|
Include it in logs. |
|
Store an unencrypted copy in a ConfigMap. |
Use an OpenShift Secret or your organization’s secret-management solution whenever supported by the deployment package.
🔧 Configure the deployment
Open:
deploy-germain.sh
Update the values for the target OpenShift environment.
Depending on the package version, the script may include variables such as:
elasticSearchVersion="<approved-version>"
mysqlVersion="<approved-version>"
kibanaVersion="<approved-version>"
zookeeperVersion="<approved-version>"
hazelcastVersion="<approved-version>"
kafkaVersion="<approved-version>"
germainVersion="<germainux-version>"
germainApmBuildRegistry="<container-registry>"
germainEnvName="<environment-name>"
Use only versions approved for the installed GermainUX release.
💬 Messaging compatibility
GermainUX 2024.2 and later uses Kafka. ActiveMQ applies only to earlier releases.
For GermainUX 2024.2 or later:
|
Action |
|---|
|
Configure the approved Kafka version. |
|
Do not deploy ActiveMQ unless Germain Support explicitly requires it for a compatibility or upgrade scenario. |
🏷️ Environment name
Set a unique environment name:
germainEnvName="germain-qa"
The environment name may be used to generate resource names, manifest directories, and configuration paths. Avoid changing it after initialization unless you intend to create a separate environment.
🧾 Configure image access
If the images are stored in a private registry, create an image-pull secret:
oc create secret docker-registry germainux-registry \
--docker-server=<registry-host> \
--docker-username=<registry-user> \
--docker-password=<registry-password>
Link it to the service account used by the workloads:
oc secrets link <service-account> germainux-registry --for=pull
Do not place registry credentials directly in deployment manifests or shell scripts.
🗄️ Configure the database
The deployment can use its packaged database resources or an external configuration database.
📦 Packaged database
If using the database supplied with the deployment:
|
Action |
|---|
|
Confirm that persistent storage is available. |
|
Set resource requests and limits. |
|
Protect the database credentials. |
|
Verify the StorageClass. |
|
Configure backups when the environment must be retained. |
🔗 External database
When using an external configuration database:
-
Set the packaged MySQL replica count to
0.Older deployment packages may use:
mysqlReplicase=0Use the exact variable name found in your
deploy-germain.shfile. -
Configure the database host:
germainDbHostname="<database-hostname>" -
Update
common.properties:germain.config.url=jdbc:mysql://<database-host>:3306/APMCFG?rewriteBatchedStatements=true germain.config.username=<database-user> germain.config.password=<database-password>
Confirm that:
|
Check |
|---|
|
OpenShift workloads can resolve the database hostname. |
|
Network policies and firewalls permit the connection. |
|
The schema exists. |
|
The account has the required permissions. |
|
TLS is configured when required. |
|
Credentials are provided through Secrets where supported. |
Do not retain example usernames or passwords in a shared or production environment.
📧 Configure email
To enable email alerts and reports, update the SMTP settings in common.properties.
Configure:
|
Setting |
|---|
|
SMTP hostname and port |
|
Authentication |
|
Username and password |
|
Sender address |
|
TLS or STARTTLS |
|
Any required certificate trust |
Store SMTP credentials in an OpenShift Secret whenever supported.
🛡️ Review OpenShift security requirements
OpenShift commonly runs containers with an automatically assigned, non-root user ID. Before deployment, confirm that every GermainUX image can:
|
Requirement |
|---|
|
Run without a fixed root user |
|
Write only to approved mounted directories |
|
Use group-writable files and directories where required |
|
Operate without privileged mode |
|
Avoid prohibited Linux capabilities |
|
Use the default restricted Security Context Constraint when possible |
Do not grant privileged or overly permissive Security Context Constraints simply to bypass file-permission or image-design problems.
If an exception is required, document and restrict it to the specific service account and workload.
🗂️ Generate the manifests
Run:
chmod +x deploy-germain.sh
./deploy-germain.sh
The script generates Kubernetes-compatible YAML files under the directory identified by germainEnvName.
Review the generated resources before applying them:
|
Resource |
|---|
|
Project or namespace |
|
Container images and tags |
|
Image-pull secrets |
|
Service accounts |
|
Security contexts |
|
Resource requests and limits |
|
Persistent-volume claims |
|
StorageClass |
|
ConfigMaps and Secrets |
|
Services and ports |
|
Routes |
|
Health probes |
|
Replica counts |
|
Node placement rules |
🚀 Deploy GermainUX
The generated resources must be applied in this order:
|
Step |
Resource type |
|---|---|
|
1 |
Configuration |
|
2 |
Infrastructure |
|
3 |
GermainUX components |
1️⃣ 1. Apply configuration resources
oc apply -f <germainEnvName>/configmap/
🔧 2. Apply infrastructure resources
oc apply -f <germainEnvName>/infra/
Wait for the infrastructure components to become ready:
oc get pods
oc get services
oc get pvc
⚙️ 3. Apply GermainUX resources
oc apply -f <germainEnvName>/germain/
Monitor the deployment:
oc get pods -w
You can use kubectl apply instead of oc apply for standard Kubernetes resources, but oc is recommended when working with OpenShift-specific objects such as Routes.
🌐 Configure external access
List existing Routes:
oc get routes
If the package creates a Route, retrieve its hostname:
oc get route <route-name>
If no Route is supplied, create one for the GermainUX service according to your organization’s TLS and ingress standards.
Example:
oc expose service <germainux-service-name>
For production, configure TLS and use a trusted certificate. Do not expose a test environment using default credentials to an untrusted network.
🖥️ Access the GermainUX Workspace
The default Workspace path is:
http://<germain-host>:8080/germainapm/workspace/
When using an OpenShift Route, access it through the Route hostname and configured protocol:
https://<route-host>/germainapm/workspace/
An initial test deployment may use:
Username: admin
Password: admin
Change the default password immediately after the first successful sign-in.
✅ Validate the deployment
👀 Check pods
oc get pods
Investigate pods in any of these states:
Pending
CrashLoopBackOff
ImagePullBackOff
CreateContainerConfigError
Error
🔗 Check services and routes
oc get services
oc get routes
💾 Check persistent storage
oc get pvc
Required claims should report:
Bound
📃 Review pod details and events
oc describe pod <pod-name>
oc get events --sort-by=.lastTimestamp
📝 Review logs
oc logs <pod-name>
For a multi-container pod:
oc logs <pod-name> -c <container-name>
For a container that restarted:
oc logs <pod-name> --previous
🏗️ Production requirements
Before using GermainUX on OpenShift in production, implement:
|
Requirement |
|---|
|
Resource requests and limits |
|
Multiple replicas for supported stateless components |
|
Pod anti-affinity and topology-spread constraints |
|
Pod disruption budgets |
|
Suitable persistent storage |
|
Database and datastore backups |
|
TLS for external and internal connections |
|
OpenShift Secrets or an external secret manager |
|
NetworkPolicies |
|
Restricted service accounts and RBAC |
|
Restricted Security Context Constraints |
|
Image vulnerability scanning |
|
Approved registries and immutable image tags |
|
Readiness, liveness, and startup probes |
|
Centralized logs and metrics |
|
Capacity and disk-usage alerts |
|
Upgrade, rollback, and disaster-recovery procedures |
Troubleshooting
⛔ Pod is rejected by OpenShift security
Review:
oc describe pod <pod-name>
Look for errors related to:
|
Issue |
|---|
|
Security Context Constraints |
|
Fixed user IDs |
|
Privileged containers |
|
Disallowed capabilities |
|
Writable-directory permissions |
|
HostPath volumes |
Correct the image or workload security context whenever possible. Grant a broader SCC only after security review.
❌ Pod cannot pull its image
Verify:
|
Check |
|---|
|
Image registry and repository |
|
Image tag |
|
Image-pull secret |
|
Service-account secret linkage |
|
Registry certificates |
|
Network access from cluster nodes |
⌛ Persistent-volume claim remains pending
Check:
oc describe pvc <pvc-name>
oc get storageclass
Confirm that the requested access mode and storage size are supported by the selected StorageClass.
📡 Route is unavailable
Check:
oc describe route <route-name>
oc get endpoints <service-name>
Verify that:
|
Check |
|---|
|
The Route points to the correct Service. |
|
The Service has ready endpoints. |
|
The target port is correct. |
|
The router is healthy. |
|
DNS resolves the Route hostname. |
|
TLS settings are valid. |
🔍 GermainUX cannot reach an external database
Confirm:
|
Check |
|---|
|
DNS resolution from the project |
|
Egress NetworkPolicies |
|
External firewall rules |
|
Database listener availability |
|
Credentials and permissions |
|
TLS and certificate trust |
|
JDBC connection configuration |
Source: OpenShift Setup.
Component: Enterprise
Feature Availability: 2024.1