Kubernetes Setup

⚙️ Kubernetes Setup

This guide explains how to deploy a small GermainUX environment on an existing Kubernetes cluster.

Testing environments only

The configuration provided with the Kubernetes distribution is intended for development, evaluation, and testing. It is not a production reference architecture. Production deployments require environment-specific sizing, persistent storage, security, availability, backup, monitoring, and disaster-recovery planning.

🏗️ Architecture

The deployment package generates Kubernetes manifests for three groups of resources:

Resource group

Purpose

configmap

GermainUX and infrastructure configuration

infra

Required infrastructure services and datastores

germain

Germain Enterprise and related GermainUX services

Apply these groups in that order because GermainUX depends on the configuration and infrastructure resources.

📋 Requirements

🤖 Kubernetes cluster

You need:

Requirement

A functioning Kubernetes cluster

Administrative or appropriately scoped cluster permissions

kubectl configured for the target cluster

A default or explicitly configured StorageClass

A container registry accessible from every cluster node

Network connectivity between all required GermainUX components

External access through an Ingress, LoadBalancer, or another approved method

📊 Example lab capacity

The original test environment used the following cluster settings:

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 values reflect a sample lab environment, not guaranteed requirements. Confirm whether CPU, memory, and disk values apply per node in your Kubernetes platform and resize the cluster according to the number of deployed components and expected data volume.

For production sizing, account for:

Factor

Number of monitored users and applications

Incoming telemetry volume

Retention period

Elasticsearch indexing and query workload

Kafka throughput and retention

High-availability requirements

JVM heap requirements

Replication and backup overhead

Expected growth

📦 Obtain the deployment package

Download the Kubernetes distribution provided for your licensed GermainUX release:

wget <germainux-kubernetes-package-url>
tar xzf germainux-kubernetes-<version>-binary.tar.gz
cd germainux-kubernetes-<version>

Obtain the current package URL and supported component-version matrix from GermainUX Support.

Do not reuse manifests generated by a different GermainUX release without reviewing their compatibility.

🔑 Configure the license

Locate:

<EXTRACTED_FILES>/templates/config/license/
germain.apm.monitoringConfig.systemConfig.license.json

Update the encrypted license value with the license content supplied by Germain Software.

Do not:

  • Commit the license to a public source-code repository.

  • Include it in an unprotected container image.

  • Share it in logs or support material.

  • Store an unencrypted copy in a ConfigMap.

For production deployments, use your organization’s approved Kubernetes secret-management solution whenever the deployment package supports it.

🔧 Configure the deployment

Open:

deploy-germain.sh

Update the deployment variables for the target environment.

A package may contain variables similar to:

elasticSearchVersion="<approved-version>"
mysqlVersion="<approved-version>"
kibanaVersion="<approved-version>"
zookeeperVersion="<approved-version>"
hazelcastVersion="<approved-version>"
kafkaVersion="<approved-version>"
germainVersion="<germainux-version>"
germainApmBuildRegistry="<registry>"
germainEnvName="<environment-name>"

Use only the infrastructure versions approved for the installed GermainUX release.

📪 Messaging compatibility

GermainUX 2024.2 and later uses Kafka. Apache ActiveMQ applies only to earlier releases.

For GermainUX 2024.2 or later:

  • Configure the approved Kafka version.

  • Do not deploy ActiveMQ unless specifically required by Germain Support for an upgrade or compatibility scenario.

For an older GermainUX release, follow that release’s ActiveMQ requirements.

🏷️ Environment name

Set a unique, descriptive environment name:

germainEnvName="germain-qa"

Use different names for development, QA, staging, and production environments. The name may be used to generate directories, resource names, configuration roots, or namespaces.

Avoid changing it after the deployment has been initialized unless you intend to create a separate environment.

🗄️ Configure the database

The deployment can use its packaged database resources or an external database for the GermainUX configuration store.

📦 Packaged database

Retain the database deployment settings supplied with the package and verify that:

  • Persistent storage is configured.

  • The database credentials are protected.

  • The database pod has sufficient memory and storage.

  • Backup and recovery are configured when the environment must be retained.

🌐 External database

When using an external configuration database:

  1. Set the packaged MySQL replica count to 0.

    Older distributions may name this variable:

    mysqlReplicase=0
    

    Use the exact variable name present in your deploy-germain.sh file.

  2. Configure the external database hostname:

    germainDbHostname="<database-hostname>"
    
  3. Update common.properties with the correct connection details.

Example:

germain.config.url=jdbc:mysql://<database-host>:3306/APMCFG?rewriteBatchedStatements=true
germain.config.username=<database-user>
germain.config.password=<database-password>

Before deployment, confirm that:

  • Kubernetes workloads can resolve and reach the database hostname.

  • The database and schema exist.

  • The configured user has the required permissions.

  • TLS is enabled when required.

  • Firewalls permit the connection.

  • Credentials are stored using the approved secret-management mechanism.

Do not retain the example APMCFG password in a shared or production environment.

📧 Configure email

To enable email alerts and reports, update the SMTP settings in the included common.properties file.

Configure:

Setting

SMTP hostname

SMTP port

Authentication method

Username and password

Sender address

TLS or STARTTLS requirements

