Skip to content

Commit

Permalink
Add container quota request for nginx side-car
Browse files Browse the repository at this point in the history
  • Loading branch information
drgarcia1986 committed Jul 21, 2020
1 parent 51ad1ae commit 37bbd32
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 39 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [NEXT_RELEASE]
### Added
- Nginx default `requests` quota value for cpu and memory

## [0.33.0] - 2020-06-23
### Added
- Verification to avoid ingress duplication when an unmanaged ingress exists
Expand Down
51 changes: 33 additions & 18 deletions pkg/server/k8s/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,20 @@ func containerSpecsToK8sContainers(containerSpecs []*spec.Container) ([]k8sv1.Co
Image: cs.Image,
}

if cs.ContainerLimits != nil {
cpu, err := resource.ParseQuantity(cs.ContainerLimits.CPU)
if cs.ContainerRequests != nil {
requests, err := containerQuotaToResourceList(cs.ContainerRequests)
if err != nil {
return nil, err
}
memory, err := resource.ParseQuantity(cs.ContainerLimits.Memory)
c.Resources.Requests = requests
}

if cs.ContainerLimits != nil {
limits, err := containerQuotaToResourceList(cs.ContainerLimits)
if err != nil {
return nil, err
}
c.Resources = k8sv1.ResourceRequirements{
Limits: k8sv1.ResourceList{
k8sv1.ResourceCPU: cpu,
k8sv1.ResourceMemory: memory,
},
}
c.Resources.Limits = limits
}

if len(cs.Command) > 0 {
Expand Down Expand Up @@ -95,6 +94,22 @@ func containerSpecsToK8sContainers(containerSpecs []*spec.Container) ([]k8sv1.Co
return containers, nil
}

func containerQuotaToResourceList(quota *spec.ContainerLimits) (k8sv1.ResourceList, error) {
cpu, err := resource.ParseQuantity(quota.CPU)
if err != nil {
return nil, err
}
memory, err := resource.ParseQuantity(quota.Memory)
if err != nil {
return nil, err
}

return k8sv1.ResourceList{
k8sv1.ResourceCPU: cpu,
k8sv1.ResourceMemory: memory,
}, nil
}

func podSpecVolumesToK8sVolumes(vols []*spec.Volume) []k8sv1.Volume {
volumes := make([]k8sv1.Volume, 0)
for _, v := range vols {
Expand Down Expand Up @@ -134,9 +149,9 @@ func podSpecToK8sPod(podSpec *spec.Pod) (*k8sv1.Pod, error) {
}

ps := k8sv1.PodSpec{
RestartPolicy: k8sv1.RestartPolicyNever,
Containers: containers,
Volumes: volumes,
RestartPolicy: k8sv1.RestartPolicyNever,
Containers: containers,
Volumes: volumes,
AutomountServiceAccountToken: &f,
InitContainers: initContainers,
}
Expand Down Expand Up @@ -179,9 +194,9 @@ func deploySpecToK8sDeploy(deploySpec *spec.Deploy, replicas int32) (*v1beta2.De
return nil, err
}
ps := k8sv1.PodSpec{
RestartPolicy: k8sv1.RestartPolicyAlways,
Containers: containers,
Volumes: volumes,
RestartPolicy: k8sv1.RestartPolicyAlways,
Containers: containers,
Volumes: volumes,
AutomountServiceAccountToken: &f,
InitContainers: initContainers,
DNSConfig: dnsConfigToK8sDNSConfig(deploySpec.DNSConfig),
Expand Down Expand Up @@ -253,9 +268,9 @@ func cronJobSpecToK8sCronJob(cronJobSpec *spec.CronJob) (*k8sv1beta1.CronJob, er

f := false
ps := k8sv1.PodSpec{
RestartPolicy: k8sv1.RestartPolicyNever,
Containers: containers,
Volumes: volumes,
RestartPolicy: k8sv1.RestartPolicyNever,
Containers: containers,
Volumes: volumes,
AutomountServiceAccountToken: &f,
InitContainers: initContainers,
}
Expand Down
62 changes: 58 additions & 4 deletions pkg/server/k8s/converters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ func TestPodSpecToK8sContainers(t *testing.T) {
CPU: "800m",
Memory: "1Gi",
},
ContainerRequests: &spec.ContainerLimits{
CPU: "100m",
Memory: "512Mi",
},
}},
}
containers, err := podSpecToK8sContainers(ps)
Expand Down Expand Up @@ -89,7 +93,30 @@ func TestPodSpecToK8sContainers(t *testing.T) {
}
}

expectedCPU, err := resource.ParseQuantity(ps.Containers[0].ContainerLimits.CPU)
expectedCPU, err := resource.ParseQuantity(ps.Containers[0].ContainerRequests.CPU)
if err != nil {
t.Fatal("error in default cpu limit:", err)
}
if c.Resources.Requests[k8sv1.ResourceCPU] != expectedCPU {
t.Errorf(
"expected %v, got %v",
expectedCPU,
c.Resources.Requests[k8sv1.ResourceCPU],
)
}
expectedMemory, err := resource.ParseQuantity(ps.Containers[0].ContainerRequests.Memory)
if err != nil {
t.Fatal("error in default memory limit:", err)
}
if c.Resources.Requests[k8sv1.ResourceMemory] != expectedMemory {
t.Errorf(
"expected %v, got %v",
expectedMemory,
c.Resources.Requests[k8sv1.ResourceMemory],
)
}

expectedCPU, err = resource.ParseQuantity(ps.Containers[0].ContainerLimits.CPU)
if err != nil {
t.Fatal("error in default cpu limit:", err)
}
Expand All @@ -100,7 +127,7 @@ func TestPodSpecToK8sContainers(t *testing.T) {
c.Resources.Limits[k8sv1.ResourceCPU],
)
}
expectedMemory, err := resource.ParseQuantity(ps.Containers[0].ContainerLimits.Memory)
expectedMemory, err = resource.ParseQuantity(ps.Containers[0].ContainerLimits.Memory)
if err != nil {
t.Fatal("error in default memory limit:", err)
}
Expand Down Expand Up @@ -579,9 +606,9 @@ func TestK8sServiceToService(t *testing.T) {
Namespace: namespace,
},
Spec: k8sv1.ServiceSpec{
Type: k8sv1.ServiceType(svcType),
Type: k8sv1.ServiceType(svcType),
LoadBalancerSourceRanges: ranges,
Ports: []k8sv1.ServicePort{{}},
Ports: []k8sv1.ServicePort{{}},
},
}
svc := k8sServiceToService(k8sSvc)
Expand Down Expand Up @@ -724,3 +751,30 @@ func TestDeploySpecPodTemplateAnnotations(t *testing.T) {
t.Errorf("got %v; want %v", got, want)
}
}

