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: Service APIs implementation #3213

Merged
merged 11 commits into from
Feb 5, 2021

Conversation

youngnick
Copy link
Member

This is a WIP of the Service APIs implementation. It's been slow going, as I've been trying to check as I went that I've got the Service APIs intent correct, and that the way we'll implement is relatively consistent with Contour's current state.

Interested mostly in feedback on the high-level parts, did I miss anything?

There's quite a bit more detail required, particular for HTTPRoute and TLSRoute.

Very interested to hear about any other areas you all think I should cover as part of this design.

@youngnick youngnick changed the title design: Service APIs implementaton [WIP] design: Service APIs implementaton Dec 17, 2020
@youngnick youngnick changed the title [WIP] design: Service APIs implementaton [WIP] design: Service APIs implementation Dec 17, 2020
@codecov
Copy link

codecov bot commented Dec 17, 2020

Codecov Report

Merging #3213 (9c60cd8) into main (54e2d14) will increase coverage by 0.04%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3213      +/-   ##
==========================================
+ Coverage   75.30%   75.35%   +0.04%     
==========================================
  Files          98       98              
  Lines        6249     6249              
==========================================
+ Hits         4706     4709       +3     
+ Misses       1436     1433       -3     
  Partials      107      107              
Impacted Files Coverage Δ
internal/k8s/log.go 69.56% <0.00%> (+6.52%) ⬆️

@youngnick youngnick mentioned this pull request Dec 21, 2020
6 tasks
@github-actions
Copy link

github-actions bot commented Jan 1, 2021

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 Jan 1, 2021
@stevesloka stevesloka removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jan 5, 2021
Copy link
Member

@stevesloka stevesloka left a comment

Choose a reason for hiding this comment

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

What also do we do with things like:

  • web sockets
  • timeouts
  • wildcard domain names (from api spec notes)
  • regex headers
  • exact path match type (also needed in ingress v1 support)


In terms of its stated goals, Contour is aiming at being an ingress controller - that is, a Layer 7 proxy with some api gateway functions.
Currently, Contour provides "TCP Proxying" that allows the forwarding of TLS streams based on the SNI information, which is precisely what the Service APIs TLSRoute object is for.
If Project Contour (the organisation) does add support for TCP and UDP forwarding, it will not be in the `projectcontour/contour` repo, but will be a separate repo.
Copy link
Member

Choose a reason for hiding this comment

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

I'm still confused on the practically of this, you're proposing that we recreate all the same logic to just watch for these two types (e.g. TCP / UDP)?

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'd guess that as part of this, we'd spin some code out into libraries, probably.

Contour expects the `spec.addresses` field to be empty.

For Listeners:
- Listeners inside Gateways will be merged where possible, as will listeners across Gateways.
Copy link
Member

Choose a reason for hiding this comment

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

Contour only supports two listeners today (e.g. http/https). Does this statement assume that you are permitted to create more dynamically?

Copy link
Member Author

Choose a reason for hiding this comment

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

The insecure/secure split definitely needs some thinking as a result of this. The initial thought is that we would replicate the current behavior, which would mean accepting only one http and one https listener, but this will be tricky to do. We may need to do something different with automatic http->https redirect for the Service APIs.

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 opened #3263 with a new design for this, and will update this document accordingly.

design/service-apis-implementation.md Outdated Show resolved Hide resolved
@danehans
Copy link
Contributor

danehans commented Jan 5, 2021

design/service-apis-implementation.md Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
@youngnick
Copy link
Member Author

