Add CPU limit, CPU Reservation and Memory Reservation

This adds support for CPU limit, CPU reservation as well as memory
reservation.

Specifically, when using the `deploy` key in Docker Compose.
This commit is contained in:
Charlie Drage
2017-08-03 09:41:14 -04:00
parent 3b2ef30afc
commit af26b797a2
9 changed files with 254 additions and 43 deletions
+30 -5
View File
@@ -389,14 +389,39 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
}
// Configure the resource limits
if service.MemLimit != 0 {
memoryResourceList := api.ResourceList{
api.ResourceMemory: *resource.NewQuantity(
int64(service.MemLimit), "RandomStringForFormat")}
template.Spec.Containers[0].Resources.Limits = memoryResourceList
if service.MemLimit != 0 || service.CPULimit != 0 {
resourceLimit := api.ResourceList{}
if service.MemLimit != 0 {
resourceLimit[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemLimit), "RandomStringForFormat")
}
if service.CPULimit != 0 {
resourceLimit[api.ResourceCPU] = *resource.NewQuantity(service.CPULimit, "RandomStringForFormat")
}
template.Spec.Containers[0].Resources.Limits = resourceLimit
}
// Configure the resource requests
if service.MemReservation != 0 || service.CPUReservation != 0 {
resourceRequests := api.ResourceList{}
if service.MemReservation != 0 {
resourceRequests[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemReservation), "RandomStringForFormat")
}
if service.CPUReservation != 0 {
resourceRequests[api.ResourceCPU] = *resource.NewQuantity(service.CPUReservation, "RandomStringForFormat")
}
template.Spec.Containers[0].Resources.Requests = resourceRequests
}
// Configure resource reservations
podSecurityContext := &api.PodSecurityContext{}
//set pid namespace mode
if service.Pid != "" {
if service.Pid == "host" {
+81 -23
View File
@@ -78,30 +78,31 @@ func TestCreateService(t *testing.T) {
}
/*
Test the creation of a service with a memory limit
Test the creation of a service with a memory limit and reservation
*/
func TestCreateServiceWithMemLimit(t *testing.T) {
// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported
Expose: []string{"expose"}, // not supported
Privileged: true,
Restart: "always",
MemLimit: 1337,
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported
Expose: []string{"expose"}, // not supported
Privileged: true,
Restart: "always",
MemLimit: 1337,
MemReservation: 1338,
}
// An example object generated via k8s runtime.Objects()
@@ -114,12 +115,69 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
t.Error(errors.Wrap(err, "k.Transform failed"))
}
// Retrieve the deployment object and test that it matches the MemLimit value
// Retrieve the deployment object and test that it matches the mem value
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
memTest, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memTest != 1337 {
t.Errorf("Expected 1337 for mem_limit check, got %v", memTest)
memLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memLimit != 1337 {
t.Errorf("Expected 1337 for memory limit check, got %v", memLimit)
}
memReservation, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Requests.Memory().AsInt64()
if memReservation != 1338 {
t.Errorf("Expected 1338 for memory reservation check, got %v", memReservation)
}
}
}
}
/*
Test the creation of a service with a cpu limit and reservation
*/
func TestCreateServiceWithCPULimit(t *testing.T) {
// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported
Expose: []string{"expose"}, // not supported
Privileged: true,
Restart: "always",
CPULimit: 10,
CPUReservation: 1,
}
// An example object generated via k8s runtime.Objects()
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
}
k := Kubernetes{}
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
if err != nil {
t.Error(errors.Wrap(err, "k.Transform failed"))
}
// Retrieve the deployment object and test that it matches the cpu value
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
cpuLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().AsInt64()
if cpuLimit != 10 {
t.Errorf("Expected 10 for cpu limit check, got %v", cpuLimit)
}
cpuReservation, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().AsInt64()
if cpuReservation != 1 {
t.Errorf("Expected 1 for cpu reservation check, got %v", cpuReservation)
}
}
}