Skip to content

Commit

Permalink
Add support for using gateway.spec.addresses as service external ips (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnh2 authored Apr 27, 2023
1 parent 12aa0ad commit 85e61d2
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 3 deletions.
3 changes: 0 additions & 3 deletions docs/latest/design/gatewayapi-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ When a [Gateway][] resource is created that references the managed GatewayClass,
new Envoy Proxy deployment. Gateway API resources that reference this Gateway will configure this managed Envoy Proxy
deployment.

__Note:__ Envoy Gateway does not support specifying an [address][] for the Gateway.

## HTTPRoute

An [HTTPRoute][] configures routing of HTTP traffic through one or more Gateways. The following HTTPRoute filters are
Expand Down Expand Up @@ -99,7 +97,6 @@ these types of cross-namespace references. Envoy Gateway supports the following
[GatewayClass]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.GatewayClass
[parameters reference]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.ParametersReference
[Gateway]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.Gateway
[address]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.GatewayAddress
[HTTPRoute]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute
[Service]: https://kubernetes.io/docs/concepts/services-networking/service/
[BackendRef]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.BackendRef
Expand Down
65 changes: 65 additions & 0 deletions docs/latest/user/gateway-address.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Gateway Address

The Gateway API provides an optional [Addresses][] field through which Envoy Gateway can set addresses for Envoy Proxy Service. The currently supported addresses are:

- [External IPs](#External-IPs)

## Installation

Install Envoy Gateway:

```shell
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace
```

Wait for Envoy Gateway to become available:

```shell
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
```

## External IPs

Using the addresses in `Gateway.Spec.Addresses` as the [External IPs][] of Envoy Proxy Service, this will __require__ the address to be of type `IPAddress`.

Install the GatewayClass, Gateway from quickstart:

```shell
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n default
```

Set the address of the Gateway, the address settings here are for reference only:

```shell
kubectl patch gateway eg --type=json --patch '[{
"op": "add",
"path": "/spec/addresses",
"value": [{
"type": "IPAddress",
"value": "1.2.3.4"
}]
}]'
```

Verify the Gateway status:

```shell
kubectl get gateway

NAME CLASS ADDRESS PROGRAMMED AGE
eg eg 1.2.3.4 True 14m
```

Verify the Envoy Proxy Service status:

```shell
kubectl get service -n envoy-gateway-system

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
envoy-default-eg-64656661 LoadBalancer 10.96.236.219 1.2.3.4 80:31017/TCP 15m
envoy-gateway ClusterIP 10.96.192.76 <none> 18000/TCP 15m
envoy-gateway-metrics-service ClusterIP 10.96.124.73 <none> 8443/TCP 15m
```

[Addresses]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.GatewayAddress
[External IPs]: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
1 change: 1 addition & 0 deletions docs/latest/user_docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ Learn how to deploy, use, and operate Envoy Gateway.
user/egctl
user/customize-envoyproxy
user/deployment-mode
user/gateway-address
32 changes: 32 additions & 0 deletions internal/gatewayapi/address.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package gatewayapi

import (
"sigs.k8s.io/gateway-api/apis/v1beta1"
)

var _ AddressesTranslator = (*Translator)(nil)

type AddressesTranslator interface {
ProcessAddresses(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources)
}

func (t *Translator) ProcessAddresses(gateways []*GatewayContext, xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources) {
for _, gateway := range gateways {
// Infra IR already exist
irKey := irStringKey(gateway.Gateway)
gwInfraIR := infraIR[irKey]

var ipAddr []string
for _, addr := range gateway.Spec.Addresses {
if *addr.Type == v1beta1.IPAddressType {
ipAddr = append(ipAddr, addr.Value)
}
}
gwInfraIR.Proxy.Addresses = ipAddr
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: tcp
protocol: TCP
port: 80
addresses:
- type: IPAddress
value: 1.2.3.4
- type: IPAddress
value: 5.6.7.8
- type: Hostname
value: foo.bar
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: tcp
protocol: TCP
port: 80
addresses:
- type: IPAddress
value: 1.2.3.4
- type: IPAddress
value: 5.6.7.8
- type: Hostname
value: foo.bar
status:
listeners:
- name: tcp
supportedKinds:
- group: gateway.networking.k8s.io
kind: TCPRoute
conditions:
- type: Programmed
status: "True"
reason: Programmed
message: Sending translated listener configuration to the data plane
- type: Accepted
status: "True"
reason: Accepted
message: Listener has been successfully translated
xdsIR:
envoy-gateway-gateway-1: {}
infraIR:
envoy-gateway-gateway-1:
proxy:
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway-gateway-1
listeners:
- address: ""
ports:
- name: tcp
protocol: TCP
servicePort: 80
containerPort: 10080
addresses:
- 1.2.3.4
- 5.6.7.8
4 changes: 4 additions & 0 deletions internal/gatewayapi/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type TranslatorManager interface {

RoutesTranslator
ListenersTranslator
AddressesTranslator
FiltersTranslator
}

Expand Down Expand Up @@ -119,6 +120,9 @@ func (t *Translator) Translate(resources *Resources) *TranslateResult {
// Process all Listeners for all relevant Gateways.
t.ProcessListeners(gateways, xdsIR, infraIR, resources)

// Process all Addresses for all relevant Gateways.
t.ProcessAddresses(gateways, xdsIR, infraIR, resources)

// Process all relevant HTTPRoutes.
httpRoutes := t.ProcessHTTPRoutes(resources.HTTPRoutes, gateways, resources, xdsIR)

Expand Down
3 changes: 3 additions & 0 deletions internal/infrastructure/kubernetes/proxy/resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,12 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
if envoyServiceConfig.Annotations != nil {
annotations = envoyServiceConfig.Annotations
}

// Set the spec of gateway service
serviceSpec := resource.ExpectedServiceSpec(envoyServiceConfig.Type)
serviceSpec.Ports = ports
serviceSpec.Selector = resource.GetSelector(labels).MatchLabels
serviceSpec.ExternalIPs = r.infra.Addresses

svc := &corev1.Service{
TypeMeta: metav1.TypeMeta{
Expand Down
3 changes: 3 additions & 0 deletions internal/ir/infra.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type ProxyInfra struct {
Config *v1alpha1.EnvoyProxy
// Listeners define the listeners exposed by the proxy infrastructure.
Listeners []ProxyListener
// Addresses contain the external addresses this gateway has been
// requested to be available at.
Addresses []string
}

// InfraMetadata defines metadata for the managed proxy infrastructure.
Expand Down
5 changes: 5 additions & 0 deletions internal/ir/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions internal/status/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func UpdateGatewayStatusProgrammedCondition(gw *gwapiv1b1.Gateway, svc *corev1.S
}
}

addresses = append(addresses, svc.Spec.ExternalIPs...)

var gwAddresses []gwapiv1b1.GatewayAddress
for i := range addresses {
addr := gwapiv1b1.GatewayAddress{
Expand Down

0 comments on commit 85e61d2

Please sign in to comment.