Skip to content

Commit

Permalink
Fix Pod use old IP when update StatefulSet pool name with annotation
Browse files Browse the repository at this point in the history
Signed-off-by: lou-lan <[email protected]>
  • Loading branch information
lou-lan committed Jun 27, 2024
1 parent 5566f50 commit 366ae3a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
63 changes: 63 additions & 0 deletions pkg/ipam/allocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,53 @@ func (i *ipam) Allocate(ctx context.Context, addArgs *models.IpamAddArgs) (*mode
logger.Debug("No Endpoint")
}

if i.config.EnableStatefulSet && podTopController.APIVersion == appsv1.SchemeGroupVersion.String() && podTopController.Kind == constant.KindStatefulSet {
if endpoint != nil {
preliminary, err := i.getPoolCandidates(ctx, addArgs, pod, podTopController)
if err != nil {
return nil, err
}
poolMap := make(map[string]map[string]struct{})
for _, candidates := range preliminary {
if _, ok := poolMap[candidates.NIC]; !ok {
poolMap[candidates.NIC] = make(map[string]struct{})
}
pools := candidates.Pools()
for _, pool := range pools {
poolMap[candidates.NIC][pool] = struct{}{}
}
}
endpointMap := make(map[string]map[string]struct{})
for _, ip := range endpoint.Status.Current.IPs {
if _, ok := endpointMap[ip.NIC]; !ok {
endpointMap[ip.NIC] = make(map[string]struct{})
}
if ip.IPv4Pool != nil && *ip.IPv4Pool != "" {
endpointMap[ip.NIC][*ip.IPv4Pool] = struct{}{}
}
if ip.IPv6Pool != nil && *ip.IPv6Pool != "" {
endpointMap[ip.NIC][*ip.IPv6Pool] = struct{}{}
}
}
if !checkEndpointInPool(endpointMap, poolMap) {
if endpoint.DeletionTimestamp == nil {
logger.Sugar().Infof("delete outdated endpoints: %v/%v", endpoint.Namespace, endpoint.Name)
if err := i.endpointManager.DeleteEndpoint(ctx, endpoint); err != nil {
return nil, err
}
}
err := i.release(ctx, endpoint.Status.Current.UID, endpoint.Status.Current.IPs)
if err != nil {
return nil, err
}
logger.Info("remove outdated endpoints")
if err := i.endpointManager.RemoveFinalizer(ctx, endpoint); err != nil {
return nil, fmt.Errorf("failed to clean Endpoint: %v", err)
}
endpoint = nil
}
}
}
if (i.config.EnableStatefulSet && podTopController.APIVersion == appsv1.SchemeGroupVersion.String() && podTopController.Kind == constant.KindStatefulSet) ||
(i.config.EnableKubevirtStaticIP && podTopController.APIVersion == kubevirtv1.SchemeGroupVersion.String() && podTopController.Kind == constant.KindKubevirtVMI) {
logger.Sugar().Infof("Try to retrieve the IP allocation of %s", podTopController.Kind)
Expand Down Expand Up @@ -98,6 +145,22 @@ func (i *ipam) Allocate(ctx context.Context, addArgs *models.IpamAddArgs) (*mode
return addResp, nil
}

func checkEndpointInPool(endpointMap, poolMap map[string]map[string]struct{}) bool {
for outerKey, innerMap := range endpointMap {
poolInnerMap, exists := poolMap[outerKey]
if !exists {
return false
}

for innerKey := range innerMap {
if _, exists := poolInnerMap[innerKey]; !exists {
return false
}
}
}
return true
}

func (i *ipam) retrieveStaticIPAllocation(ctx context.Context, nic string, pod *corev1.Pod, endpoint *spiderpoolv2beta1.SpiderEndpoint) (*models.IpamAddResponse, error) {
logger := logutils.FromContext(ctx)

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/affinity/affinity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,13 +500,13 @@ var _ = Describe("test Affinity", Label("affinity"), func() {
}
GinkgoWriter.Printf("StatefulSet %s/%s corresponding Pod IP allocations: %v \n", stsObject.Namespace, stsObject.Name, ipMap)

// A00009:Modify the annotated IPPool for a specified StatefulSet pod, the pod wouldn't change IP
// A00009:Modify the annotated IPPool for a specified StatefulSet pod, the pod will change IP
podIppoolAnnoStr = common.GeneratePodIPPoolAnnotations(frame, common.NIC1, []string{v4PoolName}, []string{v6PoolName})
stsObject, err = frame.GetStatefulSet(statefulSetName, namespace)
Expect(err).NotTo(HaveOccurred())
stsObject.Spec.Template.Annotations = map[string]string{constant.AnnoPodIPPool: podIppoolAnnoStr}
// Modify the ippool in annotation and update the statefulset
GinkgoWriter.Printf("try to update StatefulSet %s/%s template with new annotations: %v \n", stsObject.Namespace, stsObject.Name, stsObject.Spec.Template.Annotations)
GinkgoWriter.Printf("try to update StatefulSet %s/%s template from: %v, to new annotations: %v \n", stsObject.Namespace, stsObject.Name, stsObject.Spec.Template.Annotations, stsObject.Spec.Template.Annotations)
Expect(frame.UpdateResource(stsObject)).NotTo(HaveOccurred())

// Check that the container ID should be different
Expand Down

0 comments on commit 366ae3a

Please sign in to comment.