> ## Documentation Index
> Fetch the complete documentation index at: https://docs.germainux.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Setup

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

Components
[`Enterprise`](https://docs.germainux.com/main/deployment-on-premise)

Availability
2024.1

> **[Requirements](#requirements)**
>
> Environment and access needed

> **[Configure the deployment](#configure-the-deployment)**
>
> Edit deployment script variables

> **[Configure the database](#configure-the-database)**
>
> Packaged or external database

> **[Troubleshooting](#troubleshooting)**
>
> Fix deployment problems

**Kubernetes Setup**

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

> [!NOTE]
>
> **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:

* 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:

* Number of monitored users and applications
* Incoming telemetry volume
* Retention period
* Elasticsearch indexing and query workload
* Kafka throughput and retention
* High-availability requirements

> **Show all 9**
>
> * JVM heap requirements
> * Replication and backup overhead
> * Expected growth

## Obtain the deployment package

Download the Kubernetes distribution provided for your licensed GermainUX release:

```text theme={null}
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:

```text theme={null}
<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:

```text theme={null}
deploy-germain.sh
```

Update the deployment variables for the target environment.

A package may contain variables similar to:

```text theme={null}
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:

```text theme={null}
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:

```text theme={null}
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:

* 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:

```text theme={null}
kubectl config current-context
kubectl get nodes
```

Verify that all required nodes report:

```text theme={null}
Ready
```

Also confirm the target namespace:

```text theme={null}
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:

```text theme={null}
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:

* Namespace
* Image names and tags
* Image-pull secrets
* Resource requests and limits
* Persistent-volume claims
* StorageClass

> **Show all 14**
>
> * 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

```text theme={null}
kubectl apply -f <germainEnvName>/configmap/
```

### 2 Infrastructure

```text theme={null}
kubectl apply -f <germainEnvName>/infra/
```

Wait for the infrastructure components to become ready before continuing:

```text theme={null}
kubectl get pods
kubectl get services
kubectl get persistentvolumeclaims
```

### 3 GermainUX components

```text theme={null}
kubectl apply -f <germainEnvName>/germain/
```

Monitor the rollout:

```text theme={null}
kubectl get pods -w
```

If the manifests use a dedicated namespace, add:

```text theme={null}
-n <namespace>
```

to the relevant `kubectl` commands.

## Validate the deployment

### Check pods

```text theme={null}
kubectl get pods
```

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

Investigate pods reporting:

```text theme={null}
Pending
CrashLoopBackOff
ImagePullBackOff
Error
```

### Check services

```text theme={null}
kubectl get services
```

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

### Check persistent storage

```text theme={null}
kubectl get persistentvolumeclaims
```

All required claims should report:

```text theme={null}
Bound
```

### Review a failing pod

```text theme={null}
kubectl describe pod <pod-name>
kubectl logs <pod-name>
```

For a pod containing multiple containers:

```text theme={null}
kubectl logs <pod-name> -c <container-name>
```

For a container that restarted:

```text theme={null}
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:

```text theme={null}
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:

```text theme={null}
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:

* 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

> **Show all 18**
>
> * 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

### Pods remain pending

Check:

```text theme={null}
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:

```text theme={null}
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](https://docs.germainux.com/main/kubernetes-setup.md).

## Get Help

> **[Contact GermainUX Support](https://docs.germainux.com/main/support.md)**
>
> The Germain Team can help you set this up.

> **Can't find what you need?**
>
> Search all GermainUX docs with **Ctrl + K**, or use the feedback buttons at the bottom of this page to tell us what is missing.

The content of this document is proprietary to GERMAIN SOFTWARE.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.