# Wave 9-11 — GPU serving stack on worker-1 (4x Tesla V100 32GB). # # Ordering matters: device plugin must expose nvidia.com/gpu and the KServe CRDs # must exist before any InferenceService is applied, hence three waves. # # NOTE the chart versions below are v-PREFIXED (v0.15.2, not 0.15.2) — that is # how the KServe OCI tags are published; the unprefixed form 404s. apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: gpu-runtimeclass namespace: argocd annotations: # Wave 8: must precede the device plugin, whose DaemonSet sets # runtimeClassName: nvidia and is rejected at admission if the # RuntimeClass does not exist yet. argocd.argoproj.io/sync-wave: "8" spec: project: homelab source: repoURL: git@github.com:Riotpiaole/riotpiao.homelab.com.git targetRevision: main path: k8s/apps/gpu-runtimeclass destination: server: https://kubernetes.default.svc # Cluster-scoped resource; namespace is only the app's default context. namespace: gpu-system syncPolicy: syncOptions: - CreateNamespace=true --- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: nvidia-device-plugin namespace: argocd annotations: argocd.argoproj.io/sync-wave: "9" spec: project: homelab source: repoURL: https://nvidia.github.io/k8s-device-plugin chart: nvidia-device-plugin targetRevision: "0.19.3" helm: values: | # Driver + container toolkit are supplied by Talos system extensions # baked into the installer image (nonfree-kmod-nvidia-lts / # nvidia-container-toolkit-lts). This chart ONLY advertises the GPUs to # the kubelet — it does not and must not install drivers. runtimeClassName: nvidia nodeSelector: nvidia.com/gpu: "true" # Drop the chart's default nodeAffinity. It requires one of three # Node-Feature-Discovery labels (feature.node.kubernetes.io/pci-10de.present, # .../cpu-model.vendor_id=NVIDIA, or nvidia.com/gpu.present). NFD is not # installed and Talos sets nvidia.com/gpu (no ".present" suffix), so the # affinity matches zero nodes and the DaemonSet silently reports # desiredNumberScheduled=0 with no events. nodeSelector is the constraint. affinity: null destination: server: https://kubernetes.default.svc namespace: gpu-system syncPolicy: # Manual sync for first bring-up: watch device-plugin -> KServe -> models # come up in order, and avoid auto-deploying while worker-1 is cordoned. # Switch to `automated: {prune: true, selfHeal: true}` once proven. syncOptions: - CreateNamespace=true --- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: kserve-crd namespace: argocd annotations: argocd.argoproj.io/sync-wave: "9" spec: project: homelab source: repoURL: oci://ghcr.io/kserve/charts chart: kserve-crd targetRevision: v0.15.2 destination: server: https://kubernetes.default.svc namespace: kserve syncPolicy: # Manual sync for first bring-up: watch device-plugin -> KServe -> models # come up in order, and avoid auto-deploying while worker-1 is cordoned. # Switch to `automated: {prune: true, selfHeal: true}` once proven. syncOptions: - CreateNamespace=true # InferenceService CRD exceeds the annotation size limit for # client-side apply. - ServerSideApply=true --- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: kserve namespace: argocd annotations: argocd.argoproj.io/sync-wave: "10" spec: project: homelab source: repoURL: oci://ghcr.io/kserve/charts chart: kserve targetRevision: v0.15.2 helm: values: | kserve: controller: # RawDeployment => plain Deployments/Services, no Knative, no Istio. # v0.18 renames this mode "Standard"; do not bump without checking. deploymentMode: RawDeployment gateway: ingressGateway: # Route through the existing ingress-nginx, not Gateway API. # NOTE the nesting: it is gateway.ingressGateway.enableGatewayApi, # not gateway.enableGatewayApi — Helm silently ignores the wrong # key rather than erroring. enableGatewayApi: false destination: server: https://kubernetes.default.svc namespace: kserve syncPolicy: # Manual sync for first bring-up: watch device-plugin -> KServe -> models # come up in order, and avoid auto-deploying while worker-1 is cordoned. # Switch to `automated: {prune: true, selfHeal: true}` once proven. syncOptions: - CreateNamespace=true - ServerSideApply=true --- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: llm-serving namespace: argocd annotations: argocd.argoproj.io/sync-wave: "11" spec: project: homelab source: repoURL: git@github.com:Riotpiaole/riotpiao.homelab.com.git targetRevision: main path: k8s/apps/llm-serving destination: server: https://kubernetes.default.svc namespace: llm-serving syncPolicy: # Manual sync for first bring-up: watch device-plugin -> KServe -> models # come up in order, and avoid auto-deploying while worker-1 is cordoned. # Switch to `automated: {prune: true, selfHeal: true}` once proven. syncOptions: - CreateNamespace=true