@@ -12,10 +12,15 @@ import (
1212 "sync"
1313 "time"
1414
15+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+ "k8s.io/client-go/util/retry"
17+
1518 "github.com/AliyunContainerService/terway/deviceplugin"
1619 "github.com/AliyunContainerService/terway/pkg/aliyun"
1720 "github.com/AliyunContainerService/terway/pkg/aliyun/client"
1821 "github.com/AliyunContainerService/terway/pkg/aliyun/credential"
22+ "github.com/AliyunContainerService/terway/pkg/apis/alibabacloud.com/v1beta1"
23+ "github.com/AliyunContainerService/terway/pkg/apis/crds"
1924 podENITypes "github.com/AliyunContainerService/terway/pkg/apis/network.alibabacloud.com/v1beta1"
2025 "github.com/AliyunContainerService/terway/pkg/backoff"
2126 vswpool "github.com/AliyunContainerService/terway/pkg/controller/vswitch"
@@ -34,6 +39,7 @@ import (
3439 "github.com/pkg/errors"
3540 corev1 "k8s.io/api/core/v1"
3641 k8sErr "k8s.io/apimachinery/pkg/api/errors"
42+ k8stypes "k8s.io/apimachinery/pkg/types"
3743 "k8s.io/apimachinery/pkg/util/wait"
3844 "k8s.io/client-go/util/flowcontrol"
3945)
@@ -1099,6 +1105,108 @@ func (n *networkService) exclusiveENIFromCRD(podInfo *types.PodInfo, waitReady b
10991105 return netConf , nil
11001106}
11011107
1108+ func (n * networkService ) migrateEIP (ctx context.Context , objs []interface {}) error {
1109+ once := sync.Once {}
1110+
1111+ for _ , resObj := range objs {
1112+ podRes , ok := resObj .(types.PodResources )
1113+ if ! ok {
1114+ continue
1115+ }
1116+ if podRes .PodInfo == nil || ! podRes .PodInfo .EipInfo .PodEip {
1117+ continue
1118+ }
1119+ for _ , eipRes := range podRes .Resources {
1120+ if eipRes .Type != types .ResourceTypeEIP {
1121+ continue
1122+ }
1123+ allocType := v1beta1 .IPAllocTypeAuto
1124+ if podRes .PodInfo .EipInfo .PodEipID != "" {
1125+ allocType = v1beta1 .IPAllocTypeStatic
1126+ }
1127+ releaseStrategy := v1beta1 .ReleaseStrategyFollow
1128+ releaseAfter := ""
1129+
1130+ if podRes .PodInfo .IPStickTime > 0 {
1131+ releaseStrategy = v1beta1 .ReleaseStrategyTTL
1132+ releaseAfter = podRes .PodInfo .IPStickTime .String ()
1133+ }
1134+
1135+ var err error
1136+ once .Do (func () {
1137+ err = crds .RegisterCRD ([]string {crds .CRDPodEIP })
1138+ })
1139+ if err != nil {
1140+ return err
1141+ }
1142+
1143+ ctx , cancel := context .WithTimeout (ctx , 60 * time .Second )
1144+
1145+ l := serviceLog .WithField ("name" , fmt .Sprintf ("%s/%s" , podRes .PodInfo .Namespace , podRes .PodInfo .Name ))
1146+
1147+ c := n .k8s .GetClient ()
1148+ podEIP := & v1beta1.PodEIP {}
1149+ err = c .Get (ctx , k8stypes.NamespacedName {Namespace : podRes .PodInfo .Namespace , Name : podRes .PodInfo .Name }, podEIP )
1150+ if err == nil {
1151+ cancel ()
1152+ l .Info ("skip create podEIP, already exist" )
1153+ continue
1154+ }
1155+ if ! k8sErr .IsNotFound (err ) {
1156+ cancel ()
1157+ return err
1158+ }
1159+
1160+ err = retry .OnError (wait.Backoff {
1161+ Steps : 4 ,
1162+ Duration : 200 * time .Millisecond ,
1163+ Factor : 5.0 ,
1164+ Jitter : 0.1 ,
1165+ }, func (err error ) bool {
1166+ if k8sErr .IsTooManyRequests (err ) {
1167+ return true
1168+ }
1169+ if k8sErr .IsInternalError (err ) {
1170+ return true
1171+ }
1172+ return false
1173+ }, func () error {
1174+ podEIP = & v1beta1.PodEIP {
1175+ ObjectMeta : metav1.ObjectMeta {
1176+ Name : podRes .PodInfo .Name ,
1177+ Namespace : podRes .PodInfo .Namespace ,
1178+ Annotations : map [string ]string {},
1179+ Finalizers : []string {"podeip-controller.alibabacloud.com/finalizer" },
1180+ },
1181+ Spec : v1beta1.PodEIPSpec {
1182+ AllocationID : eipRes .ID ,
1183+ BandwidthPackageID : podRes .PodInfo .EipInfo .PodEipBandwidthPackageID ,
1184+ AllocationType : v1beta1.AllocationType {
1185+ Type : allocType ,
1186+ ReleaseStrategy : releaseStrategy ,
1187+ ReleaseAfter : releaseAfter ,
1188+ },
1189+ },
1190+ }
1191+
1192+ l .Infof ("create podEIP for %v" , podRes )
1193+
1194+ err := c .Create (ctx , podEIP )
1195+ if k8sErr .IsAlreadyExists (err ) {
1196+ return nil
1197+ }
1198+ return err
1199+ })
1200+ cancel ()
1201+
1202+ if err != nil {
1203+ return err
1204+ }
1205+ }
1206+ }
1207+ return nil
1208+ }
1209+
11021210// tracing
11031211func (n * networkService ) Config () []tracing.MapKeyValueEntry {
11041212 // name, daemon_mode, configFilePath, kubeconfig, master
@@ -1344,6 +1452,10 @@ func newNetworkService(ctx context.Context, configFilePath, daemonMode string) (
13441452 }
13451453 }
13461454
1455+ if limit .TrunkPod () <= 0 {
1456+ config .EnableENITrunking = false
1457+ }
1458+
13471459 ecs := aliyun .NewAliyunImpl (aliyunClient , config .EnableENITrunking && ! config .WaitTrunkENI , ipFamily , config .ENITagFilter )
13481460
13491461 netSrv .resourceDB , err = storage .NewDiskStorage (
@@ -1476,6 +1588,14 @@ func newNetworkService(ctx context.Context, configFilePath, daemonMode string) (
14761588 }
14771589 }
14781590
1591+ if config .EnableEIPMigrate {
1592+ err = netSrv .migrateEIP (ctx , resObjList )
1593+ if err != nil {
1594+ return nil , err
1595+ }
1596+ serviceLog .Infof ("eip migrate finished" )
1597+ }
1598+
14791599 resStr , err := json .Marshal (localResource )
14801600 if err != nil {
14811601 return nil , err
@@ -1511,25 +1631,26 @@ func newNetworkService(ctx context.Context, configFilePath, daemonMode string) (
15111631 if err != nil {
15121632 return nil , errors .Wrapf (err , "error init ENI ip resource manager" )
15131633 }
1514- if config .EnableEIPPool == conditionTrue {
1515- netSrv .eipResMgr = newEipResourceManager (ecs , netSrv .k8s , config .AllowEIPRob == conditionTrue )
1516- }
15171634 netSrv .mgrForResource = map [string ]ResourceManager {
15181635 types .ResourceTypeENIIP : netSrv .eniIPResMgr ,
1519- types .ResourceTypeEIP : netSrv .eipResMgr ,
15201636 }
1637+ if config .EnableEIPPool == conditionTrue && ! config .EnableEIPMigrate {
1638+ netSrv .eipResMgr = newEipResourceManager (ecs , netSrv .k8s , config .AllowEIPRob == conditionTrue )
1639+ netSrv .mgrForResource [types .ResourceTypeEIP ] = netSrv .eipResMgr
1640+ }
1641+
15211642 case daemonModeENIOnly :
15221643 //init eni
15231644 netSrv .eniResMgr , err = newENIResourceManager (poolConfig , ecs , localResource [types .ResourceTypeENI ], ipFamily , netSrv .k8s , netSrv .ipamType )
15241645 if err != nil {
15251646 return nil , errors .Wrapf (err , "error init eni resource manager" )
15261647 }
1527- if config .EnableEIPPool == conditionTrue && ! config .EnableENITrunking {
1528- netSrv .eipResMgr = newEipResourceManager (ecs , netSrv .k8s , config .AllowEIPRob == conditionTrue )
1529- }
15301648 netSrv .mgrForResource = map [string ]ResourceManager {
1531- types .ResourceTypeENI : netSrv .eniResMgr ,
1532- types .ResourceTypeEIP : netSrv .eipResMgr ,
1649+ types .ResourceTypeENIIP : netSrv .eniIPResMgr ,
1650+ }
1651+ if config .EnableEIPPool == conditionTrue && ! config .EnableENITrunking && ! config .EnableEIPMigrate {
1652+ netSrv .eipResMgr = newEipResourceManager (ecs , netSrv .k8s , config .AllowEIPRob == conditionTrue )
1653+ netSrv .mgrForResource [types .ResourceTypeEIP ] = netSrv .eipResMgr
15331654 }
15341655 default :
15351656 panic ("unsupported daemon mode" + daemonMode )
0 commit comments