Skip to content

Commit

Permalink
feat(pool): checking ip status before conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
fioncat committed Jun 13, 2024
1 parent a3c5c35 commit bc97d9b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 14 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ vip-controller:
$(DOCKER_CMD) push $(VIP_CONTROLLER_IMAGE)
@echo "Build done: $(VIP_CONTROLLER_IMAGE)"

.PHONY: release-ip
release-ip:
CGO_ENABLED=0 GOOS="linux" GOARCH="amd64" go build -o ./bin/release-ip ./cmd/release-ip

.PHONY: fmt
fmt:
@command -v goimports >/dev/null || { echo "ERROR: goimports not installed"; exit 1; }
Expand Down
52 changes: 52 additions & 0 deletions cmd/release-ip/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"fmt"
"os"

"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/uk8s-cni-vpc/pkg/iputils"
"github.com/ucloud/uk8s-cni-vpc/pkg/uapi"
)

func releaseIp(ip string) error {
macAddr, err := iputils.GetNodeMacAddress("")
if err != nil {
return fmt.Errorf("failed to get mac addr: %w", err)
}

uapiClient, err := uapi.NewClient()
if err != nil {
return fmt.Errorf("failed to init uapi client: %w", err)
}

vpcClient, err := uapiClient.VPCClient()
if err != nil {
return fmt.Errorf("failed to init vpc client: %w", err)
}

req := vpcClient.NewDeleteSecondaryIpRequest()
req.VPCId = ucloud.String(uapiClient.VPCID())
req.SubnetId = ucloud.String(uapiClient.SubnetID())
req.Ip = ucloud.String(ip)
req.Mac = ucloud.String(macAddr)

_, err = vpcClient.DeleteSecondaryIp(req)
return err
}

func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: release-ip <ip>")
os.Exit(1)
}

ip := os.Args[1]
err := releaseIp(ip)
if err != nil {
fmt.Printf("failed to release ip %v: %v\n", ip, err)
os.Exit(1)
}

fmt.Printf("released ip %v successfully\n", ip)
}
28 changes: 14 additions & 14 deletions pkg/ipamd/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,6 @@ func (s *ipamServer) getPodIp(r *rpc.AddPodNetworkRequest) (*rpc.PodNetwork, err
if err != nil {
return nil, err
}
if !pn.Recycled && pn.VPCIP != "" {
// We need to detect IP conflict before using it.
// See: https://www.rfc-editor.org/rfc/rfc5227
err = s.checkIPConflict(pn.VPCIP)
if err != nil {
ulog.Errorf("Detect ip conflict for %s error: %v, we will release it", pn.VPCIP, err)
delErr := s.uapiDeleteSecondaryIp(pn.VPCIP)
if delErr != nil {
ulog.Errorf("Release ip %s after conflict error: %v", pn.VPCIP, delErr)
}
return nil, err
}
}

ulog.Infof("Check IP %s status in VPC", pn.VPCIP)
// In some cases, the IP is deleted in VPC but still remain in the pool. If we give it to
Expand All @@ -158,11 +145,24 @@ func (s *ipamServer) getPodIp(r *rpc.AddPodNetworkRequest) (*rpc.PodNetwork, err
if err != nil {
return nil, fmt.Errorf("check ip %v status in vpc error: %v", pn.VPCIP, err)
}

if !ok {
return nil, fmt.Errorf("ip %v does not exist on current node, we will try to use another one", pn.VPCIP)
}

if !pn.Recycled && pn.VPCIP != "" {
// We need to detect IP conflict before using it.
// See: https://www.rfc-editor.org/rfc/rfc5227
err = s.checkIPConflict(pn.VPCIP)
if err != nil {
ulog.Errorf("Detect ip conflict for %s error: %v, we will release it", pn.VPCIP, err)
delErr := s.uapiDeleteSecondaryIp(pn.VPCIP)
if delErr != nil {
ulog.Errorf("Release ip %s after conflict error: %v", pn.VPCIP, delErr)
}
return nil, err
}
}

return pn, nil
}

Expand Down

0 comments on commit bc97d9b

Please sign in to comment.