func getNodeAllocatedResources(node api.Node, podList *api.PodList) (NodeAllocatedResources, error) { reqs, limits := map[api.ResourceName]resource.Quantity{}, map[api.ResourceName]resource.Quantity{} for _, pod := range podList.Items { podReqs, podLimits, err := api.PodRequestsAndLimits(&pod) if err != nil { return NodeAllocatedResources{}, err } for podReqName, podReqValue := range podReqs { if value, ok := reqs[podReqName]; !ok { reqs[podReqName] = *podReqValue.Copy() } else { value.Add(podReqValue) reqs[podReqName] = value } } for podLimitName, podLimitValue := range podLimits { if value, ok := limits[podLimitName]; !ok { limits[podLimitName] = *podLimitValue.Copy() } else { value.Add(podLimitValue) limits[podLimitName] = value } } } cpuRequests, cpuLimits, memoryRequests, memoryLimits := reqs[api.ResourceCPU], limits[api.ResourceCPU], reqs[api.ResourceMemory], limits[api.ResourceMemory] var cpuRequestsFraction, cpuLimitsFraction float64 = 0, 0 if capacity := float64(node.Status.Capacity.Cpu().MilliValue()); capacity > 0 { cpuRequestsFraction = float64(cpuRequests.MilliValue()) / capacity * 100 cpuLimitsFraction = float64(cpuLimits.MilliValue()) / capacity * 100 } var memoryRequestsFraction, memoryLimitsFraction float64 = 0, 0 if capacity := float64(node.Status.Capacity.Memory().MilliValue()); capacity > 0 { memoryRequestsFraction = float64(memoryRequests.MilliValue()) / capacity * 100 memoryLimitsFraction = float64(memoryLimits.MilliValue()) / capacity * 100 } return NodeAllocatedResources{ CPURequests: cpuRequests.MilliValue(), CPURequestsFraction: cpuRequestsFraction, CPULimits: cpuLimits.MilliValue(), CPULimitsFraction: cpuLimitsFraction, CPUCapacity: node.Status.Capacity.Cpu().MilliValue(), MemoryRequests: memoryRequests.Value(), MemoryRequestsFraction: memoryRequestsFraction, MemoryLimits: memoryLimits.Value(), MemoryLimitsFraction: memoryLimitsFraction, MemoryCapacity: node.Status.Capacity.Memory().Value(), AllocatedPods: len(podList.Items), PodCapacity: node.Status.Capacity.Pods().Value(), }, nil }
// NewPodResourcesProcurement converts k8s pod cpu and memory resource requirements into // mesos resource allocations. func NewPodResourcesProcurement() Procurement { return ProcurementFunc(func(t *T, _ *api.Node, ps *ProcureState) error { // TODO(sttts): fall back to requested resources if resource limit cannot be fulfilled by the offer _, limits, err := api.PodRequestsAndLimits(&t.Pod) if err != nil { return err } wantedCpus := float64(resources.NewCPUShares(limits[api.ResourceCPU])) wantedMem := float64(resources.NewMegaBytes(limits[api.ResourceMemory])) log.V(4).Infof( "trying to match offer with pod %v/%v: cpus: %.2f mem: %.2f MB", t.Pod.Namespace, t.Pod.Name, wantedCpus, wantedMem, ) podRoles := t.Roles() procuredCpu, remaining := procureScalarResources("cpus", wantedCpus, podRoles, ps.offer.GetResources()) if procuredCpu == nil { return fmt.Errorf( "not enough cpu resources for pod %s/%s: want=%v", t.Pod.Namespace, t.Pod.Name, wantedCpus, ) } procuredMem, remaining := procureScalarResources("mem", wantedMem, podRoles, remaining) if procuredMem == nil { return fmt.Errorf( "not enough mem resources for pod %s/%s: want=%v", t.Pod.Namespace, t.Pod.Name, wantedMem, ) } ps.offer.Resources = remaining ps.spec.Resources = append(ps.spec.Resources, append(procuredCpu, procuredMem...)...) return nil }) }