mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-21 00:33:15 +00:00
Check OS for PodLevelResources in kubelet
Reject pods with PodLevelResources running on Windows nodes at kubelet admission phase
This commit is contained in:
committed by
Tsubasa Nagasawa
parent
e2c308aff9
commit
c2b26617be
@@ -248,6 +248,7 @@ var (
|
||||
lifecycle.OutOfMemory,
|
||||
lifecycle.OutOfEphemeralStorage,
|
||||
lifecycle.OutOfPods,
|
||||
lifecycle.PodLevelResourcesNotAdmittedReason,
|
||||
tainttoleration.ErrReasonNotMatch,
|
||||
eviction.Reason,
|
||||
sysctl.ForbiddenReason,
|
||||
@@ -1011,6 +1012,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
||||
handlers = append(handlers, lifecycle.NewAppArmorAdmitHandler(klet.appArmorValidator))
|
||||
}
|
||||
|
||||
handlers = append(handlers, lifecycle.NewPodFeaturesAdmitHandler())
|
||||
|
||||
leaseDuration := time.Duration(kubeCfg.NodeLeaseDurationSeconds) * time.Second
|
||||
renewInterval := time.Duration(float64(leaseDuration) * nodeLeaseRenewIntervalFraction)
|
||||
klet.nodeLeaseController = lease.NewController(
|
||||
|
||||
@@ -3373,6 +3373,15 @@ func TestRecordAdmissionRejection(t *testing.T) {
|
||||
kubelet_admission_rejections_total{reason="OutOfExtendedResources"} 1
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "PodLevelResources",
|
||||
reason: lifecycle.PodLevelResourcesNotAdmittedReason,
|
||||
wants: `
|
||||
# HELP kubelet_admission_rejections_total [ALPHA] Cumulative number pod admission rejections by the Kubelet.
|
||||
# TYPE kubelet_admission_rejections_total counter
|
||||
kubelet_admission_rejections_total{reason="PodLevelResourcesNotSupported"} 1
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "OtherReason",
|
||||
reason: "OtherReason",
|
||||
|
||||
39
pkg/kubelet/lifecycle/features_linux.go
Normal file
39
pkg/kubelet/lifecycle/features_linux.go
Normal file
@@ -0,0 +1,39 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package lifecycle
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-helpers/resource"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func isPodLevelResourcesSupported(pod *v1.Pod) PodAdmitResult {
|
||||
podLevelResourcesEnabled := utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)
|
||||
if resource.IsPodLevelResourcesSet(pod) && !podLevelResourcesEnabled {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: PodLevelResourcesNotAdmittedReason,
|
||||
Message: "PodLevelResources feature gate is disabled",
|
||||
}
|
||||
}
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
36
pkg/kubelet/lifecycle/features_unsupported.go
Normal file
36
pkg/kubelet/lifecycle/features_unsupported.go
Normal file
@@ -0,0 +1,36 @@
|
||||
//go:build !linux && !windows
|
||||
// +build !linux,!windows
|
||||
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package lifecycle
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/component-helpers/resource"
|
||||
)
|
||||
|
||||
func isPodLevelResourcesSupported(pod *v1.Pod) PodAdmitResult {
|
||||
if resource.IsPodLevelResourcesSet(pod) {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: PodLevelResourcesNotAdmittedReason,
|
||||
Message: "pod-level resources are not supported on the node",
|
||||
}
|
||||
}
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
36
pkg/kubelet/lifecycle/features_windows.go
Normal file
36
pkg/kubelet/lifecycle/features_windows.go
Normal file
@@ -0,0 +1,36 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package lifecycle
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/component-helpers/resource"
|
||||
)
|
||||
|
||||
func isPodLevelResourcesSupported(pod *v1.Pod) PodAdmitResult {
|
||||
if resource.IsPodLevelResourcesSet(pod) {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: PodLevelResourcesNotAdmittedReason,
|
||||
Message: "pod-level resources are not supported on Windows",
|
||||
}
|
||||
}
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
@@ -45,7 +45,8 @@ import (
|
||||
const (
|
||||
maxRespBodyLength = 10 * 1 << 10 // 10KB
|
||||
|
||||
AppArmorNotAdmittedReason = "AppArmor"
|
||||
AppArmorNotAdmittedReason = "AppArmor"
|
||||
PodLevelResourcesNotAdmittedReason = "PodLevelResourcesNotSupported"
|
||||
)
|
||||
|
||||
type handlerRunner struct {
|
||||
@@ -241,3 +242,15 @@ func isHTTPResponseError(err error) bool {
|
||||
}
|
||||
return strings.Contains(urlErr.Err.Error(), "server gave HTTP response to HTTPS client")
|
||||
}
|
||||
|
||||
// NewPodFeaturesAdmitHandler returns a PodAdmitHandler which is used to evaluate
|
||||
// if a pod can be admitted from the perspective of pod features compatibility.
|
||||
func NewPodFeaturesAdmitHandler() PodAdmitHandler {
|
||||
return &podFeaturesAdmitHandler{}
|
||||
}
|
||||
|
||||
type podFeaturesAdmitHandler struct{}
|
||||
|
||||
func (h *podFeaturesAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
return isPodLevelResourcesSupported(attrs.Pod)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user