* Moves TestPrintUnstructuredObject to tableprinter_test.go
* Move TestUnknownTypePrinting to correct location of tableprinter_test.go
* Removes NewTablePrinter from TestCustomTypePrinting
When scaling down a ReplicaSet, delete doubled up replicas first, where a
"doubled up replica" is defined as one that is on the same node as an
active replica belonging to a related ReplicaSet. ReplicaSets are
considered "related" if they have a common controller (typically a
Deployment).
The intention of this change is to make a rolling update of a Deployment
scale down the old ReplicaSet as it scales up the new ReplicaSet by
deleting pods from the old ReplicaSet that are colocated with ready pods of
the new ReplicaSet. This change in the behavior of rolling updates can be
combined with pod affinity rules to preserve the locality of a Deployment's
pods over rollout.
A specific scenario that benefits from this change is when a Deployment's
pods are exposed by a Service that has type "LoadBalancer" and external
traffic policy "Local". In this scenario, the load balancer uses health
checks to determine whether it should forward traffic for the Service to a
particular node. If the node has no local endpoints for the Service, the
health check will fail for that node. Eventually, the load balancer will
stop forwarding traffic to that node. In the meantime, the service proxy
drops traffic for that Service. Thus, in order to reduce risk of dropping
traffic during a rolling update, it is desirable preserve node locality of
endpoints.
* pkg/controller/controller_utils.go (ActivePodsWithRanks): New type to
sort pods using a given ranking.
* pkg/controller/controller_utils_test.go (TestSortingActivePodsWithRanks):
New test for ActivePodsWithRanks.
* pkg/controller/replicaset/replica_set.go
(getReplicaSetsWithSameController): New method. Given a ReplicaSet, return
all ReplicaSets that have the same owner.
(manageReplicas): Call getIndirectlyRelatedPods, and pass its result to
getPodsToDelete.
(getIndirectlyRelatedPods): New method. Given a ReplicaSet, return all
pods that are owned by any ReplicaSet with the same owner.
(getPodsToDelete): Add an argument for related pods. Use related pods and
the new getPodsRankedByRelatedPodsOnSameNode function to take into account
whether a pod is doubled up when sorting pods for deletion.
(getPodsRankedByRelatedPodsOnSameNode): New function. Return an
ActivePodsWithRanks value that wraps the given slice of pods and computes
ranks where each pod's rank is equal to the number of active related pods
that are colocated on the same node.
* pkg/controller/replicaset/replica_set_test.go (newReplicaSet): Set
OwnerReferences on the ReplicaSet.
(newPod): Set a unique UID on the pod.
(byName): New type to sort pods by name.
(TestGetReplicaSetsWithSameController): New test for
getReplicaSetsWithSameController.
(TestRelatedPodsLookup): New test for getIndirectlyRelatedPods.
(TestGetPodsToDelete): Augment the "various pod phases and conditions, diff
= len(pods)" test case to ensure that scale-down still selects doubled-up
pods if there are not enough other pods to scale down. Add a "various pod
phases and conditions, diff = len(pods), relatedPods empty" test case to
verify that getPodsToDelete works even if related pods could not be
determined. Add a "ready and colocated with another ready pod vs not
colocated, diff < len(pods)" test case to verify that a doubled-up pod gets
preferred for deletion. Augment the "various pod phases and conditions,
diff < len(pods)" test case to ensure that not-ready pods are preferred
over ready but doubled-up pods.
* pkg/controller/replicaset/BUILD: Regenerate.
* test/e2e/apps/deployment.go
(testRollingUpdateDeploymentWithLocalTrafficLoadBalancer): New end-to-end
test. Create a deployment with a rolling update strategy and affinity
rules and a load balancer with "Local" external traffic policy, and verify
that set of nodes with local endponts for the service remains unchanged
during rollouts.
(setAffinity): New helper, used by
testRollingUpdateDeploymentWithLocalTrafficLoadBalancer.
* test/e2e/framework/service/jig.go (GetEndpointNodes): Factor building the
set of node names out...
(GetEndpointNodeNames): ...into this new method.
Added test TestPrintEvent()
Added test TestPrintNamespace()
Added test TestPrintSecret()
Added test TestPrintServiceAccount()
Added test TestPrintPodCondition()
Added test TestPrintDaemonSetLists
Added test TestPrintJobList
Added test TestPrintPodDisruptionBudgetList
Adds test TestPrintConfigMap
Adds test TestPrintNetworkPolicy
Adds tests TestPrintRoleBinding and TestPrintClusterRoleBinding
Adds test TestPrintCertificateSigningRequest
Adds test TestPrintEndpoint
Adds test TestPrintReplicaSetList
Adds test TestPrintComponentStatus
Adds test TestPrintCronJobList
Adds test TestPrintPodTemplate
Adds test TestPrintPodTemplateList
Adds test TestPrintReplicationController
Adds test TestPrintServiceList
Adds test TestPrintStatefulSet
Updated test TestPrintNodeStatus() to not use NewTableGenerator or NewTablePrinter
Updated test TestPrintNodeRode() to not use NewTableGenerator or NewTablePrinter
Updated test TestPrintNodeOSImage() to remove NewTableGenerator and NewTablePrinter
Updated test TestPrintNodeKernelVersion() to remove NewTableGenerator and NewTablePrinter
Updated test TestPrintNodeContainerRuntimeVersion() to remove NewTableGenerator and NewTablePrinter
Updated test TestPrintNodeName() to remove NewTableGenerator and NewTablePrinter
Updated test TestPrintNodeExternalIP() to remove NewTableGenerator and NewTablePrinter
Updated test TestPrintNodeInternalIP() to remove NewTableGenerator and NewTablePrinter
Updated ingress printing test to TestPrintIngress()
Updated test TestPrintService() to remove NewTableGenerator and NewTablePrinter
Updated test to TestPrintServiceLoadBalancer, removing NewTableGenerator and NewTablePrinter
Updated test TestPrintNonTerminatedPod() to remove NewTableGenerator
Updates test TestPrintDeployment() removing NewTableGenerator and NewTablePrinter
Updated test TestPrintDaemonSet(), removing NewTableGenerator and NewTablePrinter
Updated test TestPrintJob, removing NewTableGenerator and NewTablePrinter
Updates test TestPrintHPA(), removing NewTableGenerator and NewTablePrinter
Updated test TestPrintPodDisruptionBudget(), removing NewTableGenerator and NewTablePrinter
Updated test TestPrintControllerRevision(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintLease, removing NewTableGenerator and NewTablePrinter
Updates test TestPrintPriorityClass(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintRuntimeClass(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintEndpointSlice(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintReplicaSet(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintPersistentVolume(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintPersistentVolumneClaim(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintCronJob(), removing NewTableGenerator and NewTablePrinter
Updates test TestPrintStorageClass(), removing NewTableGenerator and NewTablePrinter
Computing EndpointChanges is a relatively expensive operation for
kube-proxy when Endpoint Slices are used. This had been computed on
every EndpointSlice update which became quite inefficient at high levels
of scale when multiple EndpointSlice update events would be triggered
before a syncProxyRules call.
Profiling results showed that computing this on each update could
consume ~80% of total kube-proxy CPU utilization at high levels of
scale. This change reduced that to as little as 3% of total kube-proxy
utilization at high levels of scale.
It's worth noting that the difference is minimal when there is a 1:1
relationship between EndpointSlice updates and proxier syncs. This is
primarily beneficial when there are many EndpointSlice updates between
proxier sync loops.