The ipallocator was blindly assuming that all errors are retryable, that
causes that the allocator tries to exhaust all the possibilities to
allocate an IP address.
If the error is not retryable this means the allocator will generate as
many API calls as existing available IPs are in the allocator, causing
CPU exhaustion since this requests are coming from inside the apiserver.
In addition to handle the error correctly, this patch also interpret the
error to return the right status code depending on the error type.
Co-authored-by: carlory <baofa.fan@daocloud.io>
An ipAllocator with a 64 bit IPv6 CIDR can allocate
addresses outside the CIDR range, due to an improper uint64 to int64
cast in the addOffsetAddress function.
Replace the cast with a call to `math/big.Int.SetUint64()`.
Service storage implements transactions. It creates an IPAddress object first and then creates
the Service object, and if the Service object already exists the complete transaction is
reverted. There can be race conditions when the repair loop picks up the new IPAddress object
for reconciliation before the transaction is reverted. This leads to spurious
IPAddressWrongReference warnings, to suppress these warnings we delay the processing of the new
IPAddress object by 5 seconds. The service allocation creates the IPAddress object before creating
the Service object, we easily identify this scenario when the IPAddress object creation timestamp
is after the Service creation timestamp. We do this only when the IPAddress object is created
recently in order to avoid indefinitely requeue/delay in IPAddress cleanup if for some reason
the service transaction revert fails.
Signed-off-by: Daman Arora <aroradaman@gmail.com>
The private constructor for the repair loop now consumes clock.Clock interface allowing
predictable unit testing.
Signed-off-by: Daman Arora <aroradaman@gmail.com>
Ignore pre-existing bad IP/CIDR values in:
- pod.spec.podIP(s)
- pod.spec.hostIP(s)
- service.spec.externalIPs
- service.spec.clusterIP(s)
- service.spec.loadBalancerSourceRanges (and corresponding annotation)
- service.status.loadBalancer.ingress[].ip
- endpoints.subsets
- endpointslice.endpoints
- networkpolicy.spec.{ingress[].from[],egress[].to[]}.ipBlock
- ingress.status.loadBalancer.ingress[].ip
In the Endpoints and EndpointSlice case, if *any* endpoint IP is
changed, then the entire object must be valid; invalid IPs are only
allowed to remain in place for updates that don't change any IPs.
(e.g., changing the labels or annotations).
In most of the other cases, when the invalid IP is part of an array,
it can be moved around within the array without triggering
revalidation.
Kubernetes clusters allow to define an IPv6 range of /108 for IPv6
despite the old allocators will only use the first /112 of that range.
The new allocators does not have this limitation, so they can allocate
IPs on the whole space, the problem happens on upgrades from clusters
that were already using this size, since the new allocators by default
will try to allocate addresses that works for both new and old allocatos
to allow safe upgrades.
The new allocators, when configured to keep compatibility with the old
allocators, must try first to allocate an IP that is compatible with the
old allocators and only fall back to the new behavior if it is not
possible.
The "// import <path>" comment has been superseded by Go modules.
We don't have to remove them, but doing so has some advantages:
- They are used inconsistently, which is confusing.
- We can then also remove the (currently broken) hack/update-vanity-imports.sh.
- Last but not least, it would be a first step towards avoiding the k8s.io domain.
This commit was generated with
sed -i -e 's;^package \(.*\) // import.*;package \1;' $(git grep -l '^package.*// import' | grep -v 'vendor/')
Everything was included, except for
package labels // import k8s.io/kubernetes/pkg/util/labels
because that package is marked as "read-only".
MultiCIDRServiceAllocator implements a new ClusterIP allocator based on
IPAddress object to solve the problems and limitations caused by
existing bitmap allocators.
However, during the rollout of new versions, deployments need to support
a skew of one version between kube-apiservers. To avoid the possible
problem where there are multiple Services requests on the skewed
apiservers and that both allocate the same IP to different Services,
the new allocator will implement a dual-write strategy under the
feature gate DisableAllocatorDualWrite.
After the MultiCIDRServiceAllocator is GA, the DisableAllocatorDualWrite
can be enabled safely as all apiservers will run with the new
allocators. The graduation of DisableAllocatorDualWrite can also
be used to clean up the opaque API object that contains the old bitmaps.
If MultiCIDRServiceAllocator is enabled and DisableAllocatorDualWrite is disable
and is a new environment, there is no bitmap object created, hence, the
apiserver will initialize it to be able to write on it.
ServiceCIDRs are protected by finalizers and the CIDRs fields are
inmutable once set, only the readiness state impact the allocator
as it can only allocate IPs if any of the ServiceCIDR is ready.
The Add/Update events triggers a reconcilation of the current state
of the ServiceCIDR present in the informers with the existing IP
allocators.
The Delete events are handled directly to update or delete the
corresponing IP allocator.
The new k8s.io/utils/ptr package provides generic wrapper functions,
which can be used instead of type-specific pointer wrapper functions.
This replaces the latter with the former, and migrates other uses of
the deprecated pointer package to ptr in affacted files.
See kubernetes/utils#283 for details.
Signed-off-by: Lan Liang <gcslyp@gmail.com>
This will allow components that don't need to watch headless services
(heavily used on ai/ml workloads) to filter them server side.
Specially useful for kubelet and kube-proxy
Change-Id: If36c2c27f2ec80db400c9133c61428d14e124f3e
This will allow components that don't need to watch headless services
(heavily used on ai/ml workloads) to filter them server side.
Specially useful for kubelet and kube-proxy
Co-authored-by: Jianbo Ma <sakuranlbj@gmail.com>
Change-Id: I6434d2c8c77aaf725ec5c07acbcda14311f24bfa
Change-Id: Iba9e25afb90712facfb3dee25c500bbe08ef38fc
the original logic always guarantee the NodePort's value if it was there. the NodePort should be allowed to set 0 if the Service has LB type with AllocateLoadBalancerNodePorts=false