mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-11 12:52:23 +00:00
rate-limiter: implement hypervisor-built-in rate limiter
As for hypervisors that support built-in rate limiter, like firecracker, we use this built-in characteristics to implement rate limiter in kata. kata-defined rate is in bits with scaling factors of 1000, otherwise fc-defined rate is in bytes with scaling factors of 1024, so need reversion. Fixes: #250 Signed-off-by: Penny Zheng <penny.zheng@arm.com>
This commit is contained in:
parent
676ad989d7
commit
cfeb966763
@ -908,11 +908,52 @@ func (fc *firecracker) fcAddNetDevice(endpoint Endpoint) {
|
||||
defer span.Finish()
|
||||
|
||||
ifaceID := endpoint.Name()
|
||||
|
||||
// The implementation of rate limiter is based on TBF.
|
||||
// Rate Limiter defines a token bucket with a maximum capacity (size) to store tokens, and an interval for refilling purposes (refill_time).
|
||||
// The refill-rate is derived from size and refill_time, and it is the constant rate at which the tokens replenish.
|
||||
refillTime := uint64(1000)
|
||||
var rxRateLimiter models.RateLimiter
|
||||
rxSize := fc.config.RxRateLimiterMaxRate
|
||||
if rxSize > 0 {
|
||||
fc.Logger().Info("Add rx rate limiter")
|
||||
|
||||
// kata-defined rxSize is in bits with scaling factors of 1000, but firecracker-defined
|
||||
// rxSize is in bytes with scaling factors of 1024, need reversion.
|
||||
rxSize = revertBytes(rxSize / 8)
|
||||
rxTokenBucket := models.TokenBucket{
|
||||
RefillTime: &refillTime,
|
||||
Size: &rxSize,
|
||||
}
|
||||
rxRateLimiter = models.RateLimiter{
|
||||
Bandwidth: &rxTokenBucket,
|
||||
}
|
||||
}
|
||||
|
||||
var txRateLimiter models.RateLimiter
|
||||
txSize := fc.config.TxRateLimiterMaxRate
|
||||
if txSize > 0 {
|
||||
fc.Logger().Info("Add tx rate limiter")
|
||||
|
||||
// kata-defined txSize is in bits with scaling factors of 1000, but firecracker-defined
|
||||
// txSize is in bytes with scaling factors of 1024, need reversion.
|
||||
txSize = revertBytes(txSize / 8)
|
||||
txTokenBucket := models.TokenBucket{
|
||||
RefillTime: &refillTime,
|
||||
Size: &txSize,
|
||||
}
|
||||
txRateLimiter = models.RateLimiter{
|
||||
Bandwidth: &txTokenBucket,
|
||||
}
|
||||
}
|
||||
|
||||
ifaceCfg := &models.NetworkInterface{
|
||||
AllowMmdsRequests: false,
|
||||
GuestMac: endpoint.HardwareAddr(),
|
||||
IfaceID: &ifaceID,
|
||||
HostDevName: &endpoint.NetworkPair().TapInterface.TAPIface.Name,
|
||||
RxRateLimiter: &rxRateLimiter,
|
||||
TxRateLimiter: &txRateLimiter,
|
||||
}
|
||||
|
||||
fc.fcConfig.NetworkInterfaces = append(fc.fcConfig.NetworkInterfaces, ifaceCfg)
|
||||
@ -1216,3 +1257,16 @@ func (fc *firecracker) watchConsole() (*os.File, error) {
|
||||
func (fc *firecracker) isRateLimiterBuiltin() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// In firecracker, it accepts the size of rate limiter in scaling factors of 2^10(1024)
|
||||
// But in kata-defined rate limiter, for better Human-readability, we prefer scaling factors of 10^3(1000).
|
||||
// func revertByte reverts num from scaling factors of 1000 to 1024, e.g. 10000000(10MB) to 10485760.
|
||||
func revertBytes(num uint64) uint64 {
|
||||
a := num / 1000
|
||||
b := num % 1000
|
||||
if a == 0 {
|
||||
return num
|
||||
} else {
|
||||
return 1024*revertBytes(a) + b
|
||||
}
|
||||
}
|
||||
|
@ -45,3 +45,14 @@ func TestFCTruncateID(t *testing.T) {
|
||||
id = fc.truncateID(testShortID)
|
||||
assert.Equal(expectedID, id)
|
||||
}
|
||||
|
||||
func TestRevertBytes(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
//10MB
|
||||
testNum := uint64(10000000)
|
||||
expectedNum := uint64(10485760)
|
||||
|
||||
num := revertBytes(testNum)
|
||||
assert.Equal(expectedNum, num)
|
||||
}
|
||||
|
@ -19,17 +19,17 @@ type TokenBucket struct {
|
||||
|
||||
// The initial size of a token bucket.
|
||||
// Minimum: 0
|
||||
OneTimeBurst *int64 `json:"one_time_burst,omitempty"`
|
||||
OneTimeBurst *uint64 `json:"one_time_burst,omitempty"`
|
||||
|
||||
// The amount of milliseconds it takes for the bucket to refill.
|
||||
// Required: true
|
||||
// Minimum: 0
|
||||
RefillTime *int64 `json:"refill_time"`
|
||||
RefillTime *uint64 `json:"refill_time"`
|
||||
|
||||
// The total number of tokens this bucket can hold.
|
||||
// Required: true
|
||||
// Minimum: 0
|
||||
Size *int64 `json:"size"`
|
||||
Size *uint64 `json:"size"`
|
||||
}
|
||||
|
||||
// Validate validates this token bucket
|
||||
|
@ -615,17 +615,17 @@ definitions:
|
||||
properties:
|
||||
size:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of tokens this bucket can hold.
|
||||
minimum: 0
|
||||
one_time_burst:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The initial size of a token bucket.
|
||||
minimum: 0
|
||||
refill_time:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The amount of milliseconds it takes for the bucket to refill.
|
||||
minimum: 0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user