Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.24.4
1.24.5
223 changes: 165 additions & 58 deletions CHANGELOG/CHANGELOG-1.33.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/build-image/cross/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.33.0-go1.24.4-bullseye.0
v1.33.0-go1.24.5-bullseye.0
4 changes: 2 additions & 2 deletions build/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ readonly KUBE_RSYNC_PORT="${KUBE_RSYNC_PORT:-}"
readonly KUBE_CONTAINER_RSYNC_PORT=8730

# These are the default versions (image tags) for their respective base images.
readonly __default_distroless_iptables_version=v0.7.6
readonly __default_go_runner_version=v2.4.0-go1.24.4-bookworm.0
readonly __default_distroless_iptables_version=v0.7.7
readonly __default_go_runner_version=v2.4.0-go1.24.5-bookworm.0
readonly __default_setcap_version=bookworm-v1.0.4

# These are the base images for the Docker-wrapped binaries.
Expand Down
8 changes: 4 additions & 4 deletions build/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ dependencies:

# Golang
- name: "golang: upstream version"
version: 1.24.4
version: 1.24.5
refPaths:
- path: .go-version
- path: build/build-image/cross/VERSION
Expand All @@ -139,7 +139,7 @@ dependencies:
match: minimum_go_version=go([0-9]+\.[0-9]+)

- name: "registry.k8s.io/kube-cross: dependents"
version: v1.33.0-go1.24.4-bullseye.0
version: v1.33.0-go1.24.5-bullseye.0
refPaths:
- path: build/build-image/cross/VERSION

Expand Down Expand Up @@ -177,15 +177,15 @@ dependencies:
match: registry\.k8s\.io\/build-image\/debian-base:[a-zA-Z]+\-v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)

- name: "registry.k8s.io/distroless-iptables: dependents"
version: v0.7.6
version: v0.7.7
refPaths:
- path: build/common.sh
match: __default_distroless_iptables_version=
- path: test/utils/image/manifest.go
match: configs\[DistrolessIptables\] = Config{list\.BuildImageRegistry, "distroless-iptables", "v([0-9]+)\.([0-9]+)\.([0-9]+)"}

- name: "registry.k8s.io/go-runner: dependents"
version: v2.4.0-go1.24.4-bookworm.0
version: v2.4.0-go1.24.5-bookworm.0
refPaths:
- path: build/common.sh
match: __default_go_runner_version=
Expand Down
2 changes: 1 addition & 1 deletion openshift-hack/images/hyperkube/Dockerfile.rhel
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ COPY --from=builder /tmp/build/* /usr/bin/
LABEL io.k8s.display-name="OpenShift Kubernetes Server Commands" \
io.k8s.description="OpenShift is a platform for developing, building, and deploying containerized applications." \
io.openshift.tags="openshift,hyperkube" \
io.openshift.build.versions="kubernetes=1.33.3"
io.openshift.build.versions="kubernetes=1.33.4"
5 changes: 5 additions & 0 deletions plugin/pkg/admission/noderestriction/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,11 @@ func (p *Plugin) admitNode(nodeName string, a admission.Attributes) error {
return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to modify taints", nodeName))
}

// Don't allow a node to update its own ownerReferences.
if !apiequality.Semantic.DeepEqual(node.OwnerReferences, oldNode.OwnerReferences) {
return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to modify ownerReferences", nodeName))
}

// Don't allow a node to update labels outside the allowed set.
// This would allow a node to add or modify its labels in a way that would let it steer privileged workloads to itself.
modifiedLabels := getModifiedLabels(node.Labels, oldNode.Labels)
Expand Down
36 changes: 30 additions & 6 deletions plugin/pkg/admission/noderestriction/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,14 @@ func (a *admitTestCase) run(t *testing.T) {

func Test_nodePlugin_Admit(t *testing.T) {
var (
mynode = &user.DefaultInfo{Name: "system:node:mynode", Groups: []string{"system:nodes"}}
bob = &user.DefaultInfo{Name: "bob"}
trueRef = true
mynode = &user.DefaultInfo{Name: "system:node:mynode", Groups: []string{"system:nodes"}}
bob = &user.DefaultInfo{Name: "bob"}

mynodeObjMeta = metav1.ObjectMeta{Name: "mynode", UID: "mynode-uid"}
mynodeObjMetaOwnerRefA = metav1.ObjectMeta{Name: "mynode", UID: "mynode-uid", OwnerReferences: []metav1.OwnerReference{{Name: "fooerA", Controller: &trueRef}}}
mynodeObjMetaOwnerRefB = metav1.ObjectMeta{Name: "mynode", UID: "mynode-uid", OwnerReferences: []metav1.OwnerReference{{Name: "fooerB", Controller: &trueRef}}}

mynodeObjMeta = metav1.ObjectMeta{Name: "mynode", UID: "mynode-uid"}
mynodeObj = &api.Node{ObjectMeta: mynodeObjMeta}
mynodeObjConfigA = &api.Node{ObjectMeta: mynodeObjMeta, Spec: api.NodeSpec{ConfigSource: &api.NodeConfigSource{
ConfigMap: &api.ConfigMapNodeConfigSource{
Expand All @@ -280,9 +284,11 @@ func Test_nodePlugin_Admit(t *testing.T) {
KubeletConfigKey: "kubelet",
}}}}

mynodeObjTaintA = &api.Node{ObjectMeta: mynodeObjMeta, Spec: api.NodeSpec{Taints: []api.Taint{{Key: "mykey", Value: "A"}}}}
mynodeObjTaintB = &api.Node{ObjectMeta: mynodeObjMeta, Spec: api.NodeSpec{Taints: []api.Taint{{Key: "mykey", Value: "B"}}}}
othernodeObj = &api.Node{ObjectMeta: metav1.ObjectMeta{Name: "othernode"}}
mynodeObjTaintA = &api.Node{ObjectMeta: mynodeObjMeta, Spec: api.NodeSpec{Taints: []api.Taint{{Key: "mykey", Value: "A"}}}}
mynodeObjTaintB = &api.Node{ObjectMeta: mynodeObjMeta, Spec: api.NodeSpec{Taints: []api.Taint{{Key: "mykey", Value: "B"}}}}
mynodeObjOwnerRefA = &api.Node{ObjectMeta: mynodeObjMetaOwnerRefA}
mynodeObjOwnerRefB = &api.Node{ObjectMeta: mynodeObjMetaOwnerRefB}
othernodeObj = &api.Node{ObjectMeta: metav1.ObjectMeta{Name: "othernode"}}

coremymirrorpod, v1mymirrorpod = makeTestPod("ns", "mymirrorpod", "mynode", true)
coreothermirrorpod, v1othermirrorpod = makeTestPod("ns", "othermirrorpod", "othernode", true)
Expand Down Expand Up @@ -1222,6 +1228,24 @@ func Test_nodePlugin_Admit(t *testing.T) {
attributes: admission.NewAttributesRecord(setForbiddenUpdateLabels(mynodeObj, "new"), setForbiddenUpdateLabels(mynodeObj, "old"), nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: `is not allowed to modify labels: foo.node-restriction.kubernetes.io/foo, node-restriction.kubernetes.io/foo, other.k8s.io/foo, other.kubernetes.io/foo`,
},
{
name: "forbid update of my node: add owner reference",
podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjOwnerRefA, mynodeObj, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "node \"mynode\" is not allowed to modify ownerReferences",
},
{
name: "forbid update of my node: remove owner reference",
podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObj, mynodeObjOwnerRefA, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "node \"mynode\" is not allowed to modify ownerReferences",
},
{
name: "forbid update of my node: change owner reference",
podsGetter: existingPods,
attributes: admission.NewAttributesRecord(mynodeObjOwnerRefA, mynodeObjOwnerRefB, nodeKind, mynodeObj.Namespace, mynodeObj.Name, nodeResource, "", admission.Update, &metav1.UpdateOptions{}, false, mynode),
err: "node \"mynode\" is not allowed to modify ownerReferences",
},

// Other node object
{
Expand Down
2 changes: 1 addition & 1 deletion staging/publishing/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2901,4 +2901,4 @@ rules:
- staging/src/k8s.io/externaljwt
recursive-delete-patterns:
- '*/.gitattributes'
default-go-version: 1.24.4
default-go-version: 1.24.5
7 changes: 6 additions & 1 deletion staging/src/k8s.io/component-helpers/resource/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,12 @@ func maxResourceList(list, newList v1.ResourceList) {
// max returns the result of max(a, b...) for each named resource and is only used if we can't
// accumulate into an existing resource list
func max(a v1.ResourceList, b ...v1.ResourceList) v1.ResourceList {
result := a.DeepCopy()
var result v1.ResourceList
if a != nil {
result = a.DeepCopy()
} else {
result = v1.ResourceList{}
}
for _, other := range b {
maxResourceList(result, other)
}
Expand Down
86 changes: 72 additions & 14 deletions staging/src/k8s.io/component-helpers/resource/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/ptr"
)

func TestPodRequestsAndLimits(t *testing.T) {
Expand Down Expand Up @@ -1967,11 +1968,14 @@ func TestIsSupportedPodLevelResource(t *testing.T) {
func TestAggregateContainerRequestsAndLimits(t *testing.T) {
restartAlways := v1.ContainerRestartPolicyAlways
cases := []struct {
containers []v1.Container
initContainers []v1.Container
name string
expectedRequests v1.ResourceList
expectedLimits v1.ResourceList
options PodResourcesOptions
containers []v1.Container
containerStatuses []v1.ContainerStatus
initContainers []v1.Container
initContainerStatuses []v1.ContainerStatus
name string
expectedRequests v1.ResourceList
expectedLimits v1.ResourceList
}{
{
name: "one container with limits",
Expand Down Expand Up @@ -2135,20 +2139,74 @@ func TestAggregateContainerRequestsAndLimits(t *testing.T) {
v1.ResourceName(v1.ResourceCPU): resource.MustParse("17"),
},
},
{
name: "regularcontainers with empty requests, but status with non-empty requests",
options: PodResourcesOptions{UseStatusResources: true},
containers: []v1.Container{
{
Name: "container-1",
Resources: v1.ResourceRequirements{},
},
},
containerStatuses: []v1.ContainerStatus{
{
Name: "container-1",
Resources: &v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("2"),
},
},
},
},
expectedRequests: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("2"),
},
expectedLimits: v1.ResourceList{},
},
{
name: "always-restart init containers with empty requests, but status with non-empty requests",
options: PodResourcesOptions{UseStatusResources: true},
initContainers: []v1.Container{
{
Name: "container-1",
RestartPolicy: ptr.To[v1.ContainerRestartPolicy](v1.ContainerRestartPolicyAlways),
Resources: v1.ResourceRequirements{},
},
},
initContainerStatuses: []v1.ContainerStatus{
{
Name: "container-1",
Resources: &v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("2"),
},
},
},
},
expectedRequests: v1.ResourceList{
v1.ResourceCPU: resource.MustParse("2"),
},
expectedLimits: v1.ResourceList{},
},
}

for idx, tc := range cases {
testPod := &v1.Pod{Spec: v1.PodSpec{Containers: tc.containers, InitContainers: tc.initContainers}}
resRequests := AggregateContainerRequests(testPod, PodResourcesOptions{})
resLimits := AggregateContainerLimits(testPod, PodResourcesOptions{})
t.Run(tc.name, func(t *testing.T) {
testPod := &v1.Pod{
Spec: v1.PodSpec{Containers: tc.containers, InitContainers: tc.initContainers},
Status: v1.PodStatus{ContainerStatuses: tc.containerStatuses, InitContainerStatuses: tc.initContainerStatuses},
}
resRequests := AggregateContainerRequests(testPod, tc.options)
resLimits := AggregateContainerLimits(testPod, tc.options)

if !equality.Semantic.DeepEqual(tc.expectedRequests, resRequests) {
t.Errorf("test case failure[%d]: %v, requests:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedRequests, resRequests)
}
if !equality.Semantic.DeepEqual(tc.expectedRequests, resRequests) {
t.Errorf("test case failure[%d]: %v, requests:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedRequests, resRequests)
}

if !equality.Semantic.DeepEqual(tc.expectedLimits, resLimits) {
t.Errorf("test case failure[%d]: %v, limits:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedLimits, resLimits)
}
if !equality.Semantic.DeepEqual(tc.expectedLimits, resLimits) {
t.Errorf("test case failure[%d]: %v, limits:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedLimits, resLimits)
}
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/images/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ REGISTRY ?= registry.k8s.io/e2e-test-images
GOARM ?= 7
DOCKER_CERT_BASE_PATH ?=
QEMUVERSION=v5.1.0-2
GOLANG_VERSION=1.24.4
GOLANG_VERSION=1.24.5
export

ifndef WHAT
Expand Down
2 changes: 1 addition & 1 deletion test/utils/image/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config
configs[APIServer] = Config{list.PromoterE2eRegistry, "sample-apiserver", "1.29.2"}
configs[AppArmorLoader] = Config{list.PromoterE2eRegistry, "apparmor-loader", "1.4"}
configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.36.1-1"}
configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.7.6"}
configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.7.7"}
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.21-0"}
configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"}
configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"}
Expand Down