@@ -12,6 +12,10 @@ import (
1212 nnc "github.com/Azure/azure-container-networking/nodenetworkconfig/api/v1alpha"
1313)
1414
15+ const (
16+ defaultMaxIPCount = int64 (250 )
17+ )
18+
1519type CNSIPAMPoolMonitor struct {
1620 pendingRelease bool
1721
@@ -71,12 +75,21 @@ func (pm *CNSIPAMPoolMonitor) Reconcile() error {
7175 pendingReleaseIPCount := len (pm .httpService .GetPendingReleaseIPConfigs ())
7276 availableIPConfigCount := len (pm .httpService .GetAvailableIPConfigs ()) // TODO: add pending allocation count to real cns
7377 freeIPConfigCount := pm .cachedNNC .Spec .RequestedIPCount - int64 (allocatedPodIPCount )
74- msg := fmt .Sprintf ("[ipam-pool-monitor] Pool Size: %v, Goal Size: %v, BatchSize: %v, MinFree: %v, MaxFree:%v, Allocated: %v, Available: %v, Pending Release: %v, Free: %v, Pending Program: %v" ,
75- cnsPodIPConfigCount , pm .cachedNNC .Spec .RequestedIPCount , pm .scalarUnits .BatchSize , pm .MinimumFreeIps , pm .MaximumFreeIps , allocatedPodIPCount , availableIPConfigCount , pendingReleaseIPCount , freeIPConfigCount , pendingProgramCount )
78+ batchSize := pm .getBatchSize () //Use getters in case customer changes batchsize manually
79+ maxIPCount := pm .getMaxIPCount ()
80+
81+
82+ msg := fmt .Sprintf ("[ipam-pool-monitor] Pool Size: %v, Goal Size: %v, BatchSize: %v, MaxIPCount: %v, MinFree: %v, MaxFree:%v, Allocated: %v, Available: %v, Pending Release: %v, Free: %v, Pending Program: %v" ,
83+ cnsPodIPConfigCount , pm .cachedNNC .Spec .RequestedIPCount , batchSize , maxIPCount , pm .MinimumFreeIps , pm .MaximumFreeIps , allocatedPodIPCount , availableIPConfigCount , pendingReleaseIPCount , freeIPConfigCount , pendingProgramCount )
7684
7785 switch {
7886 // pod count is increasing
7987 case freeIPConfigCount < pm .MinimumFreeIps :
88+ if pm .cachedNNC .Spec .RequestedIPCount == maxIPCount {
89+ // If we're already at the maxIPCount, don't try to increase
90+ return nil
91+ }
92+
8093 logger .Printf ("[ipam-pool-monitor] Increasing pool size...%s " , msg )
8194 return pm .increasePoolSize ()
8295
@@ -111,7 +124,24 @@ func (pm *CNSIPAMPoolMonitor) increasePoolSize() error {
111124 return err
112125 }
113126
114- tempNNCSpec .RequestedIPCount += pm .scalarUnits .BatchSize
127+ // Query the max IP count
128+ maxIPCount := pm .getMaxIPCount ()
129+ previouslyRequestedIPCount := tempNNCSpec .RequestedIPCount
130+ batchSize := pm .getBatchSize ()
131+
132+ tempNNCSpec .RequestedIPCount += batchSize
133+ if tempNNCSpec .RequestedIPCount > maxIPCount {
134+ // We don't want to ask for more ips than the max
135+ logger .Printf ("[ipam-pool-monitor] Requested IP count (%v) is over max limit (%v), requesting max limit instead." , tempNNCSpec .RequestedIPCount , maxIPCount )
136+ tempNNCSpec .RequestedIPCount = maxIPCount
137+ }
138+
139+ // If the requested IP count is same as before, then don't do anything
140+ if tempNNCSpec .RequestedIPCount == previouslyRequestedIPCount {
141+ logger .Printf ("[ipam-pool-monitor] Previously requested IP count %v is same as updated IP count %v, doing nothing" , previouslyRequestedIPCount , tempNNCSpec .RequestedIPCount )
142+ return nil
143+ }
144+
115145 logger .Printf ("[ipam-pool-monitor] Increasing pool size, Current Pool Size: %v, Updated Requested IP Count: %v, Pods with IP's:%v, ToBeDeleted Count: %v" , len (pm .httpService .GetPodIPConfigState ()), tempNNCSpec .RequestedIPCount , len (pm .httpService .GetAllocatedIPConfigs ()), len (tempNNCSpec .IPsNotInUse ))
116146
117147 err = pm .rc .UpdateCRDSpec (context .Background (), tempNNCSpec )
@@ -134,10 +164,35 @@ func (pm *CNSIPAMPoolMonitor) decreasePoolSize(existingPendingReleaseIPCount int
134164 var err error
135165 var newIpsMarkedAsPending bool
136166 var pendingIpAddresses map [string ]cns.IPConfigurationStatus
167+ var updatedRequestedIPCount int64
168+ var decreaseIPCountBy int64
169+
170+ // Ensure the updated requested IP count is a multiple of the batch size
171+ previouslyRequestedIPCount := pm .cachedNNC .Spec .RequestedIPCount
172+ batchSize := pm .getBatchSize ()
173+ modResult := previouslyRequestedIPCount % batchSize
174+
175+ logger .Printf ("[ipam-pool-monitor] Previously RequestedIP Count %v" , previouslyRequestedIPCount )
176+ logger .Printf ("[ipam-pool-monitor] Batch size : %v" , batchSize )
177+ logger .Printf ("[ipam-pool-monitor] modResult of (previously requested IP count mod batch size) = %v" , modResult )
178+
179+ if modResult != 0 {
180+ // Example: previouscount = 25, batchsize = 10, 25 - 10 = 15, NOT a multiple of batchsize (10)
181+ // Don't want that, so make requestedIPCount 20 (25 - (25 % 10)) so that it is a multiple of the batchsize (10)
182+ updatedRequestedIPCount = previouslyRequestedIPCount - modResult
183+ } else {
184+ // Example: previouscount = 30, batchsize = 10, 30 - 10 = 20 which is multiple of batchsize (10) so all good
185+ updatedRequestedIPCount = previouslyRequestedIPCount - batchSize
186+ }
187+
188+ decreaseIPCountBy = previouslyRequestedIPCount - updatedRequestedIPCount
189+
190+ logger .Printf ("[ipam-pool-monitor] updatedRequestedIPCount %v" , updatedRequestedIPCount )
191+
137192 if pm .updatingIpsNotInUseCount == 0 ||
138193 pm .updatingIpsNotInUseCount < existingPendingReleaseIPCount {
139- logger .Printf ("[ipam-pool-monitor] Marking IPs as PendingRelease, ipsToBeReleasedCount %d" , int (pm . scalarUnits . BatchSize ))
140- pendingIpAddresses , err = pm .httpService .MarkIPAsPendingRelease (int (pm . scalarUnits . BatchSize ))
194+ logger .Printf ("[ipam-pool-monitor] Marking IPs as PendingRelease, ipsToBeReleasedCount %d" , int (decreaseIPCountBy ))
195+ pendingIpAddresses , err = pm .httpService .MarkIPAsPendingRelease (int (decreaseIPCountBy ))
141196 if err != nil {
142197 return err
143198 }
@@ -237,8 +292,8 @@ func (pm *CNSIPAMPoolMonitor) Update(scalar nnc.Scaler, spec nnc.NodeNetworkConf
237292
238293 pm .scalarUnits = scalar
239294
240- pm .MinimumFreeIps = int64 (float64 (pm .scalarUnits . BatchSize ) * (float64 (pm .scalarUnits .RequestThresholdPercent ) / 100 ))
241- pm .MaximumFreeIps = int64 (float64 (pm .scalarUnits . BatchSize ) * (float64 (pm .scalarUnits .ReleaseThresholdPercent ) / 100 ))
295+ pm .MinimumFreeIps = int64 (float64 (pm .getBatchSize () ) * (float64 (pm .scalarUnits .RequestThresholdPercent ) / 100 ))
296+ pm .MaximumFreeIps = int64 (float64 (pm .getBatchSize () ) * (float64 (pm .scalarUnits .ReleaseThresholdPercent ) / 100 ))
242297
243298 pm .cachedNNC .Spec = spec
244299
@@ -248,6 +303,21 @@ func (pm *CNSIPAMPoolMonitor) Update(scalar nnc.Scaler, spec nnc.NodeNetworkConf
248303 return nil
249304}
250305
306+ func (pm * CNSIPAMPoolMonitor ) getMaxIPCount () int64 {
307+ if pm .scalarUnits .MaxIPCount == 0 {
308+ pm .scalarUnits .MaxIPCount = defaultMaxIPCount
309+ }
310+ return pm .scalarUnits .MaxIPCount
311+ }
312+
313+ func (pm * CNSIPAMPoolMonitor ) getBatchSize () int64 {
314+ maxIPCount := pm .getMaxIPCount ()
315+ if pm .scalarUnits .BatchSize > maxIPCount {
316+ pm .scalarUnits .BatchSize = maxIPCount
317+ }
318+ return pm .scalarUnits .BatchSize
319+ }
320+
251321//this function sets the values for state in IPAMPoolMonitor Struct
252322func (pm * CNSIPAMPoolMonitor ) GetStateSnapshot () cns.IpamPoolMonitorStateSnapshot {
253323 pm .mu .Lock ()
0 commit comments