runtime: resource limits (kubernetes implementation) (#1931)

* runtime: add resource limit CreateOptions

* util/kubernetes/client: implement support for resource limits

* runtime/kubernetes: set resource limits for k8s deployments

* util/kubernetes: remove template check for ints

* util/kubernetes: fix incorrect yaml syntax

* runtime/kubernetes: fix incorrect units

* runtime: update create options to use Resources struct
This commit is contained in:
ben-toogood 2020-08-14 11:47:28 +01:00 committed by GitHub
parent 374aae1490
commit 5a88ea7247
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package kubernetes
import ( import (
"encoding/json" "encoding/json"
"fmt"
"strings" "strings"
"time" "time"
@ -102,6 +103,22 @@ func newService(s *runtime.Service, c runtime.CreateOptions) *service {
kdeploy.Spec.Template.PodSpec.Containers[0].Args = c.Args kdeploy.Spec.Template.PodSpec.Containers[0].Args = c.Args
} }
// apply resource limits
if c.Resources != nil {
resLimits := &client.ResourceLimits{}
if c.Resources.CPU > 0 {
resLimits.CPU = fmt.Sprintf("%vm", c.Resources.CPU)
}
if c.Resources.Mem > 0 {
resLimits.Memory = fmt.Sprintf("%vMi", c.Resources.Mem)
}
if c.Resources.Disk > 0 {
resLimits.EphemeralStorage = fmt.Sprintf("%vMi", c.Resources.Disk)
}
kdeploy.Spec.Template.PodSpec.Containers[0].Resources = &client.ResourceRequirements{Limits: resLimits}
}
return &service{ return &service{
Service: s, Service: s,
kservice: kservice, kservice: kservice,

View File

@ -84,6 +84,8 @@ type CreateOptions struct {
Context context.Context Context context.Context
// Secrets to use // Secrets to use
Secrets map[string]string Secrets map[string]string
// Resources to allocate the service
Resources *Resources
} }
// ReadOptions queries runtime services // ReadOptions queries runtime services
@ -176,6 +178,13 @@ func WithOutput(out io.Writer) CreateOption {
} }
} }
// ResourceLimits sets the resources for the service to use
func ResourceLimits(r *Resources) CreateOption {
return func(o *CreateOptions) {
o.Resources = r
}
}
// ReadService returns services with the given name // ReadService returns services with the given name
func ReadService(service string) ReadOption { func ReadService(service string) ReadOption {
return func(o *ReadOptions) { return func(o *ReadOptions) {

View File

@ -104,3 +104,16 @@ type Service struct {
// Metadata stores metadata // Metadata stores metadata
Metadata map[string]string Metadata map[string]string
} }
// Resources which are allocated to a serivce
type Resources struct {
// CPU is the maximum amount of CPU the service will be allocated (unit millicpu)
// e.g. 0.25CPU would be passed as 250
CPU int
// Mem is the maximum amount of memory the service will be allocated (unit mebibyte)
// e.g. 128 MiB of memory would be passed as 128
Mem int
// Disk is the maximum amount of disk space the service will be allocated (unit mebibyte)
// e.g. 128 MiB of memory would be passed as 128
Disk int
}

View File

@ -90,8 +90,8 @@ spec:
{{- range . }} {{- range . }}
- containerPort: {{ .ContainerPort }} - containerPort: {{ .ContainerPort }}
name: {{ .Name }} name: {{ .Name }}
{{- end}} {{- end }}
{{- end}} {{- end }}
{{- if .ReadinessProbe }} {{- if .ReadinessProbe }}
{{- with .ReadinessProbe }} {{- with .ReadinessProbe }}
readinessProbe: readinessProbe:
@ -106,6 +106,39 @@ spec:
periodSeconds: {{ .PeriodSeconds }} periodSeconds: {{ .PeriodSeconds }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Resources }}
{{- with .Resources }}
resources:
{{- if .Limits }}
{{- with .Limits }}
limits:
{{- if .Memory }}
memory: {{ .Memory }}
{{- end }}
{{- if .CPU }}
cpu: {{ .CPU }}
{{- end }}
{{- if .EphemeralStorage }}
ephemeral-storage: {{ .EphemeralStorage }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Requests }}
{{- with .Requests }}
requests:
{{- if .Memory }}
memory: {{ .Memory }}
{{- end }}
{{- if .CPU }}
cpu: {{ .CPU }}
{{- end }}
{{- if .EphemeralStorage }}
ephemeral-storage: {{ .EphemeralStorage }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
` `

View File

@ -42,6 +42,7 @@ type Container struct {
Args []string `json:"args,omitempty"` Args []string `json:"args,omitempty"`
Ports []ContainerPort `json:"ports,omitempty"` Ports []ContainerPort `json:"ports,omitempty"`
ReadinessProbe *Probe `json:"readinessProbe,omitempty"` ReadinessProbe *Probe `json:"readinessProbe,omitempty"`
Resources *ResourceRequirements `json:"resources,omitempty"`
} }
// DeploymentSpec defines micro deployment spec // DeploymentSpec defines micro deployment spec
@ -234,3 +235,16 @@ type TCPSocketAction struct {
Host string `json:"host,omitempty"` Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"` Port int `json:"port,omitempty"`
} }
// ResourceRequirements describes the compute resource requirements.
type ResourceRequirements struct {
Limits *ResourceLimits `json:"limits,omitempty"`
Requests *ResourceLimits `json:"requests,omitempty"`
}
// ResourceLimits describes the limits for a service
type ResourceLimits struct {
Memory string `json:"memory,omitempty"`
CPU string `json:"cpu,omitempty"`
EphemeralStorage string `json:"ephemeral-storage,omitempty"`
}