@@ -1770,6 +1770,9 @@ type kubeovnNet struct {
17701770 AllowLiveMigration bool
17711771 IPRequest string
17721772 MacRequest string
1773+ NadName string
1774+ NadNamespace string
1775+ InterfaceName string
17731776}
17741777
17751778func (c * Controller ) getPodAttachmentNet (pod * v1.Pod ) ([]* kubeovnNet , error ) {
@@ -1802,14 +1805,23 @@ func (c *Controller) getPodAttachmentNet(pod *v1.Pod) ([]*kubeovnNet, error) {
18021805 // ignore to return all existing subnets to clean its ip crd
18031806 ignoreSubnetNotExist := ! pod .DeletionTimestamp .IsZero ()
18041807
1808+ nadCounts := make (map [string ]int )
1809+ for _ , attach := range multusNets {
1810+ nadCounts [fmt .Sprintf ("%s/%s" , attach .Namespace , attach .Name )]++
1811+ }
1812+
18051813 result := make ([]* kubeovnNet , 0 , len (multusNets ))
18061814 for _ , attach := range multusNets {
1815+ nadKey := fmt .Sprintf ("%s/%s" , attach .Namespace , attach .Name )
18071816 network , err := c .netAttachLister .NetworkAttachmentDefinitions (attach .Namespace ).Get (attach .Name )
18081817 if err != nil {
18091818 klog .Errorf ("failed to get net-attach-def %s, %v" , attach .Name , err )
18101819 if k8serrors .IsNotFound (err ) && ignoreSubnetNotExist {
18111820 // NAD deleted before pod, find subnet for cleanup
18121821 providerName := fmt .Sprintf ("%s.%s.%s" , attach .Name , attach .Namespace , util .OvnProvider )
1822+ if nadCounts [nadKey ] > 1 && attach .InterfaceRequest != "" {
1823+ providerName = fmt .Sprintf ("%s.%s" , providerName , attach .InterfaceRequest )
1824+ }
18131825 subnetName := pod .Annotations [fmt .Sprintf (util .LogicalSwitchAnnotationTemplate , providerName )]
18141826 if subnetName == "" {
18151827 for _ , subnet := range subnets {
@@ -1837,10 +1849,13 @@ func (c *Controller) getPodAttachmentNet(pod *v1.Pod) ([]*kubeovnNet, error) {
18371849
18381850 klog .Infof ("pod %s/%s net-attach-def %s not found, using subnet %s for cleanup" , pod .Namespace , pod .Name , attach .Name , subnetName )
18391851 result = append (result , & kubeovnNet {
1840- Type : providerTypeIPAM ,
1841- ProviderName : providerName ,
1842- Subnet : subnet ,
1843- IsDefault : util .IsDefaultNet (pod .Annotations [util .DefaultNetworkAnnotation ], attach ),
1852+ Type : providerTypeIPAM ,
1853+ ProviderName : providerName ,
1854+ Subnet : subnet ,
1855+ IsDefault : util .IsDefaultNet (pod .Annotations [util .DefaultNetworkAnnotation ], attach ),
1856+ NadName : attach .Name ,
1857+ NadNamespace : attach .Namespace ,
1858+ InterfaceName : attach .InterfaceRequest ,
18441859 })
18451860 continue
18461861 }
@@ -1864,6 +1879,9 @@ func (c *Controller) getPodAttachmentNet(pod *v1.Pod) ([]*kubeovnNet, error) {
18641879 isDefault := util .IsDefaultNet (pod .Annotations [util .DefaultNetworkAnnotation ], attach )
18651880
18661881 providerName = fmt .Sprintf ("%s.%s.%s" , attach .Name , attach .Namespace , util .OvnProvider )
1882+ if nadCounts [nadKey ] > 1 && attach .InterfaceRequest != "" {
1883+ providerName = fmt .Sprintf ("%s.%s" , providerName , attach .InterfaceRequest )
1884+ }
18671885 if pod .Annotations [kubevirtv1 .MigrationJobNameAnnotation ] != "" {
18681886 allowLiveMigration = true
18691887 }
@@ -1917,18 +1935,24 @@ func (c *Controller) getPodAttachmentNet(pod *v1.Pod) ([]*kubeovnNet, error) {
19171935 AllowLiveMigration : allowLiveMigration ,
19181936 MacRequest : attach .MacRequest ,
19191937 IPRequest : strings .Join (attach .IPRequest , "," ),
1938+ NadName : attach .Name ,
1939+ NadNamespace : attach .Namespace ,
1940+ InterfaceName : attach .InterfaceRequest ,
19201941 }
19211942 result = append (result , ret )
19221943 } else {
19231944 providerName = fmt .Sprintf ("%s.%s" , attach .Name , attach .Namespace )
19241945 for _ , subnet := range subnets {
19251946 if subnet .Spec .Provider == providerName {
19261947 result = append (result , & kubeovnNet {
1927- Type : providerTypeIPAM ,
1928- ProviderName : providerName ,
1929- Subnet : subnet ,
1930- MacRequest : attach .MacRequest ,
1931- IPRequest : strings .Join (attach .IPRequest , "," ),
1948+ Type : providerTypeIPAM ,
1949+ ProviderName : providerName ,
1950+ Subnet : subnet ,
1951+ MacRequest : attach .MacRequest ,
1952+ IPRequest : strings .Join (attach .IPRequest , "," ),
1953+ NadName : attach .Name ,
1954+ NadNamespace : attach .Namespace ,
1955+ InterfaceName : attach .InterfaceRequest ,
19321956 })
19331957 break
19341958 }
@@ -1993,19 +2017,28 @@ func (c *Controller) acquireAddress(pod *v1.Pod, podNet *kubeovnNet) (string, st
19932017 }
19942018
19952019 var macPointer * string
1996- if isOvnSubnet (podNet .Subnet ) {
2020+ if podNet .NadName != "" && podNet .NadNamespace != "" && podNet .InterfaceName != "" {
2021+ key := perInterfaceMACAnnotationKey (podNet .NadName , podNet .NadNamespace , podNet .InterfaceName )
2022+ if macStr := pod .Annotations [key ]; macStr != "" {
2023+ if _ , err := net .ParseMAC (macStr ); err != nil {
2024+ return "" , "" , "" , podNet .Subnet , err
2025+ }
2026+ macPointer = & macStr
2027+ }
2028+ }
2029+
2030+ if macPointer == nil && isOvnSubnet (podNet .Subnet ) {
19972031 annoMAC := pod .Annotations [fmt .Sprintf (util .MacAddressAnnotationTemplate , podNet .ProviderName )]
19982032 if annoMAC != "" {
19992033 if _ , err := net .ParseMAC (annoMAC ); err != nil {
20002034 return "" , "" , "" , podNet .Subnet , err
20012035 }
20022036 macPointer = & annoMAC
20032037 }
2004- } else {
2038+ } else if macPointer == nil {
20052039 macPointer = ptr .To ("" )
20062040 }
20072041
2008- var err error
20092042 var nsNets []* kubeovnNet
20102043 ippoolStr := pod .Annotations [fmt .Sprintf (util .IPPoolAnnotationTemplate , podNet .ProviderName )]
20112044 subnetStr := pod .Annotations [fmt .Sprintf (util .LogicalSwitchAnnotationTemplate , podNet .ProviderName )]
@@ -2079,6 +2112,14 @@ func (c *Controller) acquireAddress(pod *v1.Pod, podNet *kubeovnNet) (string, st
20792112 // Random allocate
20802113 if pod .Annotations [fmt .Sprintf (util .IPAddressAnnotationTemplate , podNet .ProviderName )] == "" &&
20812114 ippoolStr == "" {
2115+ // check new IP annotation
2116+ if podNet .NadName != "" && podNet .NadNamespace != "" && podNet .InterfaceName != "" {
2117+ annoKey := perInterfaceIPAnnotationKey (podNet .NadName , podNet .NadNamespace , podNet .InterfaceName )
2118+ if ipStr := pod .Annotations [annoKey ]; ipStr != "" {
2119+ return c .acquireStaticAddressHelper (pod , podNet , portName , macPointer , ippoolStr , nsNets , isStsPod , key )
2120+ }
2121+ }
2122+
20822123 var skippedAddrs []string
20832124 for {
20842125 ipv4 , ipv6 , mac , err := c .ipam .GetRandomAddress (key , portName , macPointer , podNet .Subnet .Name , "" , skippedAddrs , ! podNet .AllowLiveMigration )
@@ -2104,6 +2145,13 @@ func (c *Controller) acquireAddress(pod *v1.Pod, podNet *kubeovnNet) (string, st
21042145 }
21052146 }
21062147
2148+ return c .acquireStaticAddressHelper (pod , podNet , portName , macPointer , ippoolStr , nsNets , isStsPod , key )
2149+ }
2150+
2151+ func (c * Controller ) acquireStaticAddressHelper (pod * v1.Pod , podNet * kubeovnNet , portName string , macPointer * string , ippoolStr string , nsNets []* kubeovnNet , isStsPod bool , key string ) (string , string , string , * kubeovnv1.Subnet , error ) {
2152+ var v4IP , v6IP , mac string
2153+ var err error
2154+
21072155 // The static ip can be assigned from any subnet after ns supports multi subnets
21082156 if nsNets == nil {
21092157 if nsNets , err = c .getNsAvailableSubnets (pod , podNet ); err != nil {
@@ -2112,9 +2160,20 @@ func (c *Controller) acquireAddress(pod *v1.Pod, podNet *kubeovnNet) (string, st
21122160 }
21132161 }
21142162
2115- var v4IP , v6IP , mac string
2116-
21172163 // Static allocate
2164+ if podNet .NadName != "" && podNet .NadNamespace != "" && podNet .InterfaceName != "" {
2165+ key := perInterfaceIPAnnotationKey (podNet .NadName , podNet .NadNamespace , podNet .InterfaceName )
2166+ if ipStr := pod .Annotations [key ]; ipStr != "" {
2167+ for _ , net := range nsNets {
2168+ v4IP , v6IP , mac , err = c .acquireStaticAddress (key , portName , ipStr , macPointer , net .Subnet .Name , net .AllowLiveMigration )
2169+ if err == nil {
2170+ return v4IP , v6IP , mac , net .Subnet , nil
2171+ }
2172+ }
2173+ return v4IP , v6IP , mac , podNet .Subnet , err
2174+ }
2175+ }
2176+
21182177 if ipStr := pod .Annotations [fmt .Sprintf (util .IPAddressAnnotationTemplate , podNet .ProviderName )]; ipStr != "" {
21192178 for _ , net := range nsNets {
21202179 v4IP , v6IP , mac , err = c .acquireStaticAddress (key , portName , ipStr , macPointer , net .Subnet .Name , net .AllowLiveMigration )
@@ -2602,3 +2661,11 @@ func (c *Controller) checkIsPodVpcNatGw(pod *v1.Pod) (bool, string) {
26022661 }
26032662 return isVpcNatGw , vpcGwName
26042663}
2664+
2665+ func perInterfaceIPAnnotationKey (nadName , nadNamespace , ifaceName string ) string {
2666+ return fmt .Sprintf ("%s.%s.kubernetes.io/ip_address.%s" , nadName , nadNamespace , ifaceName )
2667+ }
2668+
2669+ func perInterfaceMACAnnotationKey (nadName , nadNamespace , ifaceName string ) string {
2670+ return fmt .Sprintf ("%s.%s.kubernetes.io/mac_address.%s" , nadName , nadNamespace , ifaceName )
2671+ }
0 commit comments