Skip to content

Commit

Permalink
Merge branch 'projectcontour:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
m-yosefpor authored Sep 27, 2023
2 parents 1664b47 + 1d0a774 commit bedcc67
Show file tree
Hide file tree
Showing 29 changed files with 1,117 additions and 107 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Log in to GHCR
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Log in to GHCR
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Build image
Expand Down
9 changes: 9 additions & 0 deletions apis/projectcontour/v1alpha1/contourdeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ type EnvoySettings struct {
// +kubebuilder:validation:Minimum=0
// +optional
BaseID int32 `json:"baseID,omitempty"`

// OverloadMaxHeapSize defines the maximum heap memory of the envoy controlled by the overload manager.
// When the value is greater than 0, the overload manager is enabled,
// and when envoy reaches 95% of the maximum heap size, it performs a shrink heap operation,
// When it reaches 98% of the maximum heap size, Envoy Will stop accepting requests.
// More info: https://projectcontour.io/docs/main/config/overload-manager/
//
// +optional
OverloadMaxHeapSize uint64 `json:"overloadMaxHeapSize,omitempty"`
}

// WorkloadType is the type of Kubernetes workload to use for a component.
Expand Down
38 changes: 38 additions & 0 deletions changelogs/unreleased/5657-shadialtarsha-minor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Specific routes can now opt out of the virtual host's global rate limit policy

Setting `rateLimitPolicy.global.disabled` flag to true on a specific route now disables the global rate limit policy inherited from the virtual host for that route.

