Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable setting the resource request/limits via annotations for queue-proxy side-car container #4151

Merged
12 changes: 12 additions & 0 deletions pkg/reconciler/revision/resources/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ const (
// QueueContainerName is the name of the queue proxy side car
QueueContainerName = "queue-proxy"

// queueContainerRequestCPUAnnotation is the request.cpu of the queue proxy side car
queueContainerRequestCPUAnnotation = "queue.sidecar.serving.knative.dev/requestCpu"

// queueContainerLimitCPUAnnotation is the limit.cpu of the queue proxy side car
queueContainerLimitCPUAnnotation = "queue.sidecar.serving.knative.dev/limitCpu"

// queueContainerRequestMemoryAnnotation is the request.memory of the queue proxy side car
queueContainerRequestMemoryAnnotation = "queue.sidecar.serving.knative.dev/RequestMemory"

// queueContainerLimitMemoryAnnotation is the limit.memory of the queue proxy side car
queueContainerLimitMemoryAnnotation = "queue.sidecar.serving.knative.dev/LimitMemory"

sidecarIstioInjectAnnotation = "sidecar.istio.io/inject"
// IstioOutboundIPRangeAnnotation defines the outbound ip ranges istio allows.
// TODO(mattmoor): Make this private once we remove revision_test.go
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/revision/resources/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var (

defaultQueueContainer = &corev1.Container{
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
Env: []corev1.EnvVar{{
Expand Down
57 changes: 50 additions & 7 deletions pkg/reconciler/revision/resources/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package resources
import (
"strconv"

"k8s.io/apimachinery/pkg/api/resource"

"k8s.io/apimachinery/pkg/util/intstr"

"github.com/knative/pkg/logging"
Expand All @@ -37,12 +39,6 @@ import (
const requestQueueHTTPPortName = "queue-port"

var (
queueResources = corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceName("cpu"): queueContainerCPU,
},
}

queueHTTPPort = corev1.ContainerPort{
Name: requestQueueHTTPPortName,
ContainerPort: int32(networking.BackendHTTPPort),
Expand Down Expand Up @@ -82,6 +78,53 @@ var (
}
)

func getResources(annotations map[string]string) corev1.ResourceRequirements {

resources := corev1.ResourceRequirements{}
resourcesRequest := corev1.ResourceList{corev1.ResourceCPU: queueContainerCPU}
resourcesLimits := corev1.ResourceList{}
ok := false
var requestCPU, limitCPU, requestMemory, limitMemory resource.Quantity
if ok, requestCPU = getResourceFromAnnotations(annotations, queueContainerRequestCPUAnnotation); ok {
resourcesRequest[corev1.ResourceCPU] = requestCPU
}

if ok, limitCPU = getResourceFromAnnotations(annotations, queueContainerLimitCPUAnnotation); ok {
resourcesLimits[corev1.ResourceCPU] = limitCPU
}

if ok, requestMemory = getResourceFromAnnotations(annotations, queueContainerRequestMemoryAnnotation); ok {
resourcesRequest[corev1.ResourceMemory] = requestMemory
}

if ok, limitMemory = getResourceFromAnnotations(annotations, queueContainerLimitMemoryAnnotation); ok {
resourcesLimits[corev1.ResourceMemory] = limitMemory
}

if len(resourcesRequest) != 0 {
resources.Requests = resourcesRequest
}

if len(resourcesRequest) != 0 {
resources.Limits = resourcesLimits
}

return resources
}

func getResourceFromAnnotations(m map[string]string, k string) (bool, resource.Quantity) {
v, ok := m[k]
if !ok {
return false, resource.Quantity{}
}
quantity, err := resource.ParseQuantity(v)
if err != nil {
return false, resource.Quantity{}
}

return true, quantity
}

// makeQueueContainer creates the container spec for the queue sidecar.
func makeQueueContainer(rev *v1alpha1.Revision, loggingConfig *logging.Config, observabilityConfig *metrics.ObservabilityConfig,
autoscalerConfig *autoscaler.Config, deploymentConfig *deployment.Config) *corev1.Container {
Expand Down Expand Up @@ -115,7 +158,7 @@ func makeQueueContainer(rev *v1alpha1.Revision, loggingConfig *logging.Config, o
return &corev1.Container{
Name: QueueContainerName,
Image: deploymentConfig.QueueSidecarImage,
Resources: queueResources,
Resources: getResources(rev.GetAnnotations()),
Ports: ports,
ReadinessProbe: queueReadinessProbe,
Env: []corev1.EnvVar{{
Expand Down
98 changes: 90 additions & 8 deletions pkg/reconciler/revision/resources/queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -111,7 +111,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTP2Port),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -148,7 +148,89 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Image: "alpine",
Env: env(map[string]string{
"SERVING_SERVICE": "svc",
}),
}}, {
name: "resources in annotations ",
rev: &v1alpha1.Revision{
ObjectMeta: metav1.ObjectMeta{
Namespace: "foo",
Name: "bar",
UID: "1234",
Labels: map[string]string{
serving.ServiceLabelKey: "svc",
},
Annotations: map[string]string{
queueContainerRequestCPUAnnotation: "25m",
queueContainerRequestMemoryAnnotation: "100Mi",
},
},
Spec: v1alpha1.RevisionSpec{
RevisionSpec: v1beta1.RevisionSpec{
ContainerConcurrency: 1,
TimeoutSeconds: ptr.Int64(45),
},
},
},
lc: &logging.Config{},
oc: &metrics.ObservabilityConfig{},
ac: &autoscaler.Config{},
cc: &deployment.Config{
QueueSidecarImage: "alpine",
},
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: getResources(map[string]string{
queueContainerRequestCPUAnnotation: "25m",
queueContainerRequestMemoryAnnotation: "100Mi",
}),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Image: "alpine",
Env: env(map[string]string{
"SERVING_SERVICE": "svc",
}),
}}, {
name: "Invalid data for resources in annotations ",
rev: &v1alpha1.Revision{
ObjectMeta: metav1.ObjectMeta{
Namespace: "foo",
Name: "bar",
UID: "1234",
Labels: map[string]string{
serving.ServiceLabelKey: "svc",
},
Annotations: map[string]string{
queueContainerRequestMemoryAnnotation: "100Mx",
},
},
Spec: v1alpha1.RevisionSpec{
RevisionSpec: v1beta1.RevisionSpec{
ContainerConcurrency: 1,
TimeoutSeconds: ptr.Int64(45),
},
},
},
lc: &logging.Config{},
oc: &metrics.ObservabilityConfig{},
ac: &autoscaler.Config{},
cc: &deployment.Config{
QueueSidecarImage: "alpine",
},
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: getResources(map[string]string{
queueContainerRequestCPUAnnotation: "25m",
}),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -185,7 +267,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -223,7 +305,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -257,7 +339,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -287,7 +369,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down Expand Up @@ -320,7 +402,7 @@ func TestMakeQueueContainer(t *testing.T) {
want: &corev1.Container{
// These are effectively constant
Name: QueueContainerName,
Resources: queueResources,
Resources: getResources(make(map[string]string)),
Ports: append(queueNonServingPorts, queueHTTPPort),
ReadinessProbe: queueReadinessProbe,
// These changed based on the Revision and configs passed in.
Expand Down