Store SMTP credentials as Kubernetes Secrets whenever supported. Email configuration is optional and can be completed after the initial deployment.

👀 Verify Kubernetes access

Confirm that kubectl targets the correct cluster:

kubectl config current-context
kubectl get nodes

Verify that all required nodes report:

Ready

Also confirm the target namespace:

kubectl get namespaces

Create or select the intended namespace according to the deployment package’s instructions.

Be especially careful when your workstation can access multiple development and production clusters.

📁 Generate the manifests

Run:

chmod +x deploy-germain.sh
./deploy-germain.sh

The script generates Kubernetes YAML files under a directory named after germainEnvName.

Before applying them, review the generated resources for:

Resource

Namespace

Image names and tags

Image-pull secrets

Resource requests and limits

Persistent-volume claims

StorageClass

Services and ports

Ingress or LoadBalancer configuration

ConfigMaps and Secrets

Health checks

Replica counts

Node selectors, tolerations, and affinity

Security contexts

Database and messaging settings

Do not assume that generated manifests are appropriate for production without review.

🚀 Deploy GermainUX

Apply the generated manifests in the required order.

1️⃣ Configuration

kubectl apply -f <germainEnvName>/configmap/

2️⃣ Infrastructure

kubectl apply -f <germainEnvName>/infra/

Wait for the infrastructure components to become ready before continuing:

kubectl get pods
kubectl get services
kubectl get persistentvolumeclaims

3️⃣ GermainUX components

kubectl apply -f <germainEnvName>/germain/

Monitor the rollout:

kubectl get pods -w

If the manifests use a dedicated namespace, add:

-n <namespace>

to the relevant kubectl commands.

✅ Validate the deployment

👁️ Check pods

kubectl get pods

All required pods should eventually report Running or Completed, as appropriate.

Investigate pods reporting:

Pending
CrashLoopBackOff
ImagePullBackOff
Error

⚙️ Check services

kubectl get services

Confirm that the expected ClusterIP, LoadBalancer, or NodePort services exist.

💾 Check persistent storage

kubectl get persistentvolumeclaims

All required claims should report:

Bound

🐛 Review a failing pod

kubectl describe pod <pod-name>
kubectl logs <pod-name>

For a pod containing multiple containers:

kubectl logs <pod-name> -c <container-name>

For a container that restarted:

kubectl logs <pod-name> --previous

🖥️ Open the GermainUX Workspace

At the end of a successful deployment, the script displays the URL used to access the GermainUX Workspace.

The default path is:

http://<germain-host>:8080/germainapm/workspace/

The actual hostname, protocol, and port depend on the generated Service or Ingress configuration.

An initial test deployment may use:

Username: admin
Password: admin

Change the default password immediately after the first successful sign-in. Do not expose an environment using default credentials to an untrusted network.

🛡️ Production requirements

Before using Kubernetes-hosted GermainUX in production, implement:

Requirement

Appropriately sized resource requests and limits

Multiple replicas for supported stateless components

Pod anti-affinity and topology-spread constraints

Pod disruption budgets

Persistent storage with suitable performance

Database and datastore backups

TLS for external and internal connections

Kubernetes Secrets or an external secret manager

NetworkPolicies

Restricted service accounts and RBAC

Non-root containers where supported

Image vulnerability scanning

Controlled image registries and immutable tags

Readiness, liveness, and startup probes

Centralized logs and metrics

Capacity and disk-usage alerts

Documented upgrade and rollback procedures

Disaster-recovery testing

The small-cluster configuration described on this page is not sufficient by itself for those requirements.

🔧 Troubleshooting

warning Pods remain pending

Check:

kubectl describe pod <pod-name>
kubectl get nodes
kubectl get persistentvolumeclaims

Common causes include:

  • Insufficient CPU or memory

  • Unbound persistent-volume claims

  • Node selectors that match no node

  • Missing tolerations

  • Namespace quotas

  • Image-pull secret errors

📦 Image cannot be pulled

Verify:

  • The image name and tag

  • Registry connectivity

  • Registry credentials

  • Image-pull secrets

  • Service-account configuration

  • Node access to the registry

🔗 GermainUX cannot reach an infrastructure service

Confirm:

  • The dependent pod is ready.

  • The Kubernetes Service exists.

  • The configured service hostname is correct.

  • The ports match.

  • NetworkPolicies allow the connection.

  • Authentication and TLS settings match.

  • The components are deployed in the expected namespace.

🚫 Workspace is inaccessible

Check:

kubectl get services
kubectl get ingress
kubectl describe ingress <ingress-name>

Also verify:

  • DNS resolution

  • Load balancer status

  • Ingress controller health

  • Firewall rules

  • TLS certificate configuration

  • Tomcat and Germain Enterprise logs

🔁 Configuration changes are not applied

After changing a source configuration file:

  1. Regenerate or update the relevant manifest.

  2. Apply it with kubectl apply.

  3. Confirm that the ConfigMap or Secret changed.

  4. Restart or roll out the affected deployment if it does not reload configuration dynamically.

  5. Verify the effective configuration in the application logs.

Source: Kubernetes Setup.

Component: Enterprise

Feature Availability: 2024.1