mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
Merge pull request #8207 from xordspar0/common-period-quota
Centralize cores and period/quota conversion code
This commit is contained in:
@ -25,11 +25,8 @@ func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU {
|
||||
cpu := &specs.LinuxCPU{}
|
||||
hasLimits := false
|
||||
|
||||
const cpuPeriod = 100000
|
||||
|
||||
if c.CPUS > 0 {
|
||||
quota := int64(c.CPUS * cpuPeriod)
|
||||
period := uint64(cpuPeriod)
|
||||
period, quota := util.CoresToPeriodAndQuota(c.CPUS)
|
||||
|
||||
cpu.Period = &period
|
||||
cpu.Quota = "a
|
||||
|
@ -327,7 +327,7 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) {
|
||||
period := *c.config.Spec.Linux.Resources.CPU.Period
|
||||
|
||||
if quota > 0 && period > 0 {
|
||||
cpuLimitMilli := int64(1000 * float64(quota) / float64(period))
|
||||
cpuLimitMilli := int64(1000 * util.PeriodAndQuotaToCores(period, quota))
|
||||
|
||||
// Kubernetes: precision finer than 1m is not allowed
|
||||
if cpuLimitMilli >= 1 {
|
||||
|
@ -36,8 +36,6 @@ const (
|
||||
kubeDirectoryPermission = 0755
|
||||
// https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
|
||||
kubeFilePermission = 0644
|
||||
// Kubernetes sets CPUPeriod to 100000us (100ms): https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
|
||||
defaultCPUPeriod = 100000
|
||||
)
|
||||
|
||||
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
|
||||
@ -515,10 +513,9 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
|
||||
return nil, errors.Wrap(err, "Failed to set CPU quota")
|
||||
}
|
||||
if milliCPU > 0 {
|
||||
containerConfig.Resources.CPUPeriod = defaultCPUPeriod
|
||||
// CPU quota is a fraction of the period: milliCPU / 1000.0 * period
|
||||
// Or, without floating point math:
|
||||
containerConfig.Resources.CPUQuota = milliCPU * defaultCPUPeriod / 1000
|
||||
period, quota := util.CoresToPeriodAndQuota(float64(milliCPU) / 1000)
|
||||
containerConfig.Resources.CPUPeriod = period
|
||||
containerConfig.Resources.CPUQuota = quota
|
||||
}
|
||||
|
||||
containerConfig.Resources.Memory, err = quantityToInt64(containerYAML.Resources.Limits.Memory())
|
||||
|
@ -653,3 +653,26 @@ func CreateCidFile(cidfile string, id string) error {
|
||||
cidFile.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultCPUPeriod is the default CPU period is 100us, which is the same default
|
||||
// as Kubernetes.
|
||||
const DefaultCPUPeriod uint64 = 100000
|
||||
|
||||
// CoresToPeriodAndQuota converts a fraction of cores to the equivalent
|
||||
// Completely Fair Scheduler (CFS) parameters period and quota.
|
||||
//
|
||||
// Cores is a fraction of the CFS period that a container may use. Period and
|
||||
// Quota are in microseconds.
|
||||
func CoresToPeriodAndQuota(cores float64) (uint64, int64) {
|
||||
return DefaultCPUPeriod, int64(cores * float64(DefaultCPUPeriod))
|
||||
}
|
||||
|
||||
// PeriodAndQuotaToCores takes the CFS parameters period and quota and returns
|
||||
// a fraction that represents the limit to the number of cores that can be
|
||||
// utilized over the scheduling period.
|
||||
//
|
||||
// Cores is a fraction of the CFS period that a container may use. Period and
|
||||
// Quota are in microseconds.
|
||||
func PeriodAndQuotaToCores(period uint64, quota int64) float64 {
|
||||
return float64(quota) / float64(period)
|
||||
}
|
||||
|
@ -257,3 +257,23 @@ func TestValidateSysctlBadSysctl(t *testing.T) {
|
||||
_, err := ValidateSysctls(strSlice)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCoresToPeriodAndQuota(t *testing.T) {
|
||||
cores := 1.0
|
||||
expectedPeriod := DefaultCPUPeriod
|
||||
expectedQuota := int64(DefaultCPUPeriod)
|
||||
|
||||
actualPeriod, actualQuota := CoresToPeriodAndQuota(cores)
|
||||
assert.Equal(t, actualPeriod, expectedPeriod, "Period does not match")
|
||||
assert.Equal(t, actualQuota, expectedQuota, "Quota does not match")
|
||||
}
|
||||
|
||||
func TestPeriodAndQuotaToCores(t *testing.T) {
|
||||
var (
|
||||
period uint64 = 100000
|
||||
quota int64 = 50000
|
||||
expectedCores = 0.5
|
||||
)
|
||||
|
||||
assert.Equal(t, PeriodAndQuotaToCores(period, quota), expectedCores)
|
||||
}
|
||||
|
Reference in New Issue
Block a user