In the latest round of changes, I've updated a few things:

  • change the model that Contour only looks at a single Gateway (since it's part of the implementation of that specific Gateway).
  • Contour is configured with the full name (name and namespace) of the Gateway.
  • Added references to design: Add design for multiple Envoy listeners #3263 and updated the design assuming it's going ahead. If not, this is still doable, just will require extra rules for Listener merging.

Comment on lines +64 to +84
### Combining Service APIs with other configuration

When it calculates the Envoy configuration using the DAG, Contour layers different types of configuration in order.
So, currently, Ingress is overwritten by HTTPProxy, so if an Ingress and a HTTPProxy specify the exact same route, the HTTPProxy will win.

Once we have the Service-APIs available as well, we have to choose the order.
In this design, I suggest having the order be Ingress is overwritten by HTTPProxy, is overwritten by the service-apis.
I could see reversing HTTPProxy and the Service APIs here, but I think this acknowledges that the Service APIs are really an evolution of the ideas in HTTPProxy, and will probably end up being the community standard.
Copy link
Member

Choose a reason for hiding this comment

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

I'm OK with either order, as long as we document it.

design/service-apis-implementation.md Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
design/service-apis-implementation.md Outdated Show resolved Hide resolved
design/service-apis-implementation.md Show resolved Hide resolved
@youngnick
Copy link
Member Author

To answer @stevesloka's question about additional features, I've also put some more in the documentation about what parts of the API we will target, and how we will build support.

In short, we'll build whatever is in v1alpha1 in the initial cut, then work with the upstream to define the other features (timeouts, websockets, regex headers etc) in the upstream, and support that.

stevesloka added a commit to stevesloka/contour that referenced this pull request Jan 27, 2021
stevesloka added a commit to stevesloka/contour that referenced this pull request Jan 27, 2021
The service-apis design calls out that GatewayClasses won't be watch or processed by Contour the controller,
so this removes them from processing since they won't be used.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
stevesloka added a commit to stevesloka/contour that referenced this pull request Jan 27, 2021
The service-apis design calls out that GatewayClasses & TCPRoutes won't be watched
or processed by Contour the controller, so this removes them from processing since
they won't be used.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
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 don't have any other significant feedback here, I think this points us in the right direction. I'd be OK working out the remaining details of processing objects in code, especially given the alpha status of the API.

design/service-apis-implementation.md Show resolved Hide resolved
@stevesloka
Copy link
Member

I don't have any additional large comments. There are a lot of behavior details in the API spec which we'll also need to reference during implementation.

There are still quite a few TODO's throughout the doc that will need another review pass from folks if they are expaned upon.

Thanks for this work @youngnick!

skriss pushed a commit that referenced this pull request Jan 28, 2021
…#3279)

The service-apis design calls out that GatewayClasses & TCPRoutes won't be watched
or processed by Contour the controller, so this removes them from processing since
they won't be used.

Updates #3213

Signed-off-by: Steve Sloka <[email protected]>
stevesloka added a commit to stevesloka/contour that referenced this pull request Jan 28, 2021
stevesloka added a commit that referenced this pull request Feb 3, 2021
Contour considers a Gateway to describe a single Envoy deployment, deployed and managed by something outside of itself.
Contour expects to be supplied with the full name (name and namespace) of a single Gateway, which it will watch and update the status of.
This will be a configuration file parameter.
When a Gateway is not supplied, Contour will not do Service-APIs processing, or in other words, the existing `--experimental-service-apis` flag will be obsoleted and removed).
Copy link
Member

Choose a reason for hiding this comment

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

+1 on removing the flag.

Should we default the name/namespace of a gateway (i.e. contour/projectcontour) so given a generic deployment, someone could use that as a default and not require a config file change?

Contour can still check if the service-apis CRDs exist in the cluster and use that as a key for setting up informers. I just merged #3283 which acts this way, but is different than this design doc, but @skriss asked which is a good point.

Copy link
Member Author

Choose a reason for hiding this comment

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

So, the flow if you want to use the service-apis is this:

  • install the objects in the cluster
  • create a Gateway for Contour to reference
  • Configure Contour to use that

If you don't do all those three things, then no service-apis.

That does make sense, although it means that if you install the objects and don't change the default, we should end up logging something saying "hey, you asked me to look for a Gateway called projectcontour/contour, but it doesn't exist". Not a huge deal.

Copy link
Member

Choose a reason for hiding this comment

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

Right now I have a default programmed, but we could remove that, just thought it might be nice to have some way of allowing someone to create a Gateway without needing to reconfigure / restart Contour.

This came up in a review with @skriss and thought it was a good point that what I PR'd conflicted with this design and thought we should clear up. =)


Contour will only ever update the `status` of HTTPRoute objects.

Errors or conflicts here will render that section of the config invalid.
Copy link
Member

Choose a reason for hiding this comment

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

For a missing serviceName or LocalObjectReference, the docs say:

If the referent cannot be found, the route must be dropped from the Gateway. The controller should raise the “ResolvedRefs” condition on the Gateway with the “DegradedRoutes” reason. The gateway status for this route should be updated with a condition that describes the error more specifically.

Does that mean the entire HTTPRoute is invalid or just the specific HTTPRoute.HTTPRouteRule is invalid?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I wasn't sure about that either (and how it would play with the proposal you had around keeping as much routability as possible even in partially applied resources), I think we chatted about this in office hours or something but I'm not sure there was a conclusion

Copy link
Member Author

@youngnick youngnick Feb 4, 2021

Choose a reason for hiding this comment

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

