Kubernetes storage location information
Contents
- Overview
- 1. Storage Classes
- 2. Persistent Volume Claims (PVCs)
- 3. StatefulSet Volume Claim Templates
- 4. Per-Container Storage Details
- 5. ConfigMap-Backed File Mounts
- 6. Secret Mounts
- 7. Ephemeral (In-Memory) Volumes
- 8. Deployment Options Affecting Storage
- 9. Downloading Logs
- 10. Checking disk usage of volumes
- 11. Storage Summary Table
Overview
This document describes all storage locations used across the containers in a CAST Imaging Kubernetes deployment: persistent volumes, ConfigMap-backed configuration files, Secrets, and ephemeral (in-memory) volumes.
1. Storage Classes
Two storage class types are used, depending on the feature set enabled.
1.1 Block Storage Class (castimaging-ds)
Used for all standard persistent volumes (databases, logs, archives, etc.).
| Parameter | Value |
|---|---|
| Default name | castimaging-ds (configurable via DiskClassName) |
volumeBindingMode |
WaitForFirstConsumer |
reclaimPolicy |
Delete |
allowVolumeExpansion |
true |
CSI provisioner and parameters vary by cloud provider:
Provider (K8SProvider) |
Provisioner | Key Parameters |
|---|---|---|
| EKS (AWS) | ebs.csi.aws.com |
type: gp3, fsType: ext4 |
| AKS (Azure) | disk.csi.azure.com |
skuName: Premium_LRS, kind: Managed |
| GKE (Google) | pd.csi.storage.gke.io |
type: pd-standard (or pd-ssd) |
Storage class creation is controlled by the CreateStorageClass value (default: true). Set to false if the storage classes already exist in the cluster.
1.2 File Storage Class (castimaging-fs)
This allows the Analysis Node’s shared data directory to use ReadWriteMany (RWX) access mode, enabling horizontal scaling of analysis nodes.
| Provider | Provisioner | Notes |
|---|---|---|
| EKS | efs.csi.aws.com |
provisioningMode: efs-ap (creates an EFS Access Point), directoryPerms: "770", uid/gid: "10001". Requires EFSsystemID; optionally EFSaccessPointID for an explicit PV. Does not set allowVolumeExpansion (not supported by EFS access points) |
| AKS | file.csi.azure.com |
SMB protocol; mountOptions (dir_mode=0770, file_mode=0660, uid/gid=10001, mfsymlinks, cache=strict, nobrl); optional AKSresourceGroup / AKSstorageAccount / AKSsharedDatadirPV |
| GKE | filestore.csi.storage.gke.io |
tier: standard or premium |
2. Persistent Volume Claims (PVCs)
All PVCs are created in the deployment namespace with the annotation helm.sh/resource-policy: keep, ensuring they are not deleted on helm uninstall.
| PVC Name | Default Size | Storage Class | Access Mode | Service | Conditional |
|---|---|---|---|---|---|
pvc-shared-datadir |
100Gi | castimaging-fs |
SharedVolumeAccessMode (default ReadWriteMany) |
console-analysis-node, console-control-panel, console-service | Always created |
db-data |
128Gi | castimaging-ds |
RWO | console-postgres | Only if CastStorageService.enable: true |
pvc-imagingviewer-v3-server-log |
1Gi | castimaging-ds |
RWO | viewer-server | Always created |
pvc-imagingviewer-v3-etl-logs |
10Gi | castimaging-ds |
RWO | viewer-etl | Always created |
pvc-imagingviewer-v3-etl-csvarchive |
10Gi | castimaging-ds |
RWO | viewer-etl | Always created |
pvc-imagingviewer-v3-aimanager-logs |
2Gi | castimaging-ds |
RWO | viewer-aimanager | Always created |
pvc-imagingviewer-v3-api-logs |
2Gi | castimaging-ds |
RWO | viewer-api | Always created |
pvc-mcpserver-logs |
2Gi | castimaging-ds |
RWO | mcp-server | Only if McpServer.enable: true |
pvc-extendproxy-data |
10Gi | castimaging-ds |
RWO | extendproxy | Only if ExtendProxy.enable: true |
All PVC sizes are configurable through values.yaml (e.g. size_db_data, size_shared_datadir, etc.).
3. StatefulSet Volume Claim Templates
These volumes are provisioned automatically per pod replica via volumeClaimTemplates in StatefulSets. They use the castimaging-ds block storage class.
console-analysis-node (StatefulSet)
| Template Name | Default Size | Mount Path | Purpose |
|---|---|---|---|
castdir |
100Gi | /usr/share/CAST |
CAST installation directory: extensions, LISA data, analysis engine logs |
viewer-neo4j (StatefulSet)
A single neo4jdata volume (100Gi) is provisioned per pod. It is sub-divided using subPathExpr into three logical directories:
| Sub-Path | Mount Path | Purpose |
|---|---|---|
logs |
/var/lib/neo4j/logs |
Neo4j operational logs |
neo4jdata |
/var/lib/neo4j/config/neo4j5_data |
Neo4j graph database data files |
csvarchive |
/var/lib/neo4j/config/csv/archive |
Archived CSV import files |
4. Per-Container Storage Details
4.1 console-postgres
The PostgreSQL database server used by all Console services and Keycloak.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
db-data |
PVC (db-data, 128Gi) |
/var/lib/postgresql/data (subPath: postgres) |
Database data files |
pgconf |
ConfigMap (console-v3-postgresqlconf) |
/usr/share/postgresql/postgresql.conf.sample |
Custom PostgreSQL configuration |
pginit |
ConfigMap (console-v3-init-db) |
/docker-entrypoint-initdb.d/init-db.sh |
Database initialization script (users, databases, grants) |
dshm |
EmptyDir (Memory, 4G) | /dev/shm |
Shared memory for PostgreSQL |
db-creds |
Secret (imaging-pwd-sec) |
/opt/secrets |
Database passwords, read-only |
postgres-ssl |
EmptyDir | /var/lib/postgresql/ssl |
Self-signed SSL certificate/key generated at startup by the generate-ssl-cert init container. Only when CastStorageService.ssl: true |
pghbaconf |
ConfigMap (console-v3-pghbaconf) |
/etc/postgresql/pg_hba.conf |
Host-based authentication file requiring SSL connections. Only when CastStorageService.ssl: true |
The
db-dataPVC is only created whenCastStorageService.enable: true. When using an external PostgreSQL instance (CustomPostgres.enable: true), no PVC is created and a separate init script (init-db-custom-pg.sh) is executed as an init container to set up the required users and databases on the external server.
4.2 console-analysis-node
The CAST analysis engine. Runs as a StatefulSet.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
castdir |
VolumeClaimTemplate (100Gi) | /usr/share/CAST |
CAST engine binaries, extensions, logs, LISA data |
shared-datadir |
PVC (pvc-shared-datadir, 100Gi) |
/opt/cast/shared |
Shared analysis workspace: delivery, deploy, and common-data folders |
dshm |
EmptyDir (Memory, 1G) | /dev/shm |
Shared memory for analysis processing |
The pvc-shared-datadir sub-directories used at runtime:
| Sub-directory | Path | Purpose |
|---|---|---|
| Delivery | /opt/cast/shared/delivery |
Source code and artifacts delivered for analysis |
| Deploy | /opt/cast/shared/deploy |
Analysis deployment output |
| Common data | /opt/cast/shared/common-data |
Shared configuration and data across analysis nodes |
Before version 3.6.0: when AnalysisNodeFS.enable: true, pvc-shared-datadir switches to ReadWriteMany (file storage class), allowing multiple Analysis Node replicas to share the same workspace. When disabled (default), it uses ReadWriteOnce block storage and only a single Analysis Node replica is supported.
Starting from 3.6.0: ReadWriteMany access becomes mandatory for the pvc-shared-datadir PVC and a file storage class has to be used for this volume (AnalysisNodeFS.enable option is removed).
The analysisnode-upgrade-script ConfigMap is mounted into a postgres-upgrade init container (see Section 5).
4.3 viewer-neo4j
The graph database for the Imaging Viewer. Runs as a StatefulSet.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
neo4jdata (subPath: logs) |
VolumeClaimTemplate (100Gi) | /var/lib/neo4j/logs |
Neo4j logs |
neo4jdata (subPath: neo4jdata) |
VolumeClaimTemplate (100Gi) | /var/lib/neo4j/config/neo4j5_data |
Graph database data files |
neo4jdata (subPath: csvarchive) |
VolumeClaimTemplate (100Gi) | /var/lib/neo4j/config/csv/archive |
Archived CSV files after import |
All three paths share a single underlying 100Gi PVC via sub-paths.
4.4 viewer-server
The main Imaging Viewer frontend and backend service, fronted by Nginx.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
log |
PVC (pvc-imagingviewer-v3-server-log, 1Gi) |
/opt/imaging/imaging-service/logs |
Application and Nginx access/error logs |
servernginxconf |
ConfigMap (servernginxconf) |
/opt/imaging/config/nginx/conf/nginx.conf |
Nginx reverse-proxy configuration |
4.5 viewer-etl
The ETL (Extract, Transform, Load) service responsible for importing analysis data into Neo4j.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
logdir |
PVC (pvc-imagingviewer-v3-etl-logs, 10Gi) |
/opt/imaging/imaging-etl/logs |
ETL operational logs |
csvarchive |
PVC (pvc-imagingviewer-v3-etl-csvarchive, 10Gi) |
/opt/imaging/imaging-etl/upload/archive |
Archived CSV files after they have been processed and loaded |
4.6 viewer-aimanager
The AI/enrichment manager service.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
logdir |
PVC (pvc-imagingviewer-v3-aimanager-logs, 2Gi) |
/opt/imaging/open_ai-manager/logs |
AI Manager operational logs |
4.7 viewer-api
The public REST API service for querying the Imaging graph.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
logdir |
PVC (pvc-imagingviewer-v3-api-logs, 2Gi) |
/opt/imaging/imaging-api/logs |
API service operational logs |
4.8 mcp-server
The Model Context Protocol server. Only deployed when McpServer.enable: true.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
logdir |
PVC (pvc-mcpserver-logs, 2Gi) |
/app/logs |
MCP server operational logs |
mcpserverappconfig |
ConfigMap (mcpserverappconfig) |
/app/server/config/app.config |
MCP server application configuration |
4.9 extendproxy
The CAST Extend proxy service. Only deployed when ExtendProxy.enable: true.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
extendproxy |
PVC (pvc-extendproxy-data, 10Gi) |
/opt/cast_extend_proxy/data |
Proxy cache, configuration, and runtime data |
4.10 console-control-panel
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
shared-datadir |
PVC (pvc-shared-datadir, 100Gi) |
/opt/cast/shared |
Audit trail data (common-data sub-directory) and other data shared with console-analysis-node and console-service |
There is no longer a dedicated PVC for console-control-panel: audit trail data is stored under /opt/cast/shared/common-data on the shared pvc-shared-datadir volume. If a pvc-controlpanel-audit-trails PVC still exists from a prior installation, it is orphaned and no longer mounted by this chart.
Init containers use the contexturl-controlpanel-update-script and contexturl-keycloak-update-script ConfigMap-backed SQL scripts to update context URLs in the PostgreSQL database on startup (see Section 5).
4.11 console-authentication-service
No persistent volumes are mounted in the main container.
4.12 console-service
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
shared-datadir |
PVC (pvc-shared-datadir, 100Gi) |
/opt/cast/shared |
Shared configuration and data across analysis nodes, console-control-panel, and Console service |
An init container also uses the contexturl-controlpanel-update-script, contexturl-keycloak-update-script, and license-extend-update-script ConfigMap-backed SQL scripts (see Section 5).
4.13 console-gateway-service, console-sso-service, console-dashboards
None of these services mount persistent volumes. They rely entirely on database-backed state and environment variable configuration.
A separate, one-time keycloak-init-job Kubernetes Job (not part of the console-sso-service Deployment) mounts a keycloak-init-script ConfigMap at /init-keycloak.sh and uses it to bootstrap the Keycloak realm on first install. See Section 5.
4.14 proxy-exclusions-cronjob
A suspended CronJob (schedule intentionally invalid) that can be triggered manually with kubectl create job --from=cronjob/proxy-exclusions-cronjob to refresh the reverse-proxy’s non_proxy_hosts list from the currently registered service subnets. It mounts no PVC.
| Volume | Type | Mount Path | Purpose |
|---|---|---|---|
proxy-exclusions-update-script |
ConfigMap (proxy-exclusions-update-script) |
/proxy-exclusions-update-script.sh |
Script that discovers registered service subnets and updates control_panel.settings.non_proxy_hosts |
5. ConfigMap-Backed File Mounts
The following ConfigMaps are mounted as files into containers or init containers.
| ConfigMap | Mounted In | Mount Path | Content |
|---|---|---|---|
console-v3-postgresqlconf |
console-postgres |
/usr/share/postgresql/postgresql.conf.sample |
Tuned PostgreSQL configuration (memory, WAL, logging, auto_explain) |
console-v3-init-db |
console-postgres (init via docker-entrypoint-initdb.d) |
/docker-entrypoint-initdb.d/init-db.sh |
Creates operator, guest, keycloak users and the keycloak database on first startup |
init-db-custom-pg |
Init container in console-postgres |
Executed as a script | Used when CustomPostgres.enable: true to initialize users/databases on an external PostgreSQL server |
console-v3-pghbaconf |
console-postgres |
/etc/postgresql/pg_hba.conf |
Host-based authentication file requiring SSL. Only when CastStorageService.ssl: true |
contexturl-controlpanel-update-script |
Init container in console-control-panel and console-service |
/home/imaging/sql/contexturl-controlpanel-update-script.sql |
Sets keycloak.uri property in control_panel.properties |
contexturl-keycloak-update-script |
Init container in console-control-panel and console-service |
/home/imaging/sql/contexturl-keycloak-update-script.sql |
Removes frontendUrl from Keycloak realm attributes |
license-extend-update-script |
Init container in console-service |
/home/imaging/sql/license-extend-update-script.sql |
Runs license/extend-related update SQL against the postgres database |
analysisnode-upgrade-script |
Init container in console-analysis-node |
/home/imaging/sql/analysisnode-upgrade-script.sql |
Runs schema upgrade SQL on the postgres database |
servernginxconf |
viewer-server |
/opt/imaging/config/nginx/conf/nginx.conf |
Nginx reverse-proxy rules for routing API, ETL, Neo4j, AI, login, SAML, and sourcecode endpoints |
mcpserverappconfig |
mcp-server |
/app/server/config/app.config |
MCP server runtime configuration (ports, control panel host, domain, etc.) |
keycloak-init-script |
One-time keycloak-init-job Job |
/init-keycloak.sh |
Bootstraps the Keycloak realm on first install |
proxy-exclusions-update-script |
proxy-exclusions-cronjob (manually triggered) |
/proxy-exclusions-update-script.sh |
Refreshes control_panel.settings.non_proxy_hosts from registered service subnets |
6. Secret Mounts
The Secret imaging-pwd-sec is used both as environment variable source and as a file-system mount.
| Secret Key | Used By (env var) | Mounted As File In |
|---|---|---|
postgres-db-password |
console-postgres, postgres-upgrade init container in console-analysis-node |
console-postgres → /opt/secrets/postgres-db-password |
operator-db-password |
console-authentication-service, console-control-panel, console-service, console-sso-service, postgres-upgrade init container in console-analysis-node, keycloak-init-job, proxy-exclusions-cronjob |
console-postgres → /opt/secrets/operator-db-password |
operator-db-password-crypted2 |
console-control-panel (DB_ENCRYPTED_PASSWORD) |
— |
guest-db-password |
(init script only) | console-postgres → /opt/secrets/guest-db-password |
keycloak-db-password |
(init script only) | console-postgres → /opt/secrets/keycloak-db-password |
keycloak-admin-password |
console-authentication-service, console-sso-service, keycloak-init-job |
— |
neo4j-password |
viewer-neo4j, viewer-server, viewer-etl, viewer-aimanager, viewer-api |
— |
smtp-password |
console-control-panel (SPRING_MAIL_PASSWORD). Only present when SMTP.enable: true |
— |
The file-system mount (/opt/secrets) in console-postgres is read-only and used by the init script to read passwords at startup.
If you provide your own Secret via existingSecret instead of letting the chart create imaging-pwd-sec, it must also define the operator-db-password-crypted2 key.
7. Ephemeral (In-Memory) Volumes
| Volume Name | Container | Type | Size | Mount Path | Purpose |
|---|---|---|---|---|---|
dshm |
console-postgres |
EmptyDir (Memory) | 4G | /dev/shm |
PostgreSQL shared memory (required for work_mem, parallel queries) |
dshm |
console-analysis-node |
EmptyDir (Memory) | 1G | /dev/shm |
Analysis engine shared memory |
postgres-ssl |
console-postgres |
EmptyDir | — | /var/lib/postgresql/ssl |
Self-signed SSL certificate/key. Only when CastStorageService.ssl: true |
When RestrictedSecurityMode: true, most Deployments/StatefulSets additionally mount several small EmptyDir volumes (e.g. tmp, run) to satisfy a read-only root filesystem. These are implementation details of the hardened security context and do not hold persistent data.
8. Deployment Options Affecting Storage
8.1 Cloud Provider (K8SProvider)
Controls which CSI drivers are used for the castimaging-ds (and optionally castimaging-fs) storage classes. Accepted values: EKS, AKS, GKE.
8.2 Built-in vs. External PostgreSQL
| Option | Behavior |
|---|---|
CastStorageService.enable: true (default) |
PostgreSQL is deployed as part of the Helm chart. The db-data PVC (128Gi) is created automatically. |
CastStorageService.enable: false + CustomPostgres.enable: true |
No PostgreSQL deployment and no db-data PVC. An init container runs init-db-custom-pg.sh against the external host specified by CustomPostgres.host / CustomPostgres.port. |
8.3 Analysis Node Shared File Storage (AnalysisNodeFS.enable) - Imaging version < 3.6.0
| Option | pvc-shared-datadir Access Mode |
Storage Class | Supports Multiple Analysis Nodes |
|---|---|---|---|
false (default) |
ReadWriteOnce |
castimaging-ds (block) |
No — single node only |
true |
ReadWriteMany |
castimaging-fs (file) |
Yes |
When enabling file storage on EKS, the EFSsystemID value is required. Optionally, providing EFSaccessPointID causes an explicit PersistentVolume (pv-shared-datadir) to be created.
On AKS, if auto-provisioning is not available, set AnalysisNodeFS.AKSsharedDatadirPV.create: true and provide secretName and shareName to create an explicit PV backed by an Azure File Share.
Starting from 3.6.0: ReadWriteMany access becomes mandatory for the pvc-shared-datadir PVC and a file storage class has to be used for this volume (AnalysisNodeFS.enable option is removed).
8.4 Embedded PostgreSQL SSL (CastStorageService.ssl)
| Option | Behavior |
|---|---|
CastStorageService.ssl: false (default) |
No SSL enforcement on the embedded PostgreSQL server. |
CastStorageService.ssl: true |
A generate-ssl-cert init container generates a self-signed certificate into the postgres-ssl EmptyDir; PostgreSQL is started with ssl=on and hba_file pointed at the pghbaconf ConfigMap requiring SSL connections. |
This is independent of CreatePostgresLoadBalancer, which exposes the embedded PostgreSQL service externally.
8.5 Optional Components
| Component | Controlling Value | PVC Created |
|---|---|---|
| Extend Proxy | ExtendProxy.enable: true |
pvc-extendproxy-data (10Gi) |
| MCP Server | McpServer.enable: true |
pvc-mcpserver-logs (2Gi) |
8.6 Storage Class Creation
Set CreateStorageClass: false to skip storage class creation (e.g., if the cluster admin has pre-provisioned them). The DiskClassName and FileClassName values must still match the names of the existing storage classes.
9. Downloading Logs
There are 2 types of logs:
- Standard output logs: correspond to the log avialable from kubernetes and containing anything services are writing to the standard output.
- Specific log files: some services have addtional logs available, stored in persistent files: console-postgres, console-analysis-node, viewer-neo4j, viewer-server, viewer-etl
The following commands can be used to download those logs. Run them from the machine where kubectl is configured and authenticated against your cluster.
Namespace: All commands assume the namespace castimaging-v3. Adjust if your deployment uses a different namespace.
Standard output logs (from all pods)
kubectl logs -l app=castimaging --all-containers=true --prefix=true --tail=-1 -n castimaging-v3 > all-pods-std-output.log
Specific log files stored inside pods
Postgres — postgres database logs stored in the db-data volume:
Adjust the console-postgres pod name if needed.
Linux:
kubectl cp -n castimaging-v3 \
console-postgres-0:/var/lib/postgresql/data/log \
./Logs/postgres
Windows (PowerShell):
kubectl cp -n castimaging-v3 `
console-postgres-0:/var/lib/postgresql/data/log `
./Logs/postgres
Analysis Node — CAST engine logs stored in the castdir volume:
Linux:
kubectl cp -n castimaging-v3 \
console-analysis-node-core-0:/usr/share/CAST/CAST/Logs \
./Logs/console-analysis-node
Windows (PowerShell):
kubectl cp -n castimaging-v3 `
console-analysis-node-core-0:/usr/share/CAST/CAST/Logs `
./Logs/console-analysis-node
Neo4j — graph database logs stored in the neo4jdata volume:
Linux:
kubectl cp -n castimaging-v3 \
viewer-neo4j-core-0:/var/lib/neo4j/logs \
./Logs/viewer-neo4j
Windows (PowerShell):
kubectl cp -n castimaging-v3 `
viewer-neo4j-core-0:/var/lib/neo4j/logs `
./Logs/viewer-neo4j
Viewer Server — Nginx access/error logs and application logs:
Linux:
POD=$(kubectl get pod -n castimaging-v3 -l imaging.service=viewer-server -o jsonpath='{.items[0].metadata.name}')
kubectl cp -n castimaging-v3 $POD:/opt/imaging/imaging-service/logs ./Logs/viewer-server
Windows (PowerShell):
$POD = kubectl get pod -n castimaging-v3 -l imaging.service=viewer-server -o jsonpath='{.items[0].metadata.name}'
kubectl cp -n castimaging-v3 "${POD}:/opt/imaging/imaging-service/logs" ./Logs/viewer-server
Viewer ETL — ETL service operational logs:
Linux:
POD=$(kubectl get pod -n castimaging-v3 -l imaging.service=viewer-etl -o jsonpath='{.items[0].metadata.name}')
kubectl cp -n castimaging-v3 $POD:/opt/imaging/imaging-etl/logs ./Logs/viewer-etl
Windows (PowerShell):
$POD = kubectl get pod -n castimaging-v3 -l imaging.service=viewer-etl -o jsonpath='{.items[0].metadata.name}'
kubectl cp -n castimaging-v3 "${POD}:/opt/imaging/imaging-etl/logs" ./Logs/viewer-etl
Collect all logs in one shot
Linux — save the following as collect-logs.sh and run with bash collect-logs.sh:
#!/bin/bash
NAMESPACE="${1:-castimaging-v3}"
DEST="./Logs/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$DEST"
# neo4j
echo "=== Pod: viewer-neo4j-core-0 ==="
kubectl exec viewer-neo4j-core-0 -n $NAMESPACE -- tar cf - /var/lib/neo4j/logs > $DEST/viewer-neo4j-logs.tar
# Analysis nodes
for pod in $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | grep '^console-analysis-node-core-'); do
echo "=== Pod: $pod ==="
kubectl exec $pod -n $NAMESPACE -- tar cf - /usr/share/CAST/CAST/Logs > $DEST/$pod-Logs.tar
done
# Other pods
declare -A LOG_PATHS=(
[viewer-server]="/opt/imaging/imaging-service/logs"
[viewer-etl]="/opt/imaging/imaging-etl/logs"
[console-postgres]="/var/lib/postgresql/data/log"
)
for SVC in "${!LOG_PATHS[@]}"; do
POD=$(kubectl get pod -n $NAMESPACE -l imaging.service=$SVC -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
if [ -z "$POD" ]; then
echo "No pod found for $SVC, skipping."
continue
fi
echo "=== Copying logs from $POD ($SVC) ==="
kubectl cp -n $NAMESPACE $POD:${LOG_PATHS[$SVC]} $DEST/$SVC
done
# Retrieving standard output log from all pods
echo "=== Retrieving std-out logs from all pods ==="
for pod in $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}'); do
echo "=== Pod: $pod ===" >> $DEST/all-pods-stdout.log
kubectl logs $pod -n $NAMESPACE --all-containers=true --prefix=true --tail=-1 >> $DEST/all-pods-stdout.log
done
echo "All logs collected in $DEST"
Windows — save the following as collect-logs.ps1 and run with powershell -File collect-logs.ps1:
param (
[string]$NAMESPACE = "castimaging-v3"
)
$DEST = "./Logs/$(Get-Date -Format 'yyyyMMdd_HHmmss')"
New-Item -ItemType Directory -Force -Path $DEST | Out-Null
# neo4j
Write-Host "=== Pod: viewer-neo4j-core-0 ==="
$CmdString = "kubectl exec viewer-neo4j-core-0 -n $NAMESPACE -- sh -c `"tar cf - /var/lib/neo4j/logs 2>/dev/null`" > `"$DEST\viewer-neo4j-logs.tar`""
# Execute it via cmd.exe to preserve the binary stream
cmd.exe /c $CmdString
# Analysis nodes
$pods = kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}' |
ForEach-Object { $_ -split ' ' } |
Where-Object { $_ -match '^console-analysis-node' }
foreach ($pod in $pods) {
Write-Host "=== Pod: $pod ==="
$CmdString = "kubectl exec $pod -n $NAMESPACE -- sh -c `"tar cf - /usr/share/CAST/CAST/Logs 2>/dev/null`" > `"$DEST\$pod-Logs.tar`""
cmd.exe /c $CmdString
}
# Other pods
$SERVICES = @{
"viewer-server" = "/opt/imaging/imaging-service/logs"
"viewer-etl" = "/opt/imaging/imaging-etl/logs"
"console-postgres" = "/var/lib/postgresql/data/log"
}
foreach ($SVC in $SERVICES.Keys) {
$POD = kubectl get pod -n $NAMESPACE -l "imaging.service=$SVC" -o jsonpath='{.items[0].metadata.name}' 2>$null
if (-not $POD) {
Write-Host "No pod found for $SVC, skipping."
continue
}
Write-Host "=== Copying logs from $POD ($SVC) ==="
kubectl cp -n $NAMESPACE "${POD}:$($SERVICES[$SVC])" "$DEST/$SVC"
}
# Retrieving standard output log from all pods
Write-Host "=== Retrieving std-out logs from all pods ==="
foreach ($pod in $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}').Split(' ')) {
Add-Content $DEST/all-pods-stdout.log "=== Pod: $pod ==="
kubectl logs $pod -n $NAMESPACE --all-containers=true --prefix=true --tail=-1 | Add-Content $DEST/all-pods-stdout.log
}
Write-Host "All logs collected in $DEST"
10. Checking disk usage of volumes
The following commands check the disk usage of main volumes. Run them from the machine where kubectl is configured and authenticated against your cluster.
kubectl exec -it console-analysis-node-core-0 -n castimaging-v3 -- df -h /opt/cast/shared
kubectl exec -it console-analysis-node-core-0 -n castimaging-v3 -- df -h /usr/share/CAST
kubectl exec -it console-postgres-0 -n castimaging-v3 -- df -h /var/lib/postgresql/data
kubectl exec -it viewer-neo4j-core-0 -n castimaging-v3 -- df -h /var/lib/neo4j/config/neo4j5_data
kubectl exec -it viewer-etl-xxxxx -n castimaging-v3 -- df -h /opt/imaging/imaging-etl/logs
kubectl exec -it viewer-etl-xxxxx -n castimaging-v3 -- df -h /opt/imaging/imaging-etl/upload/archive
kubectl exec -it extendproxy-xxxxx -n castimaging-v3 -- df -h /opt/cast_extend_proxy/data
11. Storage Summary Table
| Container | PVC(s) | VolumeClaimTemplate(s) | ConfigMap Files | Secret Files | EmptyDir |
|---|---|---|---|---|---|
console-postgres |
db-data ¹ |
— | postgresql.conf.sample, init-db.sh |
/opt/secrets (all DB passwords) |
/dev/shm (4G) |
console-control-panel |
pvc-shared-datadir (shared) |
— | SQL update scripts (init containers) | — | — |
console-authentication-service |
— | — | — | — | — |
console-gateway-service |
— | — | — | — | — |
console-sso-service |
— | — | — | — | — |
console-dashboards |
— | — | — | — | — |
keycloak-init-job (one-time Job) |
— | — | init-keycloak.sh |
— | — |
console-service |
pvc-shared-datadir (shared) |
— | SQL update scripts (init containers) | — | — |
proxy-exclusions-cronjob (manual trigger) |
— | — | proxy-exclusions-update-script.sh |
— | — |
console-analysis-node |
pvc-shared-datadir |
castdir (100Gi) |
SQL upgrade script (init container) | — | /dev/shm (1G) |
viewer-neo4j |
— | neo4jdata (100Gi) |
— | — | — |
viewer-server |
pvc-imagingviewer-v3-server-log |
— | nginx.conf |
— | — |
viewer-etl |
pvc-imagingviewer-v3-etl-logs, pvc-imagingviewer-v3-etl-csvarchive |
— | — | — | — |
viewer-aimanager |
pvc-imagingviewer-v3-aimanager-logs |
— | — | — | — |
viewer-api |
pvc-imagingviewer-v3-api-logs |
— | — | — | — |
mcp-server ² |
pvc-mcpserver-logs |
— | app.config |
— | — |
extendproxy ³ |
pvc-extendproxy-data |
— | — | — | — |
Notes:
db-dataPVC only exists whenCastStorageService.enable: true.mcp-serverand its PVC only deployed whenMcpServer.enable: true.extendproxyand its PVC only deployed whenExtendProxy.enable: true.console-control-panelandconsole-servicedo not have dedicated PVCs — they mount the sharedpvc-shared-datadirvolume also used byconsole-analysis-node(Section 3).