Unverified Commit 3b3d0f2e authored by julienmancuso's avatar julienmancuso Committed by GitHub
Browse files

feat: fix helm chart for graph deployment (#1866)

parent 7183683e
......@@ -17,10 +17,41 @@ limitations under the License.
# Manual Helm Deployment
This directory contains Helm charts for manually deploying Dynamo inference graphs to Kubernetes. These charts are used when you need full control over your deployment configuration.
This directory contains Helm charts for manually deploying Dynamo inference graphs to Kubernetes.
This approach allows you to install Dynamo directly using a DynamoGraphDeploymentCRD values file, which is useful for quick deployments or testing specific configurations.
### Prerequisites
- Helm 3.0+
- Kubernetes 1.16+
- ETCD v3.5+ (without auth)
- NATS v2.10+ (with jetstream enabled)
### Basic Installation
```bash
helm upgrade --install dynamo-graph ./deploy/helm/chart -n dynamo-cloud -f ./examples/vllm_v1/deploy/agg.yaml
```
### Customizable Properties
You can override the default configuration by setting the following properties:
```bash
helm upgrade --install dynamo-graph ./deploy/helm/chart -n dynamo-cloud \
-f ./examples/vllm_v1/deploy/agg.yaml \
--set "imagePullSecrets[0].name=docker-secret-1" \
--set etcdAddr="my-etcd-service:2379" \
--set natsAddr="nats://my-nats-service:4222"
```
#### Available Properties
| Property | Description | Example |
|----------|-------------|---------|
| `imagePullSecrets` | Array of image pull secrets for accessing private registries | `imagePullSecrets[0].name=docker-secret-1` |
| `etcdAddr` | Address of the etcd service | `dynamo-platform-etcd:2379` |
| `natsAddr` | Address of the NATS messaging service | `nats://dynamo-platform-nats:4222` |
For detailed documentation on manual deployment using Helm charts, please refer to:
- [Manual Helm Deployment Guide](../../docs/guides/dynamo_deploy/manual_helm_deployment.md)
- [Minikube Setup Guide](../../docs/guides/dynamo_deploy/minikube.md)
For a quick start example, see [examples/hello_world/README.md#deploying-to-kubernetes-using-helm](../../examples/hello_world/README.md#deploying-to-kubernetes-using-helm)
\ No newline at end of file
......@@ -14,8 +14,8 @@
# limitations under the License.
apiVersion: v2
name: dynamo-pipeline
description: A Helm chart to deploy a Dynamo pipeline on Kubernetes
name: dynamo-graph
description: A Helm chart to deploy a Dynamo graph on Kubernetes
type: application
version: 0.1.0
appVersion: 1.0.0
version: 0.3.2
appVersion: 0.3.2
......@@ -12,89 +12,71 @@
# 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.
{{- range .Values.services }}
{{- range $serviceName, $serviceSpec := .Values.spec.services }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $.Release.Name }}-{{ .name | lower }}
name: {{ $.Release.Name }}-{{ $serviceName | lower }}
labels:
app: {{ $.Release.Name }}-{{ .name | lower }}
app: {{ $.Release.Name }}-{{ $serviceName | lower }}
spec:
replicas: {{ .config.workers | default 1 }}
replicas: {{ $serviceSpec.replicas }}
selector:
matchLabels:
app: {{ $.Release.Name }}-{{ .name | lower }}
app: {{ $.Release.Name }}-{{ $serviceName | lower }}
template:
metadata:
labels:
app: {{ $.Release.Name }}-{{ .name | lower }}
app: {{ $.Release.Name }}-{{ $serviceName | lower }}
spec:
# pull secrets
{{- if $.Values.imagePullSecrets }}
imagePullSecrets:
{{- range $.Values.imagePullSecrets }}
- name: {{ .name }}
{{ $.Values.imagePullSecrets | toYaml | nindent 8 }}
{{- end }}
securityContext:
runAsUser: 0
containers:
- name: {{ $.Release.Name }}-{{ .name | lower }}
image: {{ $.Values.image }}
- name: {{ $.Release.Name }}-{{ $serviceName | lower }}
image: {{ $serviceSpec.extraPodSpec.mainContainer.image }}
workingDir: {{ $serviceSpec.extraPodSpec.mainContainer.workingDir }}
args:
{{ if $.Values.configFilePath }}
- cd src && uv run dynamo serve --service-name {{ .name }} {{ $.Values.dynamoIdentifier }} -f {{ $.Values.configFilePath }}
{{ else }}
- cd src && uv run dynamo serve --service-name {{ .name }} {{ $.Values.dynamoIdentifier }}
{{ end }}
command:
- sh
- -c
{{ if .config.resources }}
{{- $serviceSpec.extraPodSpec.mainContainer.args | toYaml | nindent 8 }}
{{ if $serviceSpec.resources }}
resources:
requests:
{{ if .config.resources.cpu }}
cpu: "{{ .config.resources.cpu }}"
{{ if $serviceSpec.resources.cpu }}
cpu: "{{ $serviceSpec.resources.cpu }}"
{{ end }}
{{ if .config.resources.memory }}
memory: "{{ .config.resources.memory }}"
{{ if $serviceSpec.resources.memory }}
memory: "{{ $serviceSpec.resources.memory }}"
{{ end }}
{{ if .config.resources.gpu }}
nvidia.com/gpu: "{{ .config.resources.gpu }}"
{{ if $serviceSpec.resources.gpu }}
nvidia.com/gpu: "{{ $serviceSpec.resources.gpu }}"
{{ end }}
limits:
{{ if .config.resources.cpu }}
cpu: "{{ .config.resources.cpu }}"
{{ if $serviceSpec.resources.cpu }}
cpu: "{{ $serviceSpec.resources.cpu }}"
{{ end }}
{{ if .config.resources.memory }}
memory: "{{ .config.resources.memory }}"
{{ if $serviceSpec.resources.memory }}
memory: "{{ $serviceSpec.resources.memory }}"
{{ end }}
{{ if .config.resources.gpu }}
nvidia.com/gpu: "{{ .config.resources.gpu }}"
{{ if $serviceSpec.resources.gpu }}
nvidia.com/gpu: "{{ $serviceSpec.resources.gpu }}"
{{ end }}
{{ end }}
env:
{{- if and .config.traffic .config.traffic.timeout }}
- name: TRAFFIC_TIMEOUT
value: "{{ .config.traffic.timeout }}"
{{- end }}
{{- if and .config.dynamo .config.dynamo.enabled }}
- name: DYNAMO_NAMESPACE
value: "{{ .config.dynamo.namespace }}"
- name: DYNAMO_NAME
value: "{{ .config.dynamo.name }}"
{{- end }}
{{- if .config.workers }}
- name: WORKERS
value: "{{ .config.workers }}"
{{- if $serviceSpec.envFromSecret }}
envFrom:
- secretRef:
name: {{ $serviceSpec.envFromSecret }}
{{- end }}
env:
- name: DYNAMO_PORT
value: "3000"
{{- if $.Values.natsAddr }}
- name: NATS_SERVER
value: {{ $.Values.natsAddr }}
{{- end }}
value: "{{ $.Values.dynamoPort | default 8000 }}"
{{- if $.Values.etcdAddr }}
- name: ETCD_ENDPOINTS
value: {{ $.Values.etcdAddr }}
value: "{{ $.Values.etcdAddr }}"
{{- end }}
{{- if $.Values.natsAddr }}
- name: NATS_SERVER
value: "{{ $.Values.natsAddr }}"
{{- end }}
---
{{- end }}
......@@ -12,17 +12,22 @@
# 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.
{{- range .Values.services }}
{{- range $serviceName, $serviceSpec := .Values.spec.services }}
{{- if eq $serviceSpec.componentType "main" }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $.Release.Name }}-{{ .name | lower }}
name: {{ $.Release.Name }}-{{ $serviceName | lower }}
labels:
app: {{ $.Release.Name }}-{{ $serviceName | lower }}
spec:
selector:
app: {{ $.Release.Name }}-{{ .name | lower }}
app: {{ $.Release.Name }}-{{ $serviceName | lower }}
ports:
- protocol: TCP
port: 80
targetPort: 3000
---
- port: {{ $serviceSpec.port | default 8000 }}
targetPort: {{ $serviceSpec.port | default 8000 }}
protocol: TCP
type: ClusterIP
{{- end }}
{{- end }}
......@@ -14,10 +14,7 @@
# limitations under the License.
imagePullSecrets:
- name: yatai-regcred
- name: nvcrimagepullsecret
- name: docker-imagepullsecret
- name: gitlab-imagepull
natsAddr: nats://dynamo-platform-nats:4222
etcdAddr: dynamo-platform-etcd:2379
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
replicaCount: 1
# Explicitly remove authentication
auth:
rbac:
create: false
readinessProbe:
enabled: true
livenessProbe:
enabled: true
# SPDX-FileCopyrightText: Copyright (c) 2025 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.
config:
jetstream:
enabled: true
fileStore:
enabled: true
dir: /data
pvc:
enabled: true
size: 10Gi
storageClassName:
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 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.
set -euo pipefail
# Validate input parameters
if [ "$#" -lt 4 ] || [ "$#" -gt 5 ]; then
echo "Usage: $0 <DOCKER_REGISTRY> <NAMESPACE> <DYNAMO_DIRECTORY> <DYNAMO_IDENTIFIER> [<DYNAMO_CONFIG_FILE>]"
echo "Note: DYNAMO_CONFIG_FILE is optional"
exit 1
fi
DOCKER_REGISTRY=$1
NAMESPACE=$2
DYNAMO_DIRECTORY=$3
DYNAMO_IDENTIFIER=$4
DYNAMO_CONFIG_FILE=${5:-""} # Set to empty string if not provided
# Check if any of the inputs are empty
if [[ -z "$DOCKER_REGISTRY" || -z "$NAMESPACE" || -z "$DYNAMO_IDENTIFIER" || -z "$DYNAMO_DIRECTORY" ]]; then
echo "Error: All input parameters (DOCKER_REGISTRY, NAMESPACE, DYNAMO_IDENTIFIER, DYNAMO_DIRECTORY) must be non-empty."
exit 1
fi
# Check if the specified directory exists
if [ ! -d "$DYNAMO_DIRECTORY" ]; then
echo "Error: Directory $DYNAMO_DIRECTORY does not exist."
exit 1
fi
echo "Logging into Docker registry: $DOCKER_REGISTRY"
docker login "$DOCKER_REGISTRY"
# Change to the specified directory
cd "$DYNAMO_DIRECTORY"
# Build the Dynamo application container
echo "Building Dynamo application image for $DYNAMO_IDENTIFIER..."
DOCKER_DEFAULT_PLATFORM=linux/amd64 uv run dynamo build --containerize $DYNAMO_IDENTIFIER
# Extract the module and the dynamo name
DYNAMO_MODULE=$(echo "$DYNAMO_IDENTIFIER" | awk -F':' '{print $1}' | tr '[:upper:]' '[:lower:]')
DYNAMO_NAME=$(echo "$DYNAMO_IDENTIFIER" | awk -F':' '{print $2}' | tr '[:upper:]' '[:lower:]')
# Find the built image
docker_image=$(docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" | grep "^$DYNAMO_NAME:" | sort -r -k2,3 | head -n 1 | awk '{print $1}')
if [[ -z "$docker_image" ]]; then
echo "Failed to find the built image for $DYNAMO_NAME"
exit 1
fi
# Extract the image tag (SHA) from the docker image info
docker_sha=$(echo "$docker_image" | awk -F':' '{print $2}')
echo "Found Docker image: $docker_image"
echo "Docker SHA: $docker_sha"
# Tag the image for the registry
docker_tag_for_registry="$DOCKER_REGISTRY/$docker_image"
echo "Tagging image: $docker_tag_for_registry"
docker tag "$docker_image" "$docker_tag_for_registry"
# Push the image
echo "Pushing image: $docker_tag_for_registry"
docker push "$docker_tag_for_registry"
cd -
# Install the Helm chart with the correct tag (SHA)
echo "Installing Helm chart with image: $docker_tag_for_registry"
HELM_RELEASE="${DYNAMO_MODULE//_/\-}"
helm upgrade -i "$HELM_RELEASE" ./chart -f ~/.dynamo/packages/"$DYNAMO_MODULE"/"$DYNAMO_NAME"/dynamo.yaml --set image="$docker_tag_for_registry" --set dynamoIdentifier="$DYNAMO_IDENTIFIER" --set configFilePath="$DYNAMO_CONFIG_FILE" -n "$NAMESPACE"
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment