Skip to content
Open
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.25.9
1.25.11
312 changes: 207 additions & 105 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.25.9-bullseye.0
v1.33.0-go1.25.11-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.8.9
readonly __default_go_runner_version=v2.4.0-go1.25.9-bookworm.0
readonly __default_distroless_iptables_version=v0.8.11
readonly __default_go_runner_version=v2.4.0-go1.25.11-bookworm.0
readonly __default_setcap_version=bookworm-v1.0.6

# These are the base images for the Docker-wrapped binaries.
Expand Down
6 changes: 3 additions & 3 deletions build/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ dependencies:
# match: minimum_go_version=go([0-9]+\.[0-9]+)

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

Expand Down Expand Up @@ -162,15 +162,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.8.9
version: v0.8.11
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.25.9-bookworm.0
version: v2.4.0-go1.25.11-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.12"
io.openshift.build.versions="kubernetes=1.33.13"
18 changes: 16 additions & 2 deletions pkg/controller/endpoint/endpoints_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,22 @@ func (e *Controller) addPod(obj interface{}) {

func podToEndpointAddressForService(svc *v1.Service, pod *v1.Pod) (*v1.EndpointAddress, error) {
var endpointIP string

wantIPv6 := svc.Spec.IPFamilies[0] == v1.IPv6Protocol
ipFamily := v1.IPv4Protocol

// IPFamilies is expected to be populated by apiserver defaulting, but
// some services may reach this controller with an empty IPFamilies via
// watch events. Infer the family from ClusterIP or
// pod IP so we never panic on IPFamilies[0].
if len(svc.Spec.IPFamilies) > 0 {
ipFamily = svc.Spec.IPFamilies[0]
} else if len(svc.Spec.ClusterIP) > 0 && svc.Spec.ClusterIP != v1.ClusterIPNone {
if utilnet.IsIPv6String(svc.Spec.ClusterIP) {
ipFamily = v1.IPv6Protocol
}
} else if utilnet.IsIPv6String(pod.Status.PodIP) {
ipFamily = v1.IPv6Protocol
}
wantIPv6 := ipFamily == v1.IPv6Protocol

// Find an IP that matches the family. We parse and restringify the IP in case the
// value on the Pod is in an irregular format.
Expand Down
80 changes: 80 additions & 0 deletions pkg/controller/endpoint/endpoints_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2924,3 +2924,83 @@ func TestEndpointSubsetsEqualIgnoreResourceVersion(t *testing.T) {
})
}
}

func TestPodToEndpointAddressForServiceEmptyIPFamilies(t *testing.T) {
testCases := []struct {
name string
clusterIP string
podIPs []v1.PodIP
podIP string
wantErr bool
wantFamily v1.IPFamily
}{
{
name: "headful IPv4, IPv4 pod",
clusterIP: "10.0.0.1",
podIPs: []v1.PodIP{{IP: "10.244.0.1"}},
wantFamily: v1.IPv4Protocol,
},
{
name: "headful IPv6, IPv6 pod",
clusterIP: "fd00::1",
podIPs: []v1.PodIP{{IP: "fd00::10"}},
wantFamily: v1.IPv6Protocol,
},
{
name: "headful IPv4, no matching pod IP",
clusterIP: "10.0.0.1",
podIPs: []v1.PodIP{{IP: "fd00::10"}},
wantErr: true,
},
{
name: "headless, IPv4 pod",
clusterIP: v1.ClusterIPNone,
podIPs: []v1.PodIP{{IP: "10.244.0.1"}},
podIP: "10.244.0.1",
wantFamily: v1.IPv4Protocol,
},
{
name: "headless, IPv6 pod",
clusterIP: v1.ClusterIPNone,
podIPs: []v1.PodIP{{IP: "fd00::10"}},
podIP: "fd00::10",
wantFamily: v1.IPv6Protocol,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
svc := &v1.Service{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: v1.ServiceSpec{
// Intentionally leave IPFamilies empty.
ClusterIP: tc.clusterIP,
},
}
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo-pod", Namespace: "bar", UID: "uid-1"},
Spec: v1.PodSpec{NodeName: "node-1"},
Status: v1.PodStatus{PodIP: tc.podIP, PodIPs: tc.podIPs},
}

addr, err := podToEndpointAddressForService(svc, pod)
if tc.wantErr {
if err == nil {
t.Fatalf("expected error but got addr=%v", addr)
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if addr == nil {
t.Fatal("expected an address but got nil")
}
isV6 := utilnet.IsIPv6String(addr.IP)
wantV6 := tc.wantFamily == v1.IPv6Protocol
if isV6 != wantV6 {
t.Errorf("got IP %q (IPv6=%v), want family %v", addr.IP, isV6, tc.wantFamily)
}
})
}
}
Loading