func TestContainerQuotaToResourceList(t *testing.T) {
quota := &spec.ContainerLimits{
CPU: "100m",
Memory: "1Gi",
}
expectedCPU, err := resource.ParseQuantity(quota.CPU)
if err != nil {
t.Error("Error parsing default CPU value")
}
expectedMemory, err := resource.ParseQuantity(quota.Memory)
if err != nil {
t.Error("Error parsing default Memory value")
}

rl, err := containerQuotaToResourceList(quota)
if err != nil {
t.Errorf("Got an unexpected error, %v", err)
}

if rl[k8sv1.ResourceCPU] != expectedCPU {
t.Errorf("expected %v, got %v", expectedCPU, rl[k8sv1.ResourceCPU])
}
if rl[k8sv1.ResourceMemory] != expectedMemory {
t.Errorf("expected %v, got %v", expectedMemory, rl[k8sv1.ResourceMemory])
}
}
27 changes: 18 additions & 9 deletions pkg/server/spec/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ type Port struct {
}

type Container struct {
Name string
Image string
ContainerLimits *ContainerLimits
Env map[string]string
VolumeMounts []*VolumeMounts
Command []string
Args []string
Ports []Port
Secrets []string
Name string
Image string
ContainerLimits *ContainerLimits
ContainerRequests *ContainerLimits
Env map[string]string
VolumeMounts []*VolumeMounts
Command []string
Args []string
Ports []Port
Secrets []string
}