### Sample Configurations
In the example below, `/foo` route is opted out from the global rate limit policy defined by the virtualhost.
#### httpproxy.yaml
```yaml
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: echo
spec:
virtualhost:
fqdn: local.projectcontour.io
rateLimitPolicy:
global:
descriptors:
- entries:
- remoteAddress: {}
- genericKey:
key: vhost
value: local.projectcontour.io
routes:
- conditions:
- prefix: /
services:
- name: ingress-conformance-echo
port: 80
- conditions:
- prefix: /foo
rateLimitPolicy:
global:
disabled: true
services:
- name: ingress-conformance-echo
port: 80
```
1 change: 1 addition & 0 deletions changelogs/unreleased/5699-yangyy93-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Gateway provisioner: Add the `overloadMaxHeapSize` configuration option to contourDeployment to allow adding [overloadManager](https://projectcontour.io/docs/main/config/overload-manager/) configuration when generating envoy's initial configuration file.
119 changes: 119 additions & 0 deletions design/endpoint-slice-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Contour k8s EndpointSlice support

Contour currently supports Kubernetes endpoints.
This document proposes a process to enable support for k8s EndpointSlices and, eventually, migrate to exclusively using it.

## Goals

- Contour will support k8s EndpointSlices.
- The EndpointSlices will be gated by a feature flag in the Contour config.
- Kubernetes endpoints will still be the default mode of operation.

## Non-goals

- Removal of k8s endpoints.
- Support advanced features such as topology aware routing/hints offered by k8s endpoints.

## Background

See [#2696](https://github.com/projectcontour/contour/issues/2696)

Before the introduction of the EndpointSlices, the only method for a service to expose the IP addresses and ports of the pads it fronted was through Kubernetes endpoints.

However, Kubernetes endpoints have a few challenges with scaling, such as
- transmission of the entire endpoint object even if one endpoint changes, leading to network contention and heavy recalculation on the consumers of this data.
- As of k8s v1.22, a hard limit of 1000 addresses per endpoint object.
- No topology aware information for more intelligent routing.

To solve the above problems, EndpointSlices was introduced in 1.16 and, as of k8s v1.21 in [stable state](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/).


## High-Level Design

A feature flag will gate the usage of EndpointSlices, and the implementation will use the same pattern as used in the `endpointtranslator.go` with a few differences listed in the detailed design.

## Detailed Design

### Contour Configuration changes
EndpointSlices will be configured by a boolean feature flag, which defaults to false and allows users to opt to use EndpointSlices.

```yaml
...
server:
xds-server-type: contour
use-endpoint-slice: true
...
```

```go
type Parameters struct {
// useEndpointSlice configures contour to fetch endpoint data
// from k8s EndpointSlices. defaults to false and reading endpoint
// data from the k8s endpoints.
useEndpointSlice bool
}
```
### Implementation

#### Context
The implementation of k8s EndpointSlices is fundamentally different from how EndpointSlices work.

Below is an example of a Kubernetes service represented in as endpoint and EndpointSlice objects

endpoints
```
NAME ENDPOINTS AGE
ingress-conformance-echo 10.244.0.10:3000,10.244.0.153:3000,10.244.0.154:3000 + 7 more... 3d
```

EndpointSlice
```
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
ingress-conformance-echo-8bcrv IPv4 3000 10.244.0.156,10.244.0.157 18h
ingress-conformance-echo-dr6d2 IPv4 3000 10.244.0.158,10.244.0.159 18h
ingress-conformance-echo-dt27v IPv4 3000 10.244.0.153,10.244.0.154 2d14h
ingress-conformance-echo-l2j48 IPv4 3000 10.244.0.10,10.244.0.155 3d
ingress-conformance-echo-z4bcw IPv4 3000 10.244.0.160,10.244.0.161 18h
```

#### EndpointSlice cache

Because of the above mentioned differences, there is a need to adapt the cache logic from `endpointtranslator.go` such as;

Instead of using `endpoints map[types.NamespacedName]*v1.Endpoints`, use the below format with a nested map `k,v` where `k` is the EndpointSlice name and the `v` is the EndpointSlice itself.

```go
type EndpointSliceCache struct {
endpointSlice: map[types.NamespacedName]map[string]*discoveryv1.EndpointSlice{},
}
```

The above structure lets us keep track of each EndpointSlice and change/update/delete an endpoint without shuffling all the existing endpoints.

#### EndpointSlice conditions
The EndpointSlice has information about the condition of the endpoint, namely, `ready`, `serving` and `terminating`. The EndpointSlice implementation will only support the `ready` condition.
This means that only pods with `ready` status will be considered since `ready` on the EndpointSlice maps to `ready` status on the pods. This also keep contour inline with the existing implementation.

refer [ready status](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/#ready)

#### FQDN Address types
FQDN address types on EndpointSlices will not be supported. Contour will continue to support `externalName` service types.

#### Disabled Mirroring
If a service has [endpoint mirroring](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/#endpointslice-mirroring) disabled, it will not be processed by Contour.

## Tests

To ensure the feature is well tested, this feature will have
- e2e tests
- unit tests
- daily build run with EndpointSlices enabled.

## Migration Plan

Once we have enough consensus on the correctness and performance, we can make the move to EndpointSlices permanent and deprecate use of endpoints. This can be a combination of daily builds, burn time and feedback from the community.


## Alternatives Considered

N/A
9 changes: 9 additions & 0 deletions examples/contour/01-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3384,6 +3384,15 @@ spec:
type: object
type: array
type: object
overloadMaxHeapSize:
description: 'OverloadMaxHeapSize defines the maximum heap memory
of the envoy controlled by the overload manager. When the value
is greater than 0, the overload manager is enabled, and when
envoy reaches 95% of the maximum heap size, it performs a shrink
heap operation, When it reaches 98% of the maximum heap size,
Envoy Will stop accepting requests. More info: https://projectcontour.io/docs/main/config/overload-manager/'
format: int64
type: integer
podAnnotations:
additionalProperties:
type: string
Expand Down
88 changes: 86 additions & 2 deletions examples/gateway/00-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ spec:
for each listener
rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol
== l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname
== l2.hostname : true)))'
== l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
required:
- gatewayClassName
- listeners
Expand Down Expand Up @@ -1718,7 +1718,7 @@ spec:
for each listener
rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol
== l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname
== l2.hostname : true)))'
== l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
required:
- gatewayClassName
- listeners
Expand Down Expand Up @@ -5845,6 +5845,48 @@ spec:
type: object
maxItems: 8
type: array
timeouts:
description: "Timeouts defines the timeouts that can be configured
for an HTTP request. \n Support: Extended \n "
properties:
backendRequest:
description: "BackendRequest specifies a timeout for an
individual request from the gateway to a backend. This
covers the time from when the request first starts being
sent from the gateway to when the full response has been
received from the backend. \n An entire client HTTP transaction
with a gateway, covered by the Request timeout, may result
in more than one call from the gateway to the destination
backend, for example, if automatic retries are supported.
\n Because the Request timeout encompasses the BackendRequest
timeout, the value of BackendRequest must be <= the value
of Request timeout. \n Support: Extended"
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
request:
description: "Request specifies the maximum duration for
a gateway to respond to an HTTP request. If the gateway
has not been able to respond before this deadline is met,
the gateway MUST return a timeout error. \n For example,
setting the `rules.timeouts.request` field to the value
`10s` in an `HTTPRoute` will cause a timeout if a client
request is taking longer than 10 seconds to complete.
\n This timeout is intended to cover as close to the whole
request-response transaction as possible although an implementation
MAY choose to start the timeout after the entire request
stream has been received instead of immediately after
the transaction is initiated by the client. \n When this
field is unspecified, request timeout behavior is implementation-specific.
\n Support: Extended"
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
x-kubernetes-validations:
- message: backendRequest timeout cannot be longer than request
timeout
rule: '!(has(self.request) && has(self.backendRequest) &&
duration(self.request) != duration(''0s'') && duration(self.backendRequest)
> duration(self.request))'
type: object
x-kubernetes-validations:
- message: RequestRedirect filter must not be used together with
Expand Down Expand Up @@ -8244,6 +8286,48 @@ spec:
type: object
maxItems: 8
type: array
timeouts:
description: "Timeouts defines the timeouts that can be configured
for an HTTP request. \n Support: Extended \n "
properties:
backendRequest:
description: "BackendRequest specifies a timeout for an
individual request from the gateway to a backend. This
covers the time from when the request first starts being
sent from the gateway to when the full response has been
received from the backend. \n An entire client HTTP transaction
with a gateway, covered by the Request timeout, may result
in more than one call from the gateway to the destination
backend, for example, if automatic retries are supported.
\n Because the Request timeout encompasses the BackendRequest
timeout, the value of BackendRequest must be <= the value
of Request timeout. \n Support: Extended"
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
request:
description: "Request specifies the maximum duration for
a gateway to respond to an HTTP request. If the gateway
has not been able to respond before this deadline is met,
the gateway MUST return a timeout error. \n For example,
setting the `rules.timeouts.request` field to the value
`10s` in an `HTTPRoute` will cause a timeout if a client
request is taking longer than 10 seconds to complete.
\n This timeout is intended to cover as close to the whole
request-response transaction as possible although an implementation
MAY choose to start the timeout after the entire request
stream has been received instead of immediately after
the transaction is initiated by the client. \n When this
field is unspecified, request timeout behavior is implementation-specific.
\n Support: Extended"
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
x-kubernetes-validations:
- message: backendRequest timeout cannot be longer than request
timeout
rule: '!(has(self.request) && has(self.backendRequest) &&
duration(self.request) != duration(''0s'') && duration(self.backendRequest)
> duration(self.request))'
type: object
x-kubernetes-validations:
- message: RequestRedirect filter must not be used together with
Expand Down
9 changes: 9 additions & 0 deletions examples/render/contour-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3603,6 +3603,15 @@ spec:
type: object
type: array
type: object
overloadMaxHeapSize:
description: 'OverloadMaxHeapSize defines the maximum heap memory
of the envoy controlled by the overload manager. When the value
is greater than 0, the overload manager is enabled, and when
envoy reaches 95% of the maximum heap size, it performs a shrink
heap operation, When it reaches 98% of the maximum heap size,
Envoy Will stop accepting requests. More info: https://projectcontour.io/docs/main/config/overload-manager/'
format: int64
type: integer
podAnnotations:
additionalProperties:
type: string
Expand Down
Loading

0 comments on commit bedcc67

Please sign in to comment.