Minimal notes for installing this chart on an already-existing OpenStack
Kubernetes cluster (e.g. one provisioned by Azimuth).
This directory intentionally does not contain any tooling to create the
Kubernetes cluster itself (no Terraform/Kubespray/etc.) — use Azimuth (or
your own provisioning method) for that, then point helm install at the
resulting cluster.
- An existing Kubernetes cluster on OpenStack with the Cinder CSI driver installed (this is what Azimuth-provisioned clusters ship by default).
- Node scheduling:
values-openstack.yamlsetsnode_group.label_keyto Azimuth's native Cluster API node-group label (capi.stackhpc.com/node-group: web|worker), so no manual node labeling is needed on Azimuth. On a different OpenStack cluster without that label, either label nodesnodegroup=web-group/nodegroup=worker-groupyourself, or overridenode_group.*to match your cluster's own scheme (seeopenstudio-server/values.yamlfor the full set of options). - The
nfs-server-provisionersubchart is a separate vendored dependency and does NOT readnode_group.*— it has its own hardcoded default affinity.values-openstack.yamloverridesnfs-server-provisioner.affinitydirectly; if you change your node-group label scheme, update that override too or this pod will never schedule.
helm install openstudio-server ./openstudio-server -f openstack/values-openstack.yaml -n openstudio-serverSee values-openstack.yaml for the values this
sets, and the top-level README for general chart install
instructions.
For the Azimuth/OpenStack environment described in the handoff, the chart's
load_balancer path is not reliable. A working Terraform-based workaround is
provided in terraform-proxy-vm/: it
creates the proxy VM, security group, floating IP, and nginx config while
routing to the stable Kubernetes NodePort upstream rather than the unstable
Octavia VIP path. This is the recommended path until the platform-level
Octavia/LB issue is fixed.
The proxy VM's nginx upstream is the web Service NodePort on the node IPs
(default 32105, see nodeport_port in terraform-proxy-vm), so your values
file must set web_svc.type: NodePort and web_svc.nodePorts.http: 32105
(already in values-openstack.yaml.template). The chart's default Service type
is ClusterIP; if a values file lacks this, an upgrade silently drops the
NodePort and the proxy returns 502 Bad Gateway.
-
Proxy VM returns
504 Gateway Time-out: nginx's defaultproxy_read_timeoutis 60s. Under heavy load (thousands of workers hitting the single web pod) pages like/and/projects.jsoncan take >60s. The proxy template now sets 600s timeouts; on an existing VM addproxy_read_timeout 600s; proxy_send_timeout 600s;to thelocation /block in/etc/nginx/conf.d/proxy.confandsudo systemctl reload nginx(this patch only addresses the 504s; the template also setsclient_max_body_size 0so large analysis uploads aren't rejected — add it too if you need that, and monitor the proxy VM's disk since nginx buffers request bodies there). SSH in ascloud@<floating-ip>(the default user on the Aurora Rocky image, notrocky) with the private key for the VM'skeypair_name. If it is still slow, reduce load: raise the web pod's CPU/memory requests invalues-openstack.yaml(or lowerworker-hpamaxReplicas). -
Proxy VM returns
502 Bad Gatewayafter ahelm upgrade, but the web pod is Running: checkkubectl get svc web -n openstudio-server. If it isClusterIP, your values file is missingweb_svc.type: NodePortandweb_svc.nodePorts.http(match the proxy'snodeport_port, default32105). Add them (copy fromvalues-openstack.yaml.template) and re-run the upgrade with-n openstudio-server. -
NFS backend storage tier:
nfs-server-provisioner.persistence.storageClassselects the Cinder volume type for the NFS backend (and sonfs-pvc). The template useshdd(Cinder typelagos_volume, the regular HDD tier); db, redis and the registry stay onssd(Cinder typelagos_ssd). The chart createshddonly on theopenstackprovider and, likessd, only if it doesn't already exist. The same recreate/ownership troubleshooting below applies tohdd. Changing the class on an existing install does not migrate the NFS PVC; back up and reinstall. -
StorageClass "ssd" ... exists and cannot be imported into the current release: invalid ownership metadata: assdStorageClass from a previous/different release or namespace is still on the cluster. If nothing currently uses it (kubectl get pvc -A -o jsonpath='{range .items[?(@.spec.storageClassName=="ssd")]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'), delete it (kubectl delete storageclass ssd) and re-run install — Helm will recreate it with the correct ownership. -
StorageClass ... reclaimPolicy: Forbidden/volumeBindingMode: ... field is immutable: same root cause as above —reclaimPolicyandvolumeBindingModecan't be changed on an existing StorageClass. Delete and let Helm recreate it (same fix as above). -
ssdStorageClass missing (storageclass.storage.k8s.io "ssd" not found) andhelm upgrade/helm installdoes not recreate it: the chart only renders thessdStorageClass when alookupat render time doesn't find one already on the cluster (templates/storageclass/storageclass.yaml), so Helm never actually tracks/owns that object in the release manifest. If it's deleted out-of-band afterward — e.g. by an interruptedhelm uninstallwhose pre-delete hook rankubectl delete storageclass ssdbefore the hook itself failed to complete — no subsequenthelm upgradewill bring it back, since Helm has no record it needs to. Recreate it manually:kubectl apply -f - <<'YAML' apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ssd provisioner: cinder.csi.openstack.org reclaimPolicy: Delete allowVolumeExpansion: true volumeBindingMode: WaitForFirstConsumer YAML
Tracked as #108 (needs a design decision on whether to stop using
lookuphere). -
Helm v4
conflict occurred while applying object ... with subresource "scale": Helm v4 uses server-side apply by default. If a Deployment's.spec.replicasis currently owned bykube-controller-manager(via an active HPA, e.g. from a previous partially-failed install), Helm won't overwrite it without--force-conflictsonhelm upgrade --install. This is expected on essentially every routine upgrade once theweb/workerHPAs have scaled at least once — not just a failure-recovery edge case — so always include--force-conflictsonhelm upgradeagainst a live release:helm upgrade --install openstudio-server ./openstudio-server \ -f openstack/values-openstack.yaml -n openstudio-server --force-conflicts
Tracked as #110 (proper fix is to stop hardcoding
replicas:under active HPA control). -
If a previous
helm install/uninstalldidn't complete cleanly (e.g. pods stuckTerminatingdue to a container runtime issue), don't retry with a freshhelm installinto the same failed release — usehelm upgrade --install ... --force-conflictsto move it forward instead, after clearing any stuck pods (kubectl delete pods --all -n <namespace> --grace-period=0 --force). -
Resque UI looks frozen / simulations appear stalled: check for all three causes before assuming the cluster is wedged — throughput is usually non-zero but degraded.
- Zombie Resque workers (registered in Redis, pod no longer exists) hold
jobs that will never run. Compare
SMEMBERS resque:workersagainst live pods; snapshot Redis first, thenkubectl, to avoid race false-positives. - Unschedulable/unpullable worker pods pin
worker-hpaatmaxReplicasso it can't react. See theworker_hpa.maxReplicasnotes invalues-openstack.yaml.template. - Slow-by-design simulations. Wall-clock is dominated by the analysis's
building type (~15x spread;
SecondarySchoolaverages 159 min vsSmallOfficeat 9 min) against a uniform client-submitted 4hrun_workflow_timeout. Full write-up:docs/simulation-timeout-building-type-incident.md.
Note the Mongo database is
os_docker(notos_server), and thecontainerd-registry-configDaemonSet adds ~9,000 pods to everykubectl get podslisting — filter it out. - Zombie Resque workers (registered in Redis, pod no longer exists) hold
jobs that will never run. Compare