diff --git a/docs/helm-configuration.md b/docs/helm-configuration.md index e2843c6a41..59f2d73df7 100644 --- a/docs/helm-configuration.md +++ b/docs/helm-configuration.md @@ -16,7 +16,7 @@ helm show values --version X.Y.Z oci://ghcr.io/kata-containers/kata-deploy-chart Kata ships with a number of pre-built artifacts and runtimes. You may selectively enable or disable specific shims. For example: -```yaml title="values.yaml" +```yaml shims: disableAll: true qemu: @@ -332,7 +332,7 @@ $ helm install kata-deploy \ You can also use a values file: -```yaml title="values.yaml" +```yaml nodeSelector: kata-containers: "enabled" node-type: "worker" @@ -342,6 +342,69 @@ nodeSelector: $ helm install kata-deploy -f values.yaml "${CHART}" --version "${VERSION}" ``` +### `podLabels` + +You can add extra labels to the kata-deploy DaemonSet pods. These are applied +in addition to the `name: kata-deploy` label that the chart uses internally. + +```sh +$ helm install kata-deploy \ + --set podLabels.team=platform \ + "${CHART}" --version "${VERSION}" +``` + +Or via a values file: + +```yaml +podLabels: + team: platform +``` + +### `affinity` + +Use `affinity` when you need more granular scheduling controls than +`nodeSelector` alone. `nodeSelector` only matches exact key/value pairs on a +node; affinity gives you `matchExpressions` (e.g. `In`, `NotIn`) and rules +about other pods on the same node. For example, you might want kata-deploy on +nodes reserved for your platform team but *not* on nodes that run the GPU +operator. + +```sh +# First, label the nodes where kata-deploy should run +$ kubectl label nodes worker-node-1 node.cloud/reserved=platform-team +$ kubectl label nodes worker-node-2 node.cloud/reserved=platform-team + +# Then install the chart with affinity +$ helm install kata-deploy -f values.yaml "${CHART}" --version "${VERSION}" +``` + +```yaml +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node.cloud/reserved + operator: In + values: + - platform-team + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - gpu-operator + topologyKey: kubernetes.io/hostname +``` + +When `node-feature-discovery.enabled=true`, the chart also merges in a +`nodeAffinity` rule that requires hardware virtualization support. If you set +`affinity.nodeAffinity` yourself, your required `nodeSelectorTerms` are +combined with the built-in virtualization terms. Other affinity fields +(`podAffinity`, `podAntiAffinity`, and so on) are passed through as-is. + ### Multiple Kata installations on the Same Node For debugging, testing and other use-case it is possible to deploy multiple diff --git a/tests/functional/kata-deploy/kata-deploy-scheduling.bats b/tests/functional/kata-deploy/kata-deploy-scheduling.bats new file mode 100644 index 0000000000..df10da09bd --- /dev/null +++ b/tests/functional/kata-deploy/kata-deploy-scheduling.bats @@ -0,0 +1,129 @@ +#!/usr/bin/env bats +# Copyright (c) 2026 The Kata Containers Authors +# +# SPDX-License-Identifier: Apache-2.0 +# +# Helm template tests for kata-deploy DaemonSet scheduling options +# (podLabels, podAnnotations, affinity). No cluster required. + +load "${BATS_TEST_DIRNAME}/../../common.bash" + +source "${BATS_TEST_DIRNAME}/lib/helm-deploy.bash" + +CHART_PATH="$(get_chart_path)" +RENDERED="/tmp/kata-deploy-scheduling-rendered.yaml" + +render_chart() { + helm template kata-deploy "${CHART_PATH}" \ + --set image.reference=quay.io/kata-containers/kata-deploy \ + --set image.tag=latest \ + "$@" > "${RENDERED}" +} + +# Extract the kata-deploy DaemonSet manifest (not kata-monitor or NFD subchart). +extract_kata_deploy_ds() { + awk ' + /^kind: DaemonSet$/ { buf = $0 "\n"; in_ds = 1; has_name = 0; next } + in_ds { + buf = buf $0 "\n" + if ($0 ~ /^ name: kata-deploy$/) { has_name = 1 } + if ($0 ~ /^---$/) { + if (has_name) { printf "%s", buf; exit } + in_ds = 0; buf = ""; has_name = 0 + next + } + } + END { if (has_name && in_ds) { printf "%s", buf } } + ' "${RENDERED}" +} + +# ============================================================================= +# Template Rendering Tests (no cluster required) +# ============================================================================= + +@test "Helm template: default values keep single name pod label and no affinity" { + render_chart + + local ds + ds=$(extract_kata_deploy_ds) + + [[ -n "${ds}" ]] + echo "${ds}" | grep -q "name: kata-deploy" + echo "${ds}" | grep -A5 "template:" | grep -A3 "labels:" | grep -q "name: kata-deploy" + ! echo "${ds}" | grep -A10 "template:" | grep -A5 "metadata:" | grep -q "annotations:" + ! echo "${ds}" | grep -q "affinity:" +} + +@test "Helm template: podLabels are applied to pod template" { + render_chart --set podLabels.team=platform + + local ds + ds=$(extract_kata_deploy_ds) + + echo "${ds}" | grep -A5 "template:" | grep -A4 "labels:" | grep -q "name: kata-deploy" + echo "${ds}" | grep -A5 "template:" | grep -A4 "labels:" | grep -q "team: platform" +} + +@test "Helm template: user affinity is applied to pod spec" { + local values_file + values_file=$(mktemp) + cat > "${values_file}" < "${values_file}" <