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

design: Add design for multiple Envoy listeners #3263

Closed

Conversation

youngnick
Copy link
Member

As part of implementing Service APIs, it's necessary to reconsider Contour's insecure to secure redirect functionality.
This document suggests keeping the functionality, while allowing additional listening ports to be defined.

Updates #1300
Updates #2922
Updates #3086

Blocks #3213 until we decide one way or another.

Signed-off-by: Nick Young ynick@vmware.com

As part of implementing Service APIs, it's necessary to reconsider Contour's insecure to secure redirect functionality.
This document suggests keeping the functionality, while allowing additional listening ports to be defined.

Updates projectcontour#1300
Updates projectcontour#2922
Updates projectcontour#3086

Signed-off-by: Nick Young <ynick@vmware.com>
@youngnick youngnick requested a review from a team as a code owner January 19, 2021 00:46
@youngnick youngnick requested review from jpeach and sunjayBhatia and removed request for a team January 19, 2021 00:46
@codecov
Copy link

codecov bot commented Jan 19, 2021

Codecov Report

Merging #3263 (080bce2) into main (3d41d1d) will increase coverage by 2.43%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3263      +/-   ##
==========================================
+ Coverage   75.41%   77.84%   +2.43%     
==========================================
  Files          96      103       +7     
  Lines        5963     9024    +3061     
==========================================
+ Hits         4497     7025    +2528     
- Misses       1366     1865     +499     
- Partials      100      134      +34     
Impacted Files Coverage Δ
internal/k8s/scheme.go 71.42% <0.00%> (-8.58%) ⬇️
internal/dag/accessors.go 89.56% <0.00%> (-3.92%) ⬇️
internal/xdscache/v3/route.go 87.76% <0.00%> (-3.62%) ⬇️
internal/k8s/objectmeta.go 88.57% <0.00%> (-2.34%) ⬇️
internal/envoy/route.go 84.61% <0.00%> (-1.75%) ⬇️
internal/k8s/status.go 9.80% <0.00%> (-1.63%) ⬇️
internal/envoy/v3/bootstrap.go 91.02% <0.00%> (-1.21%) ⬇️
internal/envoy/v3/route.go 98.94% <0.00%> (-1.06%) ⬇️
internal/metrics/metrics.go 84.45% <0.00%> (-0.50%) ⬇️
internal/xdscache/v3/listener.go 94.72% <0.00%> (-0.42%) ⬇️
... and 43 more

@youngnick
Copy link
Member Author

youngnick commented Jan 19, 2021

I've opened this one because I think that the Gateway object in Service-APIs implies that we should allow the creation of extra Listeners. We also have outstanding requests for similar functionality.

I'm going to say again though, that although this allows you to forward some traffic on an arbitrary port at Layer 4, I don't believe this is "Adding layer 4 load balancing to Contour". It's missing large swaths of functionality for that (most importantly, the ability to choose your serving IP), and is heavily dependent on your Envoy being configured correctly (trying to bind to ports under 1024 will fail if your container is not running, and so on).

I'm working on adding this detail to the Detailed Design section, but wanted to get some feedback on the high-level design asap.

@youngnick youngnick marked this pull request as draft January 19, 2021 00:56
Signed-off-by: Nick Young <ynick@vmware.com>
@@ -0,0 +1,111 @@
# Automatic redirection with arbitrary listeners

Status: Accepted
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we've done for other current designs, setting this to Accepted because it won't be merged unless it is accepted.


### HTTPProxy processing

For HTTPProxy resources, Contour will add an optional `port` field to the `virtualhost` YAML stanza, which matches the externally visible port for the Envoys.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to discussion on the name here, as it's the translated port. Not sure if that means we should give it a different name, or if we should just be very clear in the documentation what port we are talking about.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just not add to HTTPProxy at first revisit the extra overhead later?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seemed better to me that if we're going to add the functionality, we should add it into HTTPProxy first, while we do the rest of the Service APIs design, then it's easier to just consume it.

- port set
- TLS details set - any port other than the external version of the secure or insecure ports, allow. A new listener will be created if it doesn't exist. No redirection created for you.
- TLS details set - port is the external version of the secure or insecure ports - treat as though no port was set. Redirection will be created.
- no TLS details set - any port other than the insecure or secure ports, allow. A new listener will be created if one doesn't exist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add some detail around here or the detailed design section about what will happen if a port is set but it conflicts with an existing listener?

e.g.

  • existing HTTPProxy that asks to listen on port 9000 with no TLS details set
    • gets Envoy listener + filter chain with plaintext transport socket
  • new HTTPProxy (different vhost) that asks to listen on port 9000 with TLS details set
    • TLS transport socket would conflict with plaintext transport socket

