Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions deploy/helm/cassandra/helm/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ spec:
{{- with .Values.cassandra.affinity }}
affinity: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.cassandra.topologySpreadConstraints }}
topologySpreadConstraints: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.cassandra.tolerations }}
tolerations: {{- toYaml . | nindent 8 }}
{{- end }}
Expand Down
5 changes: 5 additions & 0 deletions deploy/helm/cassandra/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ cassandra:
nodeSelector: {}
tolerations: []
affinity: {}
# Pod topology spread constraints. Empty by default; the self-managed Helmfile
# sets these (zone spread across topology.kubernetes.io/zone) via
# highAvailability.tier2.topologySpread when HA is on. Requires a
# WaitForFirstConsumer StorageClass so each zonal PV binds in the pod's zone.
topologySpreadConstraints: []

hooks:
initializeCluster:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

{{- if .Values.api.podDisruptionBudget.enabled }}
{{- $pdbMinAvail := .Values.api.podDisruptionBudget.minAvailable | toString }}
{{- $pdbMaxUnavail := .Values.api.podDisruptionBudget.maxUnavailable | toString }}
{{- if and (ne $pdbMinAvail "") (ne $pdbMaxUnavail "") }}
{{- fail "podDisruptionBudget: set exactly one of minAvailable or maxUnavailable, not both" }}
{{- end }}
{{- if and (eq $pdbMinAvail "") (eq $pdbMaxUnavail "") }}
{{- fail "podDisruptionBudget: set exactly one of minAvailable or maxUnavailable" }}
{{- end }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "nvcf-api.fullname" . }}
namespace: {{ include "nvcf-api.namespace" . }}
labels: {{- include "nvcf-api.labels" . | nindent 4 }}
spec:
{{- if ne $pdbMinAvail "" }}
minAvailable: {{ .Values.api.podDisruptionBudget.minAvailable }}
{{- else }}
maxUnavailable: {{ .Values.api.podDisruptionBudget.maxUnavailable }}
{{- end }}
selector:
matchLabels: {{- include "nvcf-api.selectorLabels" . | nindent 6 }}
{{- end }}
10 changes: 10 additions & 0 deletions deploy/helm/cloud-functions/nvcf-api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ api:
# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
replicaCount: 1

# PodDisruptionBudget for the API. Disabled by default; the self-managed
# Helmfile enables it (minAvailable 1) via highAvailability.stateless when HA
# is on. See deploy/stacks/self-managed/global.yaml.gotmpl.
podDisruptionBudget:
enabled: false
# minAvailable and maxUnavailable are mutually exclusive; set exactly one.
# Accepts an integer or a percentage string (e.g. 1 or "50%").
minAvailable: ""
maxUnavailable: ""

# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
image:
registry: "" # must be supplied
Expand Down
1 change: 1 addition & 0 deletions deploy/stacks/self-managed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ test:
@tests/nats-placement-tags.sh
@tests/nats-tls-wiring.sh
@tests/notary-image-repository.sh
@tests/ha-value-wiring.sh

test-published-charts:
@: "$${NVCF_PUBLISHED_CHART_REGISTRY:?NVCF_PUBLISHED_CHART_REGISTRY is required}"
Expand Down
47 changes: 47 additions & 0 deletions deploy/stacks/self-managed/environments/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -714,3 +714,50 @@ grpcproxy:
# an external compute-worker endpoint.
natsServiceURL: ""
workerConnectBaseURL: ""

# =============================================================================
# Control-plane high availability
# =============================================================================
# Resilience settings are exposed as a single highAvailability: block in
# self-managed Helmfile environment values.
# deploy/stacks/self-managed/global.yaml.gotmpl maps highAvailability.* onto
# chart values (replicaCount, affinity, PDB, update strategy).
#
# deploy/stacks/self-managed/
# ├── environments/<env>.yaml # highAvailability: configuration
# └── global.yaml.gotmpl # value mapping to charts
#
# mode: none (default) — keep existing env/chart replica, affinity,
# and PDB values (local / CI / BDD).
# preferred — HA sizing and placement below; hostname
# anti-affinity and zone topology spread are
# soft (still schedule if capacity is short).
# Requires ≥3 schedulable nodes.
# enforced — same HA sizing; hostname anti-affinity and zone
# topology spread are hard (Pending rather than
# packing / ignoring the constraint). Requires
# ≥3 schedulable nodes in ≥3 zones for the
# zone constraint to actually schedule.
#
# There is no per-component subtree beneath highAvailability: sizing and
# placement are derived uniformly from mode for every in-scope release (see
# global.yaml.gotmpl). Shared scheduling tuning is available under
# global.affinity / global.topologySpreadConstraints (class -> "all" -> the
# mode convention, same fallback pattern as global.nodeSelectors); an
# explicit {} / [] there suppresses the generated policy for that class.
# Component-shaped values elsewhere in this file remain the final per-release
# escape hatch for replica counts and PDBs.
#
# In-scope charts MUST expose the required value hooks. Leave mode: none
# for single-node installs.
# =============================================================================
highAvailability:
mode: none
nats:
jetstream:
# JetStream stream replica factor (RF), applied under HA to the stream
# creators (nvcf-api, invocation-service) via env so the worker/result
# streams they declare are replicated across the NATS cluster. Default
# 3: JetStream streams use Raft quorum, so RF=2 loses quorum on a
# single replica failure and provides no HA benefit over RF=1.
replicaFactor: 3
Loading
Loading