mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #131876 from pohly/automated-cherry-pick-of-#131844-origin-release-1.33
Automated cherry pick of #131844: DRA node: reject static pods which reference ResourceClaims
This commit is contained in:
commit
6144faccba
@ -3038,6 +3038,13 @@ func gatherPodResourceClaimNames(claims []core.PodResourceClaim) sets.Set[string
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResourceClaim, podClaimNames *sets.Set[string], fldPath *field.Path) field.ErrorList {
|
func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResourceClaim, podClaimNames *sets.Set[string], fldPath *field.Path) field.ErrorList {
|
||||||
|
// static pods don't support resource claims
|
||||||
|
if podMeta != nil {
|
||||||
|
if _, ok := podMeta.Annotations[core.MirrorPodAnnotationKey]; ok {
|
||||||
|
return field.ErrorList{field.Forbidden(field.NewPath(""), "static pods do not support resource claims")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var allErrs field.ErrorList
|
var allErrs field.ErrorList
|
||||||
if claim.Name == "" {
|
if claim.Name == "" {
|
||||||
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
|
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
|
||||||
|
@ -25321,6 +25321,8 @@ func TestValidateDynamicResourceAllocation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
failureCases := map[string]*core.Pod{
|
failureCases := map[string]*core.Pod{
|
||||||
|
"static pod with resource claim reference": goodClaimReference,
|
||||||
|
"static pod with resource claim template": goodClaimTemplate,
|
||||||
"pod claim name with prefix": podtest.MakePod("",
|
"pod claim name with prefix": podtest.MakePod("",
|
||||||
podtest.SetResourceClaims(core.PodResourceClaim{
|
podtest.SetResourceClaims(core.PodResourceClaim{
|
||||||
Name: "../my-claim",
|
Name: "../my-claim",
|
||||||
@ -25450,7 +25452,14 @@ func TestValidateDynamicResourceAllocation(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
}
|
}
|
||||||
for k, v := range failureCases {
|
for k, v := range failureCases {
|
||||||
if errs := ValidatePodSpec(&v.Spec, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
|
podMeta := shortPodName
|
||||||
|
if strings.HasPrefix(k, "static pod") {
|
||||||
|
podMeta = podMeta.DeepCopy()
|
||||||
|
podMeta.Annotations = map[string]string{
|
||||||
|
core.MirrorPodAnnotationKey: "True",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errs := ValidatePodSpec(&v.Spec, podMeta, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
|
||||||
t.Errorf("expected failure for %q", k)
|
t.Errorf("expected failure for %q", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,9 @@ type defaultFunc func(pod *api.Pod) error
|
|||||||
// A static pod tried to use a ClusterTrustBundle projected volume source.
|
// A static pod tried to use a ClusterTrustBundle projected volume source.
|
||||||
var ErrStaticPodTriedToUseClusterTrustBundle = errors.New("static pods may not use ClusterTrustBundle projected volume sources")
|
var ErrStaticPodTriedToUseClusterTrustBundle = errors.New("static pods may not use ClusterTrustBundle projected volume sources")
|
||||||
|
|
||||||
|
// A static pod tried to use a resource claim.
|
||||||
|
var ErrStaticPodTriedToUseResourceClaims = errors.New("static pods may not use ResourceClaims")
|
||||||
|
|
||||||
// tryDecodeSinglePod takes data and tries to extract valid Pod config information from it.
|
// tryDecodeSinglePod takes data and tries to extract valid Pod config information from it.
|
||||||
func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v1.Pod, err error) {
|
func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v1.Pod, err error) {
|
||||||
// JSON is valid YAML, so this should work for everything.
|
// JSON is valid YAML, so this should work for everything.
|
||||||
@ -152,6 +155,9 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(v1Pod.Spec.ResourceClaims) > 0 {
|
||||||
|
return true, nil, ErrStaticPodTriedToUseResourceClaims
|
||||||
|
}
|
||||||
|
|
||||||
return true, v1Pod, nil
|
return true, v1Pod, nil
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,62 @@ func TestDecodeSinglePodRejectsClusterTrustBundleVolumes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecodeSinglePodRejectsResourceClaims(t *testing.T) {
|
||||||
|
grace := int64(30)
|
||||||
|
enableServiceLinks := v1.DefaultEnableServiceLinks
|
||||||
|
pod := &v1.Pod{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test",
|
||||||
|
UID: "12345",
|
||||||
|
Namespace: "mynamespace",
|
||||||
|
},
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
RestartPolicy: v1.RestartPolicyAlways,
|
||||||
|
DNSPolicy: v1.DNSClusterFirst,
|
||||||
|
TerminationGracePeriodSeconds: &grace,
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: "image",
|
||||||
|
Image: "test/image",
|
||||||
|
ImagePullPolicy: "IfNotPresent",
|
||||||
|
TerminationMessagePath: "/dev/termination-log",
|
||||||
|
TerminationMessagePolicy: v1.TerminationMessageReadFile,
|
||||||
|
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||||
|
Resources: v1.ResourceRequirements{
|
||||||
|
Claims: []v1.ResourceClaim{{
|
||||||
|
Name: "my-claim",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
ResourceClaims: []v1.PodResourceClaim{{
|
||||||
|
Name: "my-claim",
|
||||||
|
ResourceClaimName: ptr.To("some-external-claim"),
|
||||||
|
}},
|
||||||
|
SecurityContext: &v1.PodSecurityContext{},
|
||||||
|
SchedulerName: v1.DefaultSchedulerName,
|
||||||
|
EnableServiceLinks: &enableServiceLinks,
|
||||||
|
},
|
||||||
|
Status: v1.PodStatus{
|
||||||
|
PodIP: "1.2.3.4",
|
||||||
|
PodIPs: []v1.PodIP{
|
||||||
|
{
|
||||||
|
IP: "1.2.3.4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
json, err := runtime.Encode(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), pod)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
_, _, err = tryDecodeSinglePod(json, noDefault)
|
||||||
|
if !errors.Is(err, ErrStaticPodTriedToUseResourceClaims) {
|
||||||
|
t.Errorf("Got error %q, want %q", err, ErrStaticPodTriedToUseResourceClaims)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDecodePodList(t *testing.T) {
|
func TestDecodePodList(t *testing.T) {
|
||||||
grace := int64(30)
|
grace := int64(30)
|
||||||
enableServiceLinks := v1.DefaultEnableServiceLinks
|
enableServiceLinks := v1.DefaultEnableServiceLinks
|
||||||
|
@ -335,6 +335,10 @@ func (p *Plugin) admitPodCreate(nodeName string, a admission.Attributes) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(pod.Spec.ResourceClaims) > 0 {
|
||||||
|
return admission.NewForbidden(a, fmt.Errorf("node %q can not create pods that reference resourceclaims", nodeName))
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,6 +574,9 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
pvcpod, _ := makeTestPod("ns", "mypvcpod", "mynode", true)
|
pvcpod, _ := makeTestPod("ns", "mypvcpod", "mynode", true)
|
||||||
pvcpod.Spec.Volumes = []api.Volume{{VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: "foo"}}}}
|
pvcpod.Spec.Volumes = []api.Volume{{VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: "foo"}}}}
|
||||||
|
|
||||||
|
claimpod, _ := makeTestPod("ns", "myclaimpod", "mynode", true)
|
||||||
|
claimpod.Spec.ResourceClaims = []api.PodResourceClaim{{Name: "myclaim", ResourceClaimName: pointer.String("myexternalclaim")}}
|
||||||
|
|
||||||
tests := []admitTestCase{
|
tests := []admitTestCase{
|
||||||
// Mirror pods bound to us
|
// Mirror pods bound to us
|
||||||
{
|
{
|
||||||
@ -1055,6 +1058,12 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
|||||||
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
|
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
|
||||||
err: "reference persistentvolumeclaims",
|
err: "reference persistentvolumeclaims",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "forbid create of pod referencing resourceclaim",
|
||||||
|
podsGetter: noExistingPods,
|
||||||
|
attributes: admission.NewAttributesRecord(claimpod, nil, podKind, claimpod.Namespace, claimpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
|
||||||
|
err: "reference resourceclaim",
|
||||||
|
},
|
||||||
|
|
||||||
// My node object
|
// My node object
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user