Skip to content

Commit

Permalink
support vip dual stack (#3617)
Browse files Browse the repository at this point in the history
Signed-off-by: zcq98 <zhaocongqi_yewu@cmss.chinamobile.com>
Co-authored-by: zcq98 <zhaocongqi_yewu@cmss.chinamobile.com>
  • Loading branch information
zcq98 and zcq98 authored Jan 15, 2024
1 parent 8707ff7 commit 45b0071
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 35 deletions.
83 changes: 54 additions & 29 deletions pkg/controller/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -2013,42 +2013,67 @@ func getPodType(pod *v1.Pod) string {
}

func (c *Controller) getVirtualIPs(pod *v1.Pod, podNets []*kubeovnNet) map[string]string {
vipsMap := make(map[string]string)
if aaps := pod.Annotations[util.AAPsAnnotation]; aaps != "" {
for _, vipName := range strings.Split(aaps, ",") {
vip, err := c.virtualIpsLister.Get(vipName)
if err != nil {
klog.Errorf("failed to get vip %s, %v", vipName, err)
continue
}
if vip.Spec.Namespace != pod.Namespace || vip.Status.V4ip == "" {
continue
}
subnet, err := c.subnetsLister.Get(vip.Spec.Subnet)
if err != nil {
klog.Errorf("failed to get subnet %s, %v", vip.Spec.Subnet, err)
continue
}
key := fmt.Sprintf("%s.%s", subnet.Name, subnet.Spec.Provider)
if vips, exists := vipsMap[key]; exists {
vipsMap[key] = strings.Join([]string{vips, vip.Status.V4ip}, ",")
} else {
vipsMap[key] = vip.Status.V4ip
}
vipsListMap := make(map[string][]string)
var vipNamesList []string
for _, vipName := range strings.Split(strings.TrimSpace(pod.Annotations[util.AAPsAnnotation]), ",") {
if !util.ContainsString(vipNamesList, vipName) {
vipNamesList = append(vipNamesList, vipName)
}
}
for _, vipName := range vipNamesList {
vip, err := c.virtualIpsLister.Get(vipName)
if err != nil {
klog.Errorf("failed to get vip %s, %v", vipName, err)
continue
}
if vip.Spec.Namespace != pod.Namespace || (vip.Status.V4ip == "" && vip.Status.V6ip == "") {
continue
}
subnet, err := c.subnetsLister.Get(vip.Spec.Subnet)
if err != nil {
klog.Errorf("failed to get subnet %s, %v", vip.Spec.Subnet, err)
continue
}
key := fmt.Sprintf("%s.%s", subnet.Name, subnet.Spec.Provider)
vipsList := vipsListMap[key]
if vipsList == nil {
vipsList = []string{}
}

// ipam will ensure the uniqueness of VIP
if util.IsValidIP(vip.Status.V4ip) {
vipsList = append(vipsList, vip.Status.V4ip)
}
if util.IsValidIP(vip.Status.V6ip) {
vipsList = append(vipsList, vip.Status.V6ip)
}

vipsListMap[key] = vipsList
}

for _, podNet := range podNets {
key := fmt.Sprintf("%s.%s", podNet.Subnet.Name, podNet.ProviderName)
vip := pod.Annotations[fmt.Sprintf(util.PortVipAnnotationTemplate, podNet.ProviderName)]
if vip == "" {
vipStr := pod.Annotations[fmt.Sprintf(util.PortVipAnnotationTemplate, podNet.ProviderName)]
if vipStr == "" {
continue
}
if vips, exists := vipsMap[key]; exists {
vipsMap[key] = strings.Join([]string{vips, vip}, ",")
} else {
vipsMap[key] = vip
key := fmt.Sprintf("%s.%s", podNet.Subnet.Name, podNet.ProviderName)
vipsList := vipsListMap[key]
if vipsList == nil {
vipsList = []string{}
}

for _, vip := range strings.Split(vipStr, ",") {
if util.IsValidIP(vip) && !util.ContainsString(vipsList, vip) {
vipsList = append(vipsList, vip)
}
}

vipsListMap[key] = vipsList
}

vipsMap := make(map[string]string)
for key, vipsList := range vipsListMap {
vipsMap[key] = strings.Join(vipsList, ",")
}
return vipsMap
}
17 changes: 11 additions & 6 deletions pkg/controller/vip.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ func (c *Controller) enqueueUpdateVirtualIP(oldObj, newObj interface{}) {
oldVip.Spec.MacAddress != newVip.Spec.MacAddress ||
oldVip.Spec.ParentMac != newVip.Spec.ParentMac ||
oldVip.Spec.ParentV4ip != newVip.Spec.ParentV4ip ||
oldVip.Spec.V4ip != newVip.Spec.V4ip {
oldVip.Spec.V4ip != newVip.Spec.V4ip ||
oldVip.Spec.V6ip != newVip.Spec.V6ip {
klog.Infof("enqueue update vip %s", key)
c.updateVirtualIPQueue.Add(key)
}
Expand Down Expand Up @@ -216,7 +217,7 @@ func (c *Controller) handleAddVirtualIP(key string) error {
}
klog.V(3).Infof("handle add vip %s", key)
vip := cachedVip.DeepCopy()
var sourceV4Ip, v4ip, v6ip, mac, subnetName string
var sourceV4Ip, sourceV6Ip, v4ip, v6ip, mac, subnetName string
subnetName = vip.Spec.Subnet
if subnetName == "" {
return fmt.Errorf("failed to create vip '%s', subnet should be set", key)
Expand All @@ -228,12 +229,15 @@ func (c *Controller) handleAddVirtualIP(key string) error {
}
portName := ovs.PodNameToPortName(vip.Name, vip.Spec.Namespace, subnet.Spec.Provider)
sourceV4Ip = vip.Spec.V4ip
if sourceV4Ip != "" {
v4ip, v6ip, mac, err = c.acquireStaticIPAddress(subnet.Name, vip.Name, portName, sourceV4Ip)
sourceV6Ip = vip.Spec.V6ip
ipStr := util.GetStringIP(sourceV4Ip, sourceV6Ip)
if ipStr != "" {
v4ip, v6ip, mac, err = c.acquireStaticIPAddress(subnet.Name, vip.Name, portName, ipStr)
} else {
// Random allocate
v4ip, v6ip, mac, err = c.acquireIPAddress(subnet.Name, vip.Name, portName)
}

if err != nil {
klog.Error(err)
return err
Expand Down Expand Up @@ -420,11 +424,12 @@ func (c *Controller) handleUpdateVirtualParents(key string) error {
return err
}
// only pods in the same namespace as vip are allowed to use aap
if cachedVip.Status.V4ip == "" || cachedVip.Spec.Namespace == "" {
if (cachedVip.Status.V4ip == "" && cachedVip.Status.V6ip == "") || cachedVip.Spec.Namespace == "" {
return nil
}
// add new virtual port if not exist
if err = c.OVNNbClient.CreateVirtualLogicalSwitchPort(cachedVip.Name, cachedVip.Spec.Subnet, cachedVip.Status.V4ip); err != nil {
ipStr := util.GetStringIP(cachedVip.Status.V4ip, cachedVip.Status.V6ip)
if err = c.OVNNbClient.CreateVirtualLogicalSwitchPort(cachedVip.Name, cachedVip.Spec.Subnet, ipStr); err != nil {
klog.Errorf("create virtual port with vip %s from logical switch %s: %v", cachedVip.Name, cachedVip.Spec.Subnet, err)
return err
}
Expand Down

0 comments on commit 45b0071

Please sign in to comment.