 Hey, everyone. Thanks for joining us on a primer on Gateway API extensions. My name is Damian Hansen. I'm a software engineer with Solo.io. I've been involved with Gateway API either as a maintainer, a contributor, or an implementer since the project's inception. Hey, everyone. My name is Sanjay Bhatia. I'm a software engineer at VMware, and I'm a maintainer of the Contour Ingress Controller and a contributor to Gateway API. So what is Gateway API? Gateway API is a project that's managed by the SIG network community within Kubernetes, and it is a collection of resources used to describe service routing within Kubernetes. And it is the next generation of Kubernetes routing and load balancing APIs. You may ask yourself, what's the next generation about Gateway API? Gateway API supports a ton of different protocols from GRPC, PLS, of course, HTTP, Layer 4 protocols. The protocol support continues to evolve within the project. It can perform advanced traffic routing. This could be routing across different namespaces or based on information within the request if it's a header, and not only the request, but also the response as well. So Gateway API allows us to do a lot of really cool, fun things for routing traffic within Kubernetes cluster or into or outside of our Kubernetes cluster. And I mentioned that Gateway API is a collection of resources. There are some core resources that we want to talk about in more detail here. There is the Gateway class resource. The Gateway class resource represents a set or a collection of gateways that have a common configuration and behavior. You could think of a gateway class that's called internet-facing that would include all gateways that are exposed outside to the public internet, while another gateway class called internal would only be for internal communication and not exposed outside of your trust domain, for example. And so beyond the Gateway class, we have a gateway. This is a resource that actually is the core of Gateway API. So the gateway resource is what actually instantiates the infrastructure used to perform these operations. So typical implementations of a gateway would be a load balancer or a proxy. And when you create a gateway behind the scenes, there is a controller that's responsible for watching and reconciling a gateway that then goes ahead and instantiates that infrastructure, creates the proxy or the load balancer, maybe it creates a Kubernetes service that allows requests to the gateway to be load balanced across a series of gateways. And then we have routes. In this example, we see the HTTP route that's used to route requests that match traffic for a particular gateway. And you see the lines that go in between all these that represents how these different resources are interrelated. So when you create a route, you attach a route to a gateway. When you create a gateway, you tell the gateway that it's part of a particular gateway class, and that becomes a relationship between these resources. And then last but not least, we talk about the gateway being a piece of infrastructure within a gateway class and HTTP route being configuration to tell the gateway where to go ahead and send that request, but ultimately that request needs to go to something. Typically, it's a service that's within the route, it's represented as a backend, but it doesn't necessarily have to be a service. And we'll talk through some examples here as we move forward through some of these slides. So we talked briefly about the different core resources and what gateway API is at a high level. But let's dive into a little bit more about the extensibility and really talk about extensibility for gateway API. We need to understand a concept of feature support levels. So features are expressed through maybe fields of a resource or a particular resource, and the different resources and fields actually have different support levels. And so if a field or resources considered core support, that means that all implementations that are conformant to gateway API must support the resource, the fields within the resource if it's considered core as well. And here's an example of a core resource, right? Gateway is a core resource, and this gateway defines core fields. A gateway class name, right? What gateway class is this gateway a member of? And then a listener. This is an HTTP listener that's specified the name, a protocol, and a TCP port to expose on the gateway. And these are all core fields. So no matter what the implementation is for gateway API, it must support these fields. And that ensures that users of these APIs that allows you to that portability, right? To be able to go between implementations and know that you're going to get the expected behavior. So now the next support level is extended. And what this means is an implementation doesn't necessarily have to support an extended feature, but if it does, that it must support the feature per the specification. And here's a few examples of extended features, right? So you can go ahead and use the address field to specify a type of address and the value for that address type. Or more likely you would go ahead and you'd create a filter within your HTTP route or your route resource that performs some kind of operation on that request. And in this example, the URL rewrite filter is an extended filter, although gateway API has route filters that are core. And leading into extensions, implementation specific features, they are not portable. They are not part of the gateway API release. So the types for these implement implementation specific features, those types are not part of the Go types that are specified within the project. What the project does instead is it has these extension points that reference an object, right? In this example, we see that it's the gateway class parameters ref that's referencing an object. And when we reference an object, it's by group, kind, and name. I can also include a namespace. We'll talk a little bit more about referencing resources across namespaces. And in this example, we use that parameters ref extension point to expose configuration through a custom resource that we as an implementer would be responsible for support. And again, since it is implementation specific, it's not portable across implementations, hence the name implementation specific. But in this example, we see that the my config resource is used to create an address pool. And I would expect that this implementation uses this address pool that when gateways are instantiated from this gateway class, that the implementation has a controller that assigns addresses from this pool to those gates. So you see in the examples that I provided for these extension points, typically it's a reference to a group and a kind and a name, right? And so that's a local object reference expecting that that resource that is being referred to is within the same namespace as the reference. But gateway API also provides that flexibility, right? Being able to balance both being secure by default saying that the reference has to be in the same namespace as the referring resource, but also providing the flexibility to say, you know what, I may need to reference a object that exists in a different namespace. And here's a perfect example, right? Having an HTTP route in one namespace that needs to refer to a service in a different namespace. And that's where the reference grant resource comes in. And the reference grant resource is a flexible resource that allows you to specify the to and from, right? So from what resource do you want to give a grant to reference for another resource? And of note, as you can see in this diagram, when you create a reference grant, you always want to put that reference grant in the namespace of the resource that's being referred to, right? And what that does is in the background, there's a controller that'd be watching the reference from the HTTP route to the service. And without the reference grant, the controllers say, no, sorry, would surface some kind of status condition in the HTTP route saying, yeah, you're, you know, invalid reference. But with the reference grant, the the implementations controller which would look and say, okay, if you're out, you're trying to reference service in back end namespace. This isn't a different namespace. But I see that there's a reference grant there that allows this. So I'm now going to allow that configuration to exist. And then, of course, requests that come through the gateway and will eventually go to the service in the back end namespace. And again, this reference grant resource provides that flexibility for Gateway API to allow that cross namespace reference. So hopefully this is starting to make a little sense to you. And this will allow us to dive a little bit deeper into the different extension points provided by Gateway API. The first that we'll talk about is the parameters ref within a Gateway class. I've already touched on that a few times. So we won't dive too deeply into it. But the parameters ref is used for exposing custom configuration. It's optional if you want to create gateways of a particular Gateway class and that Gateway class just has a controller name, no parameters ref. Then what's expected is those gateways would be instantiated with default configuration. But in typical environments, you're going to want to be able to have custom configuration if it's maybe some type of network publishing strategies to be able to say I want to use node ports or external load balancers for my gateways, all these kinds of things. That's just scratching the surface of the custom configuration that you can provide to your gateways. This is the extension point that you want to use. It doesn't necessarily have to be a custom resource. This could be a config map that's supported as a core support level. But what I've seen quite a bit in projects that I've been involved in is the desire to have typed configuration and not just a data blob within a config map. And that's typically where you see this parameters ref use. Gateway certificates provides another extension point for us to use. So we've already talked about what a gateway is. And so for gateways, they could terminate HTTPS, TLS traffic. And to do that, it needs to know about the TLS certificates and keys to do so. And by default, you can store these TLS certain keys in a secret and that's supported as a core support level for that feature. But if for some reason you have a use case that says, hey, can't store these certs or keys in Kubernetes secret, I need some other kind of resource. Gateway API provides that mechanism within the cert refs field. Again, local object reference, if you need to refer to this resource in another namespace, we need a reference grant and we specify namespace within certificate refs. And one point about that certificate ref is it doesn't, or the reference grant is, it doesn't necessarily need to be used with a custom resource, right? So if you have a secret in a different namespace, you could still use a reference grant and you don't have to specify the group in kind because it's inferred that it'd be a secret and it would just be the name and namespace. Route backends. So as part of a route, for example, HTTP route, that route is configuration to match traffic for Gateway to optionally do something with that traffic, modify it, transform it and such, and then eventually route that traffic to a backend such as a service, right? Well, we can do matching requests, I'm sorry here, we can go ahead and have a backend that's potentially not a service, right? And here we have an HTTP route backend named MyCubeService that refers to a service. This slide's actually incorrect, I apologize for that, they should say service and not secret, we'll fix that after the recording. But we can also specify some type of implementation specific resource. In this example, MyCustomBackend, this could be an AWS storage bucket, this could even be a multi cluster service, right? So if I don't want to route to a service within my cluster and I want to route it to a different cluster I could use, the Kubernetes multi cluster services has a back end as well. And then optionally routes, as I mentioned, can modify the traffic using filters. And this mechanism can be expressed at the rule level, or it can be expressed per back end, right? So if I want to go ahead and have a filter for all match traffic, do something to that traffic, let's say authenticate it first before sending it to the back end service, I would do it at the rule level, but if I say I just want to do it with for a particular back end, that's where we start, we can have filters as a field on a per back end basis. Now, an important distinction here is there are filters within Gateway API that are core or extended or again, even using the resource reference model for referring to implementation specific resources. But even if a core filter is expressed on a per back end basis, that filter is no longer considered core, it's considered extended. And then no matter where you express your implementation specific filter, either at the rule level or the back end level, that's always going to be implementation specific from a support level standpoint. But I just wanted to make sure you understand that distinction of using the core filters either at the rule level or the back end level. And typically what I see is filters being used at the rule level. I've already touched on this, that there's filters that are part of Gateway API at the core or extended level. Here's an example of the request header modifier filter. That's core. And then there's actually a response header modifier that's not core, that's extended. Or in this example, I say, hey, I want to actually authenticate those requests that are matched. And before forwarding the request to my back end service, I'm going to go ahead and have this my off filter be able to express all sorts of authentication configuration that my implementation would utilize to authenticate those requests before forwarding their quest onto the back end. So that provides an overview of some of the extension mechanisms for Gateway API. Hopefully that helps you kind of get that foundation set. And now I want to go ahead and hand it over to Sanjay to talk more about the additional extension types. Yeah, thank you, Daniel. So Daniel's talked about a lot of the extension mechanisms within Gateway API resources that allow you to refer to a custom configuration resource from within one of the Gateway API core resources. There's a few fields within these resources that also allow you to provide some custom configuration, particularly in the form of what you would call a domain prefixed string that you can use to provide some custom types or custom values. So for example, the Gateway address type, you can provide a custom domain prefix string to provide a implementation specific interpretation of that type there. In addition, the Gateway listener protocol can have a domain prefixed string to supply a custom protocol that your implementation may support. And similarly, passing TLS options for a Gateway listener, you can specify some domain prefix strings for the keys for these options that you may provide. In addition, the regular expression match type on various routes is implementation specific support level, because various implementations may use different regular expression engines, or what have you. So HTTP route path header or query parameter matching, when it's of type regular expression, that's implementation specific support. And similarly for GRPC route. So now we'll move on to a pretty powerful type of extension point that Gateway API is enthusiastic about. And that has to do with it's called policy attachment. And more generally, we're going to talk a little bit about meta resources, which Dan has actually talked about a little bit with referenced grant. So a meta resource is a Kubernetes object that augment the behavior of another one. So in the case of reference grant, you are able to allow cross namespace references by with the configuration that you have in a reference grant. Similarly, a policy is a meta resource that allows you to augment behavior of another object. So for example, you may want to apply some configuration to an HTTP route or a gateway or a service that is implementation specific. But, and this gives us a huge opportunity to do implementation specific things without having to add these things to the Gateway API or the core networking APIs in the case of service. This sort of standard method to plug features into the Gateway API and possibly in the future, more broadly in Kubernetes, offers a great opportunity to augment the APIs in general and offer a uniform user experience. And we're hoping that this standard approach, standardized approach for using these types of meta resources can be a nice way for implementations of the Gateway API to extend the Gateway API. So the core of policy attachment is the target ref. So every policy resource should contain a target reference field that allows you to specify a similar to reference grant and some of the other extension points that Daniel was talking about a local object reference for the target of this policy. And along with that target reference, you'll have some configuration that you want to apply to this to the target of your policy. There's two types of policy attachment, the first of which is direct policy attachment for when you want to augment a particular individual resource. So in this example here, we have a TLS policy that is targeting a service. And in this case, we may want to apply some configuration that proxy implementation or an Ingress controller implementation of Gateway API uses to apply TLS connection details between the proxy and the back end service. So this is a way to, instead of having to change the service resource itself, we can add a meta resource or policy that targets the service and allows us to have some implementation specific configuration on top of what service gives us already. And another next form of policy attachment we have is inherited policy attachment, which is useful for when you want to have settings that flow down a hierarchy of resources. And in a former iteration, this was called hierarchical policy attachment. This is particularly useful in Gateway API, because we have hierarchy of resources, right? We have Gateway class gateways and then the routes underneath them. And then they also reference back ends and other other resources. So in this example, we have a Gateway and some HTTP routes that attach to that Gateway. And we have a target ref in this rate limit policy that targets that Gateway. So all the configuration in this policy should be applied to the Gateway and all of its sort of child resources, the routes that attach to that Gateway. And the core part of the inherited policy attachment idea is that we have a concept of overrides and defaults. So overrides are settings that are applied at the higher levels of the hierarchy and they cannot be changed by objects lower down in the hierarchy. So you imagine in this example, we have a policy applied to the Gateway. That means that any routes attached to this Gateway, if requests come in that match those routes, if they're rate limited, the status code 503 should be returned. And that applies to all of the routes in that Gateway and that cannot be changed by any configuration applied specifically to those routes. On the other hand, we also have defaults, which allow us to set some default values that can be overridden by resources that are further down in the hierarchy. So you can see how these overrides and defaults may be a powerful way to replace something like webhook validation or gatekeeper policies or other things that administrators have to use to ensure compliance, for example, in resources that are created in that cluster that they're managing. So here, going along further with this example, we have another rate limit policy that's targeting a particular route in our Gateway and route hierarchy. And it is overriding some of the default values that were set in the higher level policy. So we have a stricter rate limit in this policy that's applied to this particular route. So you can see if you expand this out to some more complex use cases and more complex hierarchies of resources, this could be a really powerful tool that fits really well into the role-oriented and the different personas and the role-oriented design of Gateway API. So now we've talked about a bunch of different extension points in Gateway API. If I'm a developer working on an implementation, what do I do next? How do I sort out all these different extension points, all the flexibility that the API gives me? How do I use it? So what we found is really useful is to document your use cases using the Gateway API personas. For example, even just writing down statements as an app developer, I need to route traffic across multiple clusters. That go a really long way into helping you decide which extension point to leverage, what resources are involved, what the access levels and RBAC rules possibly are needed in your design. And then to design your API, the Gateway API project strives in this documentation to provide guidelines and documentation and recommendations on how to develop extensions. As the ecosystem matures and there's more implementations contributing to the upstream policies and documentation, this will grow and you'll be able to get really good recommendations on how to design your APIs. And of course, following Kubernetes API design conventions as is expected. And of course, if you're implementing your API, if you chose an extension point that involves custom resources, you'll likely have to implement a controller that watches your custom resources and reconciles them along with other Gateway API resources. And so a huge part of this is also sharing and contributing and collaborating with the upstream community. These Gateway API extension points are still under active development and changing. A lot of the stuff is still being developed in Gateway enhancement proposals. And we're still thinking about how policy attachment, for example, is observable, how to surface status and errors and what policies are in effect, what configuration is in effect on a particular route for users to be able to understand what's going on in their cluster and what they should expect from the configuration that they've applied. So as we go through this process, as developers that are working on implementations of Gateway API or users, we would love to have feedback and discussion on the upstream channels about your experience and your ideas as well. And so that's a neat little segue into talking about Gateway API extensions where they're headed and how we can get involved. So this active, as I said, is active development going on with Gateway API enhancement proposals and active discussion in the weekly community meetings in various time zones. So definitely get involved in the community meetings on Slack in the community Slack at the SIG Network Gateway API and, of course, in the Gateway API GitHub repository. Enhancing with proposals, issues, discussions, pull requests, of course, everything is welcome. And with that, Daniel, do you have anything to add? No, thanks, Sanjay. I would say that we hope that you found our talk useful. And that there are many Gateway API implementations out there. But when it comes to the extensions, like a majority of the current implementations focus on core or maybe even some extended feature level or support level features. But this area that we have focused on our discussion for today, the extensions, that's an area that is still very few implementations take advantage of the extensions. And so it's a great time to get involved in the community, especially around these extension mechanisms. And you see here the weekly gamma meetings. So even the APIs are evolving in the sense that gamma, which is a subgroup that's focused on Gateway API for mesh management. There's just a lot of opportunity to really help develop extensions, extension best practices, or even how Gateway API evolves for mesh management. So with that said, we hope you take a moment and give us some feedback on today's talk and feel free to reach out to us. We're on Slack, a part of the Slack channel, and involved in different projects for CNCF. And we really appreciate your time.