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

Add support for maxConnections, maxConcurrentRequests, and maxPendingRequests to IngressGateway CRD #1691

Merged
merged 5 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ FEATURES:
* Support merged metrics with consul-dataplane. [[GH-1635](https://github.com/hashicorp/consul-k8s/pull/1635)]
* Support transparent proxying when using consul-dataplane. [[GH-1625](https://github.com/hashicorp/consul-k8s/pull/1478),[GH-1632](https://github.com/hashicorp/consul-k8s/pull/1632)]
* Enable sync-catalog to only talk to Consul servers. [[GH-1659](https://github.com/hashicorp/consul-k8s/pull/1659)]
* Ingress Gateway
* Add support for MaxConnections, MaxConcurrentRequests, and MaxPendingRequests to Ingress Gateway CRD. [[GH-1691](https://github.com/hashicorp/consul-k8s/pull/1691)]

IMPROVEMENTS:
* CLI
Expand Down
41 changes: 41 additions & 0 deletions charts/consul/templates/crd-ingressgateways.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@ spec:
spec:
description: IngressGatewaySpec defines the desired state of IngressGateway.
properties:
defaults:
description: Defaults is default configuration for all upstream services
properties:
maxConcurrentRequests:
description: The maximum number of concurrent requests that will
be allowed at a single point in time. Use this to limit HTTP/2
traffic, since HTTP/2 has many requests per connection.
format: int32
type: integer
maxConnections:
description: The maximum number of connections a service instance
will be allowed to establish against the given upstream. Use
this to limit HTTP/1.1 traffic, since HTTP/1.1 has a request
per connection.
format: int32
type: integer
maxPendingRequests:
description: The maximum number of requests that will be queued
while waiting for a connection to be established.
format: int32
type: integer
type: object
listeners:
description: Listeners declares what ports the ingress gateway should
listen on, and what services to associated to those ports.
Expand Down Expand Up @@ -98,6 +120,25 @@ spec:
items:
type: string
type: array
maxConcurrentRequests:
description: The maximum number of concurrent requests
that will be allowed at a single point in time. Use
this to limit HTTP/2 traffic, since HTTP/2 has many
requests per connection.
format: int32
type: integer
maxConnections:
description: The maximum number of connections a service
instance will be allowed to establish against the given
upstream. Use this to limit HTTP/1.1 traffic, since
HTTP/1.1 has a request per connection.
format: int32
type: integer
maxPendingRequests:
description: The maximum number of requests that will
be queued while waiting for a connection to be established.
format: int32
type: integer
name:
description: "Name declares the service to which traffic
should be forwarded. \n This can either be a specific
Expand Down
72 changes: 65 additions & 7 deletions control-plane/api/v1alpha1/ingressgateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ type IngressGatewaySpec struct {
// Listeners declares what ports the ingress gateway should listen on, and
// what services to associated to those ports.
Listeners []IngressListener `json:"listeners,omitempty"`

// Defaults is default configuration for all upstream services
Defaults *IngressServiceConfig `json:"defaults,omitempty"`
}

type IngressServiceConfig struct {
// The maximum number of connections a service instance
// will be allowed to establish against the given upstream. Use this to limit
// HTTP/1.1 traffic, since HTTP/1.1 has a request per connection.
MaxConnections *uint32 `json:"maxConnections,omitempty"`
// The maximum number of requests that will be queued
// while waiting for a connection to be established.
MaxPendingRequests *uint32 `json:"maxPendingRequests,omitempty"`
// The maximum number of concurrent requests that
// will be allowed at a single point in time. Use this to limit HTTP/2 traffic,
// since HTTP/2 has many requests per connection.
MaxConcurrentRequests *uint32 `json:"maxConcurrentRequests,omitempty"`
}

type GatewayTLSConfig struct {
Expand Down Expand Up @@ -144,6 +161,8 @@ type IngressService struct {
// Allow HTTP header manipulation to be configured.
RequestHeaders *HTTPHeaderModifiers `json:"requestHeaders,omitempty"`
ResponseHeaders *HTTPHeaderModifiers `json:"responseHeaders,omitempty"`

IngressServiceConfig `json:",inline"`
}

func (in *IngressGateway) GetObjectMeta() metav1.ObjectMeta {
Expand Down Expand Up @@ -235,6 +254,7 @@ func (in *IngressGateway) ToConsul(datacenter string) capi.ConfigEntry {
TLS: *in.Spec.TLS.toConsul(),
Listeners: listeners,
Meta: meta(datacenter),
Defaults: in.Spec.Defaults.toConsul(),
}
}

Expand All @@ -257,6 +277,8 @@ func (in *IngressGateway) Validate(consulMeta common.ConsulMeta) error {
errs = append(errs, v.validate(path.Child("listeners").Index(i), consulMeta)...)
}

errs = append(errs, in.Spec.Defaults.validate(path.Child("defaults"))...)

if len(errs) > 0 {
return apierrors.NewInvalid(
schema.GroupKind{Group: ConsulHashicorpGroup, Kind: ingressGatewayKubeKind},
Expand Down Expand Up @@ -329,13 +351,16 @@ func (in IngressListener) toConsul() capi.IngressListener {

func (in IngressService) toConsul() capi.IngressService {
return capi.IngressService{
Name: in.Name,
Hosts: in.Hosts,
Namespace: in.Namespace,
Partition: in.Partition,
TLS: in.TLS.toConsul(),
RequestHeaders: in.RequestHeaders.toConsul(),
ResponseHeaders: in.ResponseHeaders.toConsul(),
Name: in.Name,
Hosts: in.Hosts,
Namespace: in.Namespace,
Partition: in.Partition,
TLS: in.TLS.toConsul(),
RequestHeaders: in.RequestHeaders.toConsul(),
ResponseHeaders: in.ResponseHeaders.toConsul(),
MaxConnections: in.MaxConnections,
MaxPendingRequests: in.MaxPendingRequests,
MaxConcurrentRequests: in.MaxConcurrentRequests,
}
}

Expand Down Expand Up @@ -406,6 +431,39 @@ func (in IngressListener) validate(path *field.Path, consulMeta common.ConsulMet
string(asJSON),
"hosts must be empty if protocol is \"tcp\""))
}

errs = append(errs, svc.IngressServiceConfig.validate(path)...)
}
return errs
}

func (in *IngressServiceConfig) validate(path *field.Path) field.ErrorList {
if in == nil {
return nil
}
var errs field.ErrorList

if in.MaxConnections != nil && *in.MaxConnections <= 0 {
errs = append(errs, field.Invalid(path.Child("maxconnections"), *in.MaxConnections, "MaxConnections must be > 0"))
}

if in.MaxConcurrentRequests != nil && *in.MaxConcurrentRequests <= 0 {
errs = append(errs, field.Invalid(path.Child("maxconcurrentrequests"), *in.MaxConcurrentRequests, "MaxConcurrentRequests must be > 0"))
}

if in.MaxPendingRequests != nil && *in.MaxPendingRequests <= 0 {
errs = append(errs, field.Invalid(path.Child("maxpendingrequests"), *in.MaxPendingRequests, "MaxPendingRequests must be > 0"))
}
return errs
}

func (in *IngressServiceConfig) toConsul() *capi.IngressServiceConfig {
if in == nil {
return nil
}
return &capi.IngressServiceConfig{
MaxConnections: in.MaxConnections,
MaxPendingRequests: in.MaxPendingRequests,
MaxConcurrentRequests: in.MaxConcurrentRequests,
}
}
Loading