From 024146f705874f64c6180c286e9c01f6547a1cea Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 9 Feb 2024 13:03:39 +0100 Subject: [PATCH] KEP-127: the kubelet stores runtime helpers as they are received from the ResponseStatus request to the runtime. Signed-off-by: Giuseppe Scrivano --- pkg/kubelet/container/runtime.go | 22 ++++++++++++++++++- pkg/kubelet/kubelet.go | 2 ++ pkg/kubelet/kuberuntime/helpers.go | 15 +++++++++++-- .../kuberuntime/kuberuntime_manager.go | 2 +- pkg/kubelet/runtime.go | 14 ++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index d2943b9ce91..b7d82ca1773 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -526,6 +526,8 @@ const ( type RuntimeStatus struct { // Conditions is an array of current observed runtime conditions. Conditions []RuntimeCondition + // Handlers is a map of current available handlers + Handlers map[string]RuntimeHandler } // GetRuntimeCondition gets a specified runtime condition from the runtime status. @@ -542,10 +544,28 @@ func (r *RuntimeStatus) GetRuntimeCondition(t RuntimeConditionType) *RuntimeCond // String formats the runtime status into human readable string. func (r *RuntimeStatus) String() string { var ss []string + var sh []string for _, c := range r.Conditions { ss = append(ss, c.String()) } - return fmt.Sprintf("Runtime Conditions: %s", strings.Join(ss, ", ")) + for _, h := range r.Handlers { + sh = append(sh, h.String()) + } + return fmt.Sprintf("Runtime Conditions: %s; Handlers: %s", strings.Join(ss, ", "), strings.Join(sh, ", ")) +} + +// RuntimeHandler contains condition information for the runtime handler. +type RuntimeHandler struct { + // Name is the handler name. + Name string + // SupportsUserNamespaces is true if the handler has support for + // user namespaces. + SupportsUserNamespaces bool +} + +// String formats the runtime handler into human readable string. +func (h *RuntimeHandler) String() string { + return fmt.Sprintf("Name=%s SupportsUserNamespaces: %v", h.Name, h.SupportsUserNamespaces) } // RuntimeCondition contains condition information for the runtime. diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 2bd35b96611..199ad2df85b 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -2898,7 +2898,9 @@ func (kl *Kubelet) updateRuntimeUp() { kl.runtimeState.setRuntimeState(fmt.Errorf("container runtime not ready: %v", runtimeReady)) return } + kl.runtimeState.setRuntimeState(nil) + kl.runtimeState.setRuntimeHandlers(s.Handlers) kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules) kl.runtimeState.setRuntimeSync(kl.clock.Now()) } diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go index bb302bc5b02..50261972236 100644 --- a/pkg/kubelet/kuberuntime/helpers.go +++ b/pkg/kubelet/kuberuntime/helpers.go @@ -200,7 +200,7 @@ func parsePodUIDFromLogsDirectory(name string) types.UID { } // toKubeRuntimeStatus converts the runtimeapi.RuntimeStatus to kubecontainer.RuntimeStatus. -func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.RuntimeStatus { +func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus, handlers []*runtimeapi.RuntimeHandler) *kubecontainer.RuntimeStatus { conditions := []kubecontainer.RuntimeCondition{} for _, c := range status.GetConditions() { conditions = append(conditions, kubecontainer.RuntimeCondition{ @@ -210,7 +210,18 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.Runtim Message: c.Message, }) } - return &kubecontainer.RuntimeStatus{Conditions: conditions} + retHandlers := make(map[string]kubecontainer.RuntimeHandler) + for _, h := range handlers { + supportsUserns := false + if h.Features != nil { + supportsUserns = h.Features.UserNamespaces + } + retHandlers[h.Name] = kubecontainer.RuntimeHandler{ + Name: h.Name, + SupportsUserNamespaces: supportsUserns, + } + } + return &kubecontainer.RuntimeStatus{Conditions: conditions, Handlers: retHandlers} } func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) (*runtimeapi.SecurityProfile, error) { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index f833c28e426..688c5a843fd 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -353,7 +353,7 @@ func (m *kubeGenericRuntimeManager) Status(ctx context.Context) (*kubecontainer. if resp.GetStatus() == nil { return nil, errors.New("runtime status is nil") } - return toKubeRuntimeStatus(resp.GetStatus()), nil + return toKubeRuntimeStatus(resp.GetStatus(), resp.GetRuntimeHandlers()), nil } // GetPods returns a list of containers grouped by pods. The boolean parameter diff --git a/pkg/kubelet/runtime.go b/pkg/kubelet/runtime.go index 9ee5ece1ff4..cc16dfdcd52 100644 --- a/pkg/kubelet/runtime.go +++ b/pkg/kubelet/runtime.go @@ -23,6 +23,7 @@ import ( "time" utilerrors "k8s.io/apimachinery/pkg/util/errors" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) type runtimeState struct { @@ -34,6 +35,7 @@ type runtimeState struct { storageError error cidr string healthChecks []*healthCheck + rtHandlers map[string]kubecontainer.RuntimeHandler } // A health check function should be efficient and not rely on external @@ -69,6 +71,18 @@ func (s *runtimeState) setRuntimeState(err error) { s.runtimeError = err } +func (s *runtimeState) setRuntimeHandlers(rtHandlers map[string]kubecontainer.RuntimeHandler) { + s.Lock() + defer s.Unlock() + s.rtHandlers = rtHandlers +} + +func (s *runtimeState) runtimeHandlers() map[string]kubecontainer.RuntimeHandler { + s.RLock() + defer s.RUnlock() + return s.rtHandlers +} + func (s *runtimeState) setStorageState(err error) { s.Lock() defer s.Unlock()