type ContainerBuilder struct {
Expand Down Expand Up @@ -63,6 +64,14 @@ func (b *ContainerBuilder) WithLimits(cpu, memory string) *ContainerBuilder {
return b
}

func (b *ContainerBuilder) WithRequests(cpu, memory string) *ContainerBuilder {
b.c.ContainerRequests = &ContainerLimits{
CPU: cpu,
Memory: memory,
}
return b
}

func (b *ContainerBuilder) ExposePort(name string, port int) *ContainerBuilder {
b.c.Ports = append(b.c.Ports, Port{Name: name, ContainerPort: int32(port)})
return b
Expand Down
8 changes: 8 additions & 0 deletions pkg/server/spec/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ func TestContainerBuilder(t *testing.T) {
expectedEnv := map[string]string{"Key": "Value"}
expectedSecrets := []string{"SECRET", "VERY-SECRET"}
expectedLimits := ContainerLimits{CPU: "200m", Memory: "256Mi"}
expectedRequests := ContainerLimits{CPU: "50m", Memory: "56Mi"}
expectedCmd := []string{"echo", "hi"}
expectedArgs := []string{"hello", "from", "test"}
expectedPort := 5000
Expand All @@ -16,6 +17,7 @@ func TestContainerBuilder(t *testing.T) {
WithEnv(expectedEnv).
WithSecrets(expectedSecrets).
WithLimits(expectedLimits.CPU, expectedLimits.Memory).
WithRequests(expectedRequests.CPU, expectedRequests.Memory).
WithCommand(expectedCmd).
WithArgs(expectedArgs).
ExposePort("http", expectedPort).
Expand All @@ -33,6 +35,12 @@ func TestContainerBuilder(t *testing.T) {
if actual := c.ContainerLimits.Memory; actual != expectedLimits.Memory {
t.Errorf("expected %s, got %s", expectedLimits.Memory, actual)
}
if actual := c.ContainerRequests.CPU; actual != expectedRequests.CPU {
t.Errorf("expected %s, got %s", expectedRequests.CPU, actual)
}
if actual := c.ContainerRequests.Memory; actual != expectedRequests.Memory {
t.Errorf("expected %s, got %s", expectedRequests.Memory, actual)
}
if actual := c.Ports[0].ContainerPort; actual != int32(expectedPort) {
t.Errorf("expected %d, got %d", expectedPort, actual)
}
Expand Down
19 changes: 11 additions & 8 deletions pkg/server/spec/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import (
)

const (
NginxConfFile = "nginx.conf"
nginxConfTmplDir = "/etc/nginx/template/"
nginxConfDir = "/etc/nginx/"
nginxVolName = "nginx-conf"
nginxArgTmpl = "envsubst '%s' < %s%s > %s%s && nginx -g 'daemon off;'"
nginxBackendTmpl = "http://localhost:%d"
nginxDefaultCPULimit = "100m"
nginxDefaultMemoryLimit = "256Mi"
NginxConfFile = "nginx.conf"
nginxConfTmplDir = "/etc/nginx/template/"
nginxConfDir = "/etc/nginx/"
nginxVolName = "nginx-conf"
nginxArgTmpl = "envsubst '%s' < %s%s > %s%s && nginx -g 'daemon off;'"
nginxBackendTmpl = "http://localhost:%d"
nginxDefaultCPULimit = "100m"
nginxDefaultMemoryLimit = "256Mi"
nginxDefaultCPURequest = "25m"
nginxDefaultMemoryRequest = "56Mi"
)

func newNginxContainerArgs(env map[string]string) string {
Expand Down Expand Up @@ -54,6 +56,7 @@ func NewNginxContainer(image string, a *app.App) *Container {
WithArgs([]string{"-c", args}).
WithEnv(env).
WithLimits(nginxDefaultCPULimit, nginxDefaultMemoryLimit).
WithRequests(nginxDefaultCPURequest, nginxDefaultMemoryRequest).
ExposePort("nginx", secondaryPort).
Build()
}
3 changes: 3 additions & 0 deletions pkg/server/spec/nginx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,7 @@ func TestNewNginxContainer(t *testing.T) {
if actual := c.ContainerLimits.CPU; actual != nginxDefaultCPULimit {
t.Errorf("expected %s, got %s", nginxDefaultCPULimit, actual)
}
if actual := c.ContainerRequests.CPU; actual != nginxDefaultCPURequest {
t.Errorf("expected %s, got %s", nginxDefaultCPULimit, actual)
}
}

0 comments on commit 37bbd32

Please sign in to comment.