With Service APIs this configuration would be "not mergeable", seems the port in addition to vhost could be a uniqueness constraint to add onto HTTPProxy resources if I'm understanding correctly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a great point, thanks Sunjay. Currently any two HTTPProxy objects that match on vhost name render both proxies invalid. We will need to extend that to ports as well, there are some cases around what to do with mixed port/no port configurations that match on vhosts as well. That is definitely something for the detailed design section.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a small note in here about the uniqueness constraint, but I think further detail is for the detailed design section.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to this, you could have conflicts across different APIs, e.g. an HTTPProxy conflicts with a Gateway.

design/multiple-listeners-design.md Outdated Show resolved Hide resolved
Currently, Contour allows the configuration of the secure and insecure listening ports for Envoy using the `--envoy-service-https-port` and the `--envoy-service-http-port` parameters respectively.
(It's fair to say that these parameters are confusingly named).

These will also be exposed in the configuration file as `secureListenerPort` and `insecureListenerPort` respectively.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like the service-api spec should be able to define this and not rely on the implementation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't disagree, but don't want to block this on waiting for upstream.

design/multiple-listeners-design.md Outdated Show resolved Hide resolved
Currently, Contour allows the configuration of the secure and insecure listening ports for Envoy using the `--envoy-service-https-port` and the `--envoy-service-http-port` parameters respectively.
(It's fair to say that these parameters are confusingly named).

These will also be exposed in the configuration file as `secureListenerPort` and `insecureListenerPort` respectively.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also use a convention that the service port named http will be the insecure port, the port named https will be the secure. This removes the need for the extra config options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the service APIs though, the ports don't have names. So it would need to be "the first port with protocol: HTTP" or something. I thought it was clearer to put the behavior in Contour, which allows us to backport it to HTTPProxy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The k8s service has names and the design says we're going to watch them, so given that you can match up the port name in the service to a port on a listener.


### HTTPProxy processing

For HTTPProxy resources, Contour will add an optional `port` field to the `virtualhost` YAML stanza, which matches the externally visible port for the Envoys.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just not add to HTTPProxy at first revisit the extra overhead later?

design/multiple-listeners-design.md Outdated Show resolved Hide resolved
@danehans
Copy link
Contributor

xref: projectcontour/contour-operator#151 (operator network publishing API)

Signed-off-by: Nick Young <ynick@vmware.com>
with "externally visible secure port" meaning "whatever port an external user will go to to get to the secure port",
and similarly for the "externally visible insecure port".

Importantly, pecifying a port for Envoy's secure or insecure listening port that does not match the a port on the Service will be a fatal error for Contour.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/pecifying/specifying/

Copy link
Member

@skriss skriss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this proposal, though I think I'd also be fine saying that for our initial service-apis implementation, we only support two listeners (one http, one https) just like Contour works today, and any additional ones would be errors; then we could tackle this later. IOW, I'm not seeing that this has to be a prereq for an initial service-apis implementation, especially given the alpha state of the API.

design/multiple-listeners-design.md Show resolved Hide resolved
@youngnick youngnick mentioned this pull request Jan 28, 2021
@skriss skriss added the kind/design Categorizes issue or PR as related to design. label Feb 1, 2021
@youngnick
Copy link
Member Author

I'm going to leave this open for now, it will be easy to rebase later, and I think we should look at this again soon (once we have some basic Service-APIs support).

@stevesloka
Copy link
Member

@cten this was the listeners design doc if you had anything to add. =)

@github-actions
Copy link

Marking this PR stale since there has been no activity for 14 days. It will be closed if there is no activity for another 90 days.

@github-actions github-actions bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Feb 20, 2021
@nak3
Copy link
Member

nak3 commented Mar 4, 2021

The additional arbitrary port listeners makes it possible to select one envoy by 2 private (ClusterIP) and public (LoadBalancer) services.
Knative currently deploys two envoy for private and private access, but we would like to use only one envoy with 2 services like this https://gist.github.com/danehans/c19b56fcef6219c6bf1af419fc8ead4e#file-gistfile1-txt (Thanks @danehans).
So, we want this feature not only for Gateway API support but also even now 😄

@nak3
Copy link
Member

nak3 commented May 20, 2021

I think this issue is still not solved so is it alright to re-open?

@youngnick youngnick reopened this May 21, 2021
@youngnick
Copy link
Member Author

We can leave it open; I suspect we will need it sooner than I thought.

@moizrassiwala
Copy link

Is this available yet?

@youngnick
Copy link
Member Author

No, this design has not been finished. As I said earlier, I think we still need it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/design Categorizes issue or PR as related to design. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants