mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-09 22:16:08 +02:00
Set maximum CPU and Memory requests on K8s (#1959)
* Set maximum CPU and Memory requests on K8s
This commit is contained in:
@@ -183,6 +183,32 @@ func (c *Cluster) enforceMinResourceLimits(resources *v1.ResourceRequirements) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cluster) enforceMaxResourceRequests(resources *v1.ResourceRequirements) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
cpuRequest := resources.Requests[v1.ResourceCPU]
|
||||
maxCPURequest := c.OpConfig.MaxCPURequest
|
||||
maxCPU, err := util.MinResource(maxCPURequest, cpuRequest.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not compare defined CPU request %s for %q container with configured maximum value %s: %v",
|
||||
cpuRequest.String(), constants.PostgresContainerName, maxCPURequest, err)
|
||||
}
|
||||
resources.Requests[v1.ResourceCPU] = maxCPU
|
||||
|
||||
memoryRequest := resources.Requests[v1.ResourceMemory]
|
||||
maxMemoryRequest := c.OpConfig.MaxMemoryRequest
|
||||
maxMemory, err := util.MinResource(maxMemoryRequest, memoryRequest.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not compare defined memory request %s for %q container with configured maximum value %s: %v",
|
||||
memoryRequest.String(), constants.PostgresContainerName, maxMemoryRequest, err)
|
||||
}
|
||||
resources.Requests[v1.ResourceMemory] = maxMemory
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setMemoryRequestToLimit(resources *v1.ResourceRequirements, containerName string, logger *logrus.Entry) {
|
||||
|
||||
requests := resources.Requests[v1.ResourceMemory]
|
||||
@@ -260,6 +286,13 @@ func (c *Cluster) generateResourceRequirements(
|
||||
setMemoryRequestToLimit(&result, containerName, c.logger)
|
||||
}
|
||||
|
||||
// enforce maximum cpu and memory requests for Postgres containers only
|
||||
if containerName == constants.PostgresContainerName {
|
||||
if err = c.enforceMaxResourceRequests(&result); err != nil {
|
||||
return nil, fmt.Errorf("could not enforce maximum resource requests: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1841,8 +1841,10 @@ func TestSidecars(t *testing.T) {
|
||||
},
|
||||
Resources: config.Resources{
|
||||
DefaultCPURequest: "200m",
|
||||
MaxCPURequest: "300m",
|
||||
DefaultCPULimit: "500m",
|
||||
DefaultMemoryRequest: "0.7Gi",
|
||||
MaxMemoryRequest: "1.0Gi",
|
||||
DefaultMemoryLimit: "1.3Gi",
|
||||
},
|
||||
SidecarImages: map[string]string{
|
||||
@@ -2128,8 +2130,10 @@ func TestGenerateService(t *testing.T) {
|
||||
},
|
||||
Resources: config.Resources{
|
||||
DefaultCPURequest: "200m",
|
||||
MaxCPURequest: "300m",
|
||||
DefaultCPULimit: "500m",
|
||||
DefaultMemoryRequest: "0.7Gi",
|
||||
MaxMemoryRequest: "1.0Gi",
|
||||
DefaultMemoryLimit: "1.3Gi",
|
||||
},
|
||||
SidecarImages: map[string]string{
|
||||
@@ -2415,18 +2419,21 @@ func TestGenerateResourceRequirements(t *testing.T) {
|
||||
roleLabel := "spilo-role"
|
||||
sidecarName := "postgres-exporter"
|
||||
|
||||
// two test cases will call enforceMinResourceLimits which emits 2 events per call
|
||||
// hence bufferSize of 4 is required
|
||||
newEventRecorder := record.NewFakeRecorder(4)
|
||||
// enforceMinResourceLimits will be called 2 twice emitting 4 events (2x cpu, 2x memory raise)
|
||||
// enforceMaxResourceRequests will be called 4 times emitting 6 events (2x cpu, 4x memory cap)
|
||||
// hence event bufferSize of 10 is required
|
||||
newEventRecorder := record.NewFakeRecorder(10)
|
||||
|
||||
configResources := config.Resources{
|
||||
ClusterLabels: map[string]string{"application": "spilo"},
|
||||
ClusterNameLabel: clusterNameLabel,
|
||||
DefaultCPURequest: "100m",
|
||||
DefaultCPULimit: "1",
|
||||
MaxCPURequest: "500m",
|
||||
MinCPULimit: "250m",
|
||||
DefaultMemoryRequest: "100Mi",
|
||||
DefaultMemoryLimit: "500Mi",
|
||||
MinCPULimit: "250m",
|
||||
MaxMemoryRequest: "1Gi",
|
||||
MinMemoryLimit: "250Mi",
|
||||
PodRoleLabel: roleLabel,
|
||||
}
|
||||
@@ -2558,6 +2565,10 @@ func TestGenerateResourceRequirements(t *testing.T) {
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: acidv1.PostgresSpec{
|
||||
Resources: &acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{Memory: "200Mi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{Memory: "300Mi"},
|
||||
},
|
||||
TeamID: "acid",
|
||||
Volume: acidv1.Volume{
|
||||
Size: "1G",
|
||||
@@ -2565,8 +2576,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedResources: acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "500Mi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"},
|
||||
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "300Mi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "300Mi"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -2691,6 +2702,62 @@ func TestGenerateResourceRequirements(t *testing.T) {
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"},
|
||||
},
|
||||
},
|
||||
{
|
||||
subTest: "test enforcing max cpu and memory requests",
|
||||
config: config.Config{
|
||||
Resources: configResources,
|
||||
PodManagementPolicy: "ordered_ready",
|
||||
SetMemoryRequestToLimit: false,
|
||||
},
|
||||
pgSpec: acidv1.Postgresql{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: acidv1.PostgresSpec{
|
||||
Resources: &acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "2", Memory: "4Gi"},
|
||||
},
|
||||
TeamID: "acid",
|
||||
Volume: acidv1.Volume{
|
||||
Size: "1G",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResources: acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{CPU: "500m", Memory: "1Gi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "2", Memory: "4Gi"},
|
||||
},
|
||||
},
|
||||
{
|
||||
subTest: "test SetMemoryRequestToLimit flag but raise only until max memory request",
|
||||
config: config.Config{
|
||||
Resources: configResources,
|
||||
PodManagementPolicy: "ordered_ready",
|
||||
SetMemoryRequestToLimit: true,
|
||||
},
|
||||
pgSpec: acidv1.Postgresql{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: acidv1.PostgresSpec{
|
||||
Resources: &acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{Memory: "500Mi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{Memory: "2Gi"},
|
||||
},
|
||||
TeamID: "acid",
|
||||
Volume: acidv1.Volume{
|
||||
Size: "1G",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResources: acidv1.Resources{
|
||||
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "1Gi"},
|
||||
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user