You're right, I think we need to implement this per the spec for now, and raise this upstream as a concern. I'll update to reflect this.

Copy link
Member

Choose a reason for hiding this comment

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

Chatting in Slack the thought is that only that HTTPRoute.Rule is invalidated so I think the design is correct unless we want to specifically call it out better: https://kubernetes.slack.com/archives/CR0H13KGA/p1612463856030500?thread_ts=1612459180.030400&cid=CR0H13KGA

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for asking this question in the upstream Slack @stevesloka. I agree with Harry's answer there - we will implement this as "conflicts will invalidate that rule" not "conflicts with invalidate the whole Route" for now, and see if we can push that upstream.

stevesloka added a commit to stevesloka/contour that referenced this pull request Feb 3, 2021
Deprecate the '--experimental-service-apis' flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
Comment on lines +77 to +84
### Combining Service APIs with other configuration

When it calculates the Envoy configuration using the DAG, Contour layers different types of configuration in order.
So, currently, Ingress is overwritten by HTTPProxy, so if an Ingress and a HTTPProxy specify the exact same route, the HTTPProxy will win.

Once we have the Service-APIs available as well, we have to choose the order.
In this design, I suggest having the order be Ingress is overwritten by HTTPProxy, is overwritten by the service-apis.
I could see reversing HTTPProxy and the Service APIs here, but I think this acknowledges that the Service APIs are really an evolution of the ideas in HTTPProxy, and will probably end up being the community standard.
Copy link
Member

Choose a reason for hiding this comment

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

Some aspects of this are not entirely clear to me, e.g. what if there's a service-apis Listener with a wildcard domain name that overlaps with an HTTPProxy with a specific domain name, or what if some other service-apis Listener settings conflict with Contour's listener settings -- but I'm also not sure it's that important right now, and we can figure it out during 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 think the wildcard domain name thing will be sorted out by implementing wildcard domains everywhere - we should do that before starting with this, since we need to do it for Ingress v1 anyway. I think the limited form of wildcard FQDN defined in the service-apis is probably implementable in HTTPProxy as well.

I think the LIstener settings details should be sorted out during implementation, but I think that the service-apis spec should probably override the Contour config one, since it's more specific (I think). I don't think it matters really, as long as we document it.

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.

no further comments/questions from me, I think we can sort out remaining details during implementation. 🎉

Copy link
Member

@stevesloka stevesloka left a comment

Choose a reason for hiding this comment

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

I think this is good enough to start implementation and dig into what comes out of that when we hit those bits. 🎉

@youngnick youngnick force-pushed the service-apis-design branch from 90ab2f9 to 8060741 Compare February 4, 2021 23:54
@youngnick
Copy link
Member Author

Looks like the new ExternalName integration test is failing on main, I'm going to merge this design, and take a look.

@youngnick youngnick merged commit ff8768d into projectcontour:main Feb 5, 2021
stevesloka added a commit to stevesloka/contour that referenced this pull request Feb 5, 2021
Deprecate the '--experimental-service-apis' flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
skriss pushed a commit to abhide/contour that referenced this pull request Feb 8, 2021
…contour#3311)

Deprecate the `--experimental-service-apis` flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
iyacontrol pushed a commit to iyacontrol/contour that referenced this pull request Feb 18, 2021
* Add design document for service-apis implementation.

Signed-off-by: Nick Young <[email protected]>
Signed-off-by: iyacontrol <[email protected]>
iyacontrol pushed a commit to iyacontrol/contour that referenced this pull request Feb 18, 2021
…contour#3311)

Deprecate the `--experimental-service-apis` flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
Signed-off-by: iyacontrol <[email protected]>
iyacontrol pushed a commit to iyacontrol/contour that referenced this pull request Feb 23, 2021
* Add design document for service-apis implementation.

Signed-off-by: Nick Young <[email protected]>
Signed-off-by: iyacontrol <[email protected]>
iyacontrol pushed a commit to iyacontrol/contour that referenced this pull request Feb 23, 2021
…contour#3311)

Deprecate the `--experimental-service-apis` flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
Signed-off-by: iyacontrol <[email protected]>
iyacontrol pushed a commit to iyacontrol/contour that referenced this pull request Feb 23, 2021
…contour#3311)

Deprecate the `--experimental-service-apis` flag to `contour serve` in favor of using the gateway.name & gateway.namespace config file options.

Updates projectcontour#3213

Signed-off-by: Steve Sloka <[email protected]>
Signed-off-by: iyacontrol <[email protected]>
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants