Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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.23.6
1.23.8
251 changes: 176 additions & 75 deletions CHANGELOG/CHANGELOG-1.32.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.32.0-go1.23.6-bullseye.0
v1.32.0-go1.23.8-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.6.8
readonly __default_go_runner_version=v2.4.0-go1.23.6-bookworm.0
readonly __default_distroless_iptables_version=v0.6.9
readonly __default_go_runner_version=v2.4.0-go1.23.8-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.23.6
version: 1.23.8
refPaths:
- path: .go-version
- path: build/build-image/cross/VERSION
Expand All @@ -140,7 +140,7 @@ dependencies:
match: golang:([0-9]+\.[0-9]+).0-bullseye

- name: "registry.k8s.io/kube-cross: dependents"
version: v1.32.0-go1.23.6-bullseye.0
version: v1.32.0-go1.23.8-bullseye.0
refPaths:
- path: build/build-image/cross/VERSION

Expand Down Expand Up @@ -178,15 +178,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.6.8
version: v0.6.9
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.23.6-bookworm.0
version: v2.4.0-go1.23.8-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.32.4"
io.openshift.build.versions="kubernetes=1.32.5"
65 changes: 34 additions & 31 deletions pkg/proxy/winkernel/hns.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,40 +133,43 @@ func (hns hns) getAllEndpointsByNetwork(networkName string) (map[string]*(endpoi
continue
}

// Add to map with key endpoint ID or IP address
// Storing this is expensive in terms of memory, however there is a bug in Windows Server 2019 that can cause two endpoints to be created with the same IP address.
// TODO: Store by IP only and remove any lookups by endpoint ID.
endpointInfos[ep.Id] = &endpointInfo{
ip: ep.IpConfigurations[0].IpAddress,
isLocal: uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0,
macAddress: ep.MacAddress,
hnsID: ep.Id,
hns: hns,
// only ready and not terminating endpoints were added to HNS
ready: true,
serving: true,
terminating: false,
}
endpointInfos[ep.IpConfigurations[0].IpAddress] = endpointInfos[ep.Id]
for index, ipConfig := range ep.IpConfigurations {

if index > 1 {
// Expecting only ipv4 and ipv6 ipaddresses
// This is highly unlikely to happen, but if it does, we should log a warning
// and break out of the loop
klog.Warning("Endpoint ipconfiguration holds more than 2 IP addresses.", "hnsID", ep.Id, "IP", ipConfig.IpAddress, "ipConfigCount", len(ep.IpConfigurations))
break
}

if len(ep.IpConfigurations) == 1 {
continue
}
isLocal := uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0

// If ipFamilyPolicy is RequireDualStack or PreferDualStack, then there will be 2 IPS (iPV4 and IPV6)
// in the endpoint list
endpointDualstack := &endpointInfo{
ip: ep.IpConfigurations[1].IpAddress,
isLocal: uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0,
macAddress: ep.MacAddress,
hnsID: ep.Id,
hns: hns,
// only ready and not terminating endpoints were added to HNS
ready: true,
serving: true,
terminating: false,
if existingEp, ok := endpointInfos[ipConfig.IpAddress]; ok && isLocal {
// If the endpoint is already part of the queried endpoints map and is local,
// then we should not add it again to the map
// This is to avoid overwriting the remote endpoint info with a local endpoint.
klog.V(3).InfoS("Endpoint already exists in queried endpoints map; skipping.", "newLocalEndpoint", ep, "ipConfig", ipConfig, "existingEndpoint", existingEp)
continue
}

// Add to map with key endpoint ID or IP address
// Storing this is expensive in terms of memory, however there is a bug in Windows Server 2019 and 2022 that can cause two endpoints (local and remote) to be created with the same IP address.
// TODO: Store by IP only and remove any lookups by endpoint ID.
epInfo := &endpointInfo{
ip: ipConfig.IpAddress,
isLocal: isLocal,
macAddress: ep.MacAddress,
hnsID: ep.Id,
hns: hns,
// only ready and not terminating endpoints were added to HNS
ready: true,
serving: true,
terminating: false,
}
endpointInfos[ep.Id] = epInfo
endpointInfos[ipConfig.IpAddress] = epInfo
}
endpointInfos[ep.IpConfigurations[1].IpAddress] = endpointDualstack
}
klog.V(3).InfoS("Queried endpoints from network", "network", networkName)
klog.V(5).InfoS("Queried endpoints details", "network", networkName, "endpointInfos", endpointInfos)
Expand Down
64 changes: 64 additions & 0 deletions pkg/proxy/winkernel/hns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,70 @@ func TestGetAllEndpointsByNetwork(t *testing.T) {
}
}

func TestGetAllEndpointsByNetworkWithDupEP(t *testing.T) {
hcnMock := getHcnMock("L2Bridge")
hns := hns{hcn: hcnMock}

ipv4Config := &hcn.IpConfig{
IpAddress: epIpAddress,
}
ipv6Config := &hcn.IpConfig{
IpAddress: epIpv6Address,
}
remoteEndpoint := &hcn.HostComputeEndpoint{
IpConfigurations: []hcn.IpConfig{*ipv4Config, *ipv6Config},
MacAddress: epMacAddress,
SchemaVersion: hcn.SchemaVersion{
Major: 2,
Minor: 0,
},
Flags: hcn.EndpointFlagsRemoteEndpoint,
}
Network, _ := hcnMock.GetNetworkByName(testNetwork)
remoteEndpoint, err := hns.hcn.CreateEndpoint(Network, remoteEndpoint)
if err != nil {
t.Error(err)
}

// Create a duplicate local endpoint with the same IP address
dupLocalEndpoint := &hcn.HostComputeEndpoint{
IpConfigurations: []hcn.IpConfig{*ipv4Config, *ipv6Config},
MacAddress: epMacAddress,
SchemaVersion: hcn.SchemaVersion{
Major: 2,
Minor: 0,
},
}

dupLocalEndpoint, err = hns.hcn.CreateEndpoint(Network, dupLocalEndpoint)
if err != nil {
t.Error(err)
}

mapEndpointsInfo, err := hns.getAllEndpointsByNetwork(Network.Name)
if err != nil {
t.Error(err)
}
endpointIpv4, ipv4EpPresent := mapEndpointsInfo[ipv4Config.IpAddress]
assert.True(t, ipv4EpPresent, "IPV4 endpoint is missing in Dualstack mode")
assert.Equal(t, endpointIpv4.ip, epIpAddress, "IPV4 IP is missing in Dualstack mode")
assert.Equal(t, endpointIpv4.hnsID, remoteEndpoint.Id, "HNS ID is not matching with remote endpoint")

endpointIpv6, ipv6EpPresent := mapEndpointsInfo[ipv6Config.IpAddress]
assert.True(t, ipv6EpPresent, "IPV6 endpoint is missing in Dualstack mode")
assert.Equal(t, endpointIpv6.ip, epIpv6Address, "IPV6 IP is missing in Dualstack mode")
assert.Equal(t, endpointIpv6.hnsID, remoteEndpoint.Id, "HNS ID is not matching with remote endpoint")

err = hns.hcn.DeleteEndpoint(remoteEndpoint)
if err != nil {
t.Error(err)
}
err = hns.hcn.DeleteEndpoint(dupLocalEndpoint)
if err != nil {
t.Error(err)
}
}

func TestGetEndpointByID(t *testing.T) {
// TODO: remove skip once the test has been fixed.
t.Skip("Skipping failing test on Windows.")
Expand Down
15 changes: 12 additions & 3 deletions pkg/proxy/winkernel/proxier.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,11 @@ func (ep *endpointInfo) DecrementRefCount() {
if !ep.IsLocal() && ep.refCount != nil && *ep.refCount > 0 {
*ep.refCount--
}
refCount := 0
if ep.refCount != nil {
refCount = int(*ep.refCount)
}
klog.V(5).InfoS("Endpoint RefCount after decrement.", "endpointInfo", ep, "refCount", refCount)
}

func (ep *endpointInfo) Cleanup() {
Expand Down Expand Up @@ -1709,10 +1714,14 @@ func (proxier *Proxier) syncProxyRules() {

// remove stale endpoint refcount entries
for epIP := range proxier.terminatedEndpoints {
if epToDelete := queriedEndpoints[epIP]; epToDelete != nil && epToDelete.hnsID != "" {
klog.V(5).InfoS("Terminated endpoints ready for deletion", "epIP", epIP)
if epToDelete := queriedEndpoints[epIP]; epToDelete != nil && epToDelete.hnsID != "" && !epToDelete.IsLocal() {
if refCount := proxier.endPointsRefCount.getRefCount(epToDelete.hnsID); refCount == nil || *refCount == 0 {
klog.V(3).InfoS("Deleting unreferenced remote endpoint", "hnsID", epToDelete.hnsID)
proxier.hns.deleteEndpoint(epToDelete.hnsID)
klog.V(3).InfoS("Deleting unreferenced remote endpoint", "hnsID", epToDelete.hnsID, "IP", epToDelete.ip)
err := proxier.hns.deleteEndpoint(epToDelete.hnsID)
if err != nil {
klog.ErrorS(err, "Deleting unreferenced remote endpoint failed", "hnsID", epToDelete.hnsID)
}
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions pkg/proxy/winkernel/proxier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ func NewFakeProxier(syncPeriod time.Duration, minSyncPeriod time.Duration, hostn
return proxier
}

func getHcnMock(networkType string) *fakehcn.HcnMock {
var remoteSubnets []*remoteSubnetInfo
rs := &remoteSubnetInfo{
destinationPrefix: destinationPrefix,
isolationID: 4096,
providerAddress: providerAddress,
drMacAddress: macAddress,
}
remoteSubnets = append(remoteSubnets, rs)
hnsNetworkInfo := &hnsNetworkInfo{
id: strings.ToUpper(guid),
name: testNetwork,
networkType: networkType,
remoteSubnets: remoteSubnets,
}
hnsNetwork := newHnsNetwork(hnsNetworkInfo)
hcnMock := fakehcn.NewHcnMock(hnsNetwork)
return hcnMock
}

func TestCreateServiceVip(t *testing.T) {
syncPeriod := 30 * time.Second
proxier := NewFakeProxier(syncPeriod, syncPeriod, "testhost", netutils.ParseIPSloppy("10.0.0.1"), NETWORK_TYPE_OVERLAY)
Expand Down
23 changes: 11 additions & 12 deletions pkg/volume/util/operationexecutor/node_expander_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,18 +139,6 @@ func TestNodeExpander(t *testing.T) {
expectFinalErrors: false,
expectedStatusSize: resource.MustParse("2G"),
},
{
name: "RWX pv.spec.cap = pvc.status.cap, resizeStatus='', desiredSize > actualSize, reize_op=unsupported",
pvc: addAccessMode(getTestPVC(volumetesting.FailWithUnSupportedVolumeName, "2G", "2G", "2G", nil), v1.ReadWriteMany),
pv: getTestPV(volumetesting.FailWithUnSupportedVolumeName, "2G"),
recoverVolumeExpansionFailure: true,
expectError: false,
expectedResizeStatus: "",
expectResizeCall: false,
assumeResizeOpAsFinished: true,
expectFinalErrors: false,
expectedStatusSize: resource.MustParse("2G"),
},
{
name: "pv.spec.cap > pvc.status.cap, resizeStatus=node_expansion_pending, featuregate=disabled",
pvc: getTestPVC("test-vol0", "2G", "1G", "2G", &nodeResizePending),
Expand All @@ -163,6 +151,17 @@ func TestNodeExpander(t *testing.T) {
expectFinalErrors: false,
expectedStatusSize: resource.MustParse("2G"),
},
{
name: "RWX pv.spec.cap = pvc.status.cap, resizeStatus='', desiredSize > actualSize, reize_op=unsupported",
pvc: addAccessMode(getTestPVC(volumetesting.FailWithUnSupportedVolumeName, "2G", "2G", "2G", nil), v1.ReadWriteMany),
pv: getTestPV(volumetesting.FailWithUnSupportedVolumeName, "2G"),
expectError: false,
expectedResizeStatus: "",
expectResizeCall: false,
assumeResizeOpAsFinished: true,
expectFinalErrors: false,
expectedStatusSize: resource.MustParse("2G"),
},
}

for i := range tests {
Expand Down
2 changes: 1 addition & 1 deletion staging/publishing/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2900,4 +2900,4 @@ rules:
- staging/src/k8s.io/externaljwt
recursive-delete-patterns:
- '*/.gitattributes'
default-go-version: 1.23.6
default-go-version: 1.23.8
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.23.6
GOLANG_VERSION=1.23.8
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.6.8"}
configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.6.9"}
configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.16-0"}
configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"}
configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"}
Expand Down