runtime: fall back to CDI annotations when kubelet socket is absent

NVIDIA GPU configs default pod_resource_api_sock to the kubelet Pod
Resources API path. On non-Kubernetes hosts that path is usually missing;
use CDI sandbox annotations for cold-plug instead of failing kubelet lookup.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Fabiano Fidêncio
2026-05-24 15:17:15 +02:00
parent 478970131c
commit 92da7974f5
2 changed files with 57 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ import (
"context"
"fmt"
"net"
"os"
"strings"
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
@@ -39,12 +40,15 @@ func coldPlugDevices(ctx context.Context, s *service, ociSpec *specs.Spec) error
return nil
}
kubeletSock := s.config.PodResourceAPISock
if kubeletSock != "" {
if kubeletPodResourceSocketAvailable(s.config.PodResourceAPISock) {
return coldPlugWithAPI(ctx, s, ociSpec)
}
shimLog.Debug("config.PodResourceAPISock not set, skip k8s based device cold plug")
if s.config.PodResourceAPISock != "" {
shimLog.Debugf("config.PodResourceAPISock %q not available, fall back to CDI annotations", s.config.PodResourceAPISock)
} else {
shimLog.Debug("config.PodResourceAPISock not set, use CDI annotations for cold plug")
}
// Here we deal with CDI devices that are cold-plugged
// for the single_container (nerdctl, podman, ...) use-case.
@@ -58,6 +62,20 @@ func coldPlugDevices(ctx context.Context, s *service, ociSpec *specs.Spec) error
return nil
}
// kubeletPodResourceSocketAvailable reports whether the configured kubelet Pod
// Resources API socket exists and can be used for Kubernetes-based cold plug.
func kubeletPodResourceSocketAvailable(sock string) bool {
if sock == "" {
return false
}
fi, err := os.Stat(sock)
if err != nil {
return false
}
return (fi.Mode() & os.ModeSocket) != 0
}
func coldPlugWithAPI(ctx context.Context, s *service, ociSpec *specs.Spec) error {
ann := ociSpec.Annotations
devices, err := getDeviceSpec(ctx, s.config.PodResourceAPISock, ann)

View File

@@ -0,0 +1,36 @@
// Copyright (c) 2025 NVIDIA CORPORATION.
//
// SPDX-License-Identifier: Apache-2.0
//
package containerdshim
import (
"net"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestKubeletPodResourceSocketAvailable(t *testing.T) {
assert.False(t, kubeletPodResourceSocketAvailable(""))
tmpDir := t.TempDir()
sockPath := filepath.Join(tmpDir, "kubelet.sock")
assert.False(t, kubeletPodResourceSocketAvailable(sockPath))
f, err := os.Create(sockPath)
assert.NoError(t, err)
assert.NoError(t, f.Close())
assert.False(t, kubeletPodResourceSocketAvailable(sockPath))
assert.NoError(t, os.Remove(sockPath))
l, err := net.Listen("unix", sockPath)
assert.NoError(t, err)
defer l.Close()
assert.True(t, kubeletPodResourceSocketAvailable(sockPath))
}