Skip to content

Move GEP-3792 to Memorandum with API in other GEPs #3894

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

kflynn
Copy link
Contributor

@kflynn kflynn commented Jul 1, 2025

GEP-3792 is becoming Memorandum, defining the problems that need solving for OCG support.
#3950 is the new GEP that defines the Mesh resource.
An API GEP to allow experimenting with OCG support will arrive shortly.

/kind gep

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/gep PRs related to Gateway Enhancement Proposal(GEP) cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Jul 1, 2025
@k8s-ci-robot k8s-ci-robot requested review from gcs278 and robscott July 1, 2025 17:44
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jul 1, 2025
gatewayClassName: ocg-gateway-class
...
mesh: # All mesh-related configuration goes here
trustBundle:
Copy link
Contributor

Choose a reason for hiding this comment

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

I want to put in consideration adoption of ClusterTrustBundle which is now Beta in Kubernetes. It was designed exactly for this goal and is a perfect fit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This isn't a "no", but... what would that look like? do we basically vendor the Go type for ClusterTrustBundle for codegen and hope that it doesn't change out from under us? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

No, just an object ref to a ClusterTrustBundle. Or maybe not even a 'ref' needed, just a name (its cluster scoped so no namespace needed)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ClusterTrustBundle, if I understand correctly, is an alpha feature from K8s 1.27 to K8s 1.32, which is to say that in nearly every version supported by Gateway API, if you don't have the feature gate enabled, the ClusterTrustBundle resource type won't exist and there will be no way to refer to a ClusterTrustBundle resource in the Gateway resource... which is why I'm asking what using ClusterTrustBundle would look like. 🙂

(I really, really do not want Gateway API to ship definitions for resources defined by the Kubernetes core, ever.)

ClusterTrustBundle is also a cluster-scoped resource, which feels a bit less than ideal, but that's a much much smaller problem in my mind.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is also an alpha (experimental) feature. It seems problematic that an experimental feature cannot depend on a Beta feature, and instead we are just re-inventing the exact thing ClusterTrustBundle was designed for

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this isn't a question about semantics, I kind of agree with you in principle. 🙂 I'm asking about mechanics here: how, technically, can we use ClusterTrustBundle on a cluster where the APIserver does not have any resource type defined under that name?

Saying "you have use K8s 1.33 or enable the feature gate" feels problematic.

Copy link
Contributor

Choose a reason for hiding this comment

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

The options here are:

  • we only add trustBundle inline for now, with a note about how we will add ClusterTrustBundle in the future.
  • we add both for now, with a note that once ClusterTrustBundle is more available in Gateway API supported versions, we will remove the inline trustBundle. We can get away with that as long as this resource is Experimental.
  • We only add trustBundle, and say "run 1.33 or later, or enable an alpha feature to use this". This would require us to specify the behavior for implementations; since this has a FeatureName anyway, there is a mechanism to say "requires k8s 1.33 or alpha feature enabled to work", although we've never done that before.

Because Gateway API's claimed Kubernetes support is five versions, the last would mean that we would need to wait nearly two years before bringing this API to GA in options 2 or 3. That feels like a longer timeline than people would expect for this. Unless we are okay with doing 3 and adding features that are not supported across all supported Kubernetes versions, which does not seem optimal to me.

@robscott for his thoughts on this one too.

Copy link
Contributor

@youngnick youngnick Jul 2, 2025

Choose a reason for hiding this comment

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

Actually, I just checked, and ClusterTrustBundle is only beta, and not enabled by default in v1.33, so this would be even longer. (See https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#cluster-trust-bundles for the reference)

At a minimum, if ClusterTrustBundle moves to Stable in v1.34, then the only time we could allow it with no caveats is as of Kubernetes v1.38, which is in just over two years.

In short; my thoughts here are that we can add a ClusterTrustBundle reference with a feature name and a version caveat at best. But we need something for before then as well.

Copy link

Choose a reason for hiding this comment

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

We have similar (though less restrictive) versioning issues for using ClusterTrustBundle within GKE. The approach we took was to make a CustomResource ("GKEClusterTrustBundle") that had exactly the same shape as ClusterTrustBundle, and have our controllers understand both types.

Copy link
Member

Choose a reason for hiding this comment

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

Elsewhere in GW API when we've dealt with configure CA certs we've started with config maps with the idea that we'd add support for ClusterTrustBundle as it became more broadly available. That seems like a reasonable approach here, with the distinction that ClusterTrustBundle is likely going to go to GA in v1.35, so it would be good to consider that our default starting point with ConfigMap as the legacy backfill option from the outset.

- The mesh MUST use an mTLS certificate ultimately signed by a certificate in
the trust bundle provided to the OCG.

- The OCG MUST send the `ocg.gateway.networking.k8s.io/v1` ALPN protocol
Copy link
Contributor

Choose a reason for hiding this comment

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

This applies to the whole proposal in general but specifically this line. There are 3 OCG implementations today. I would think to make this viable we need at least 2 to agree to this.

I know that, unless things have changed, using a custom ALPN is the hill at least one cloud will die on and will never support

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not comfortable making this a MUST. Custom ALPNs are certainly a way to signal mTLS, but different implementations may use tunneling protocols like HBONE instead.

Copy link
Contributor Author

@kflynn kflynn Jul 1, 2025

Choose a reason for hiding this comment

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

@keithmattix and I discussed this on Slack a bit, since I'm very uncomfortable with making this a MAY and then having, say, the OCG expecting ALPN, the mesh expecting HBONE, but they both believe that they "support GEP-3792 OCG".

As Keith noted on Slack, though, it doesn't really make sense to require a mesh to only support one mechanism for solving the protocol problem, and it follows that it probably does make sense to add an explicit field to the Gateway and Mesh resources to say what the signalling mechanism is. That also permits warning Chihiro if the Gateway and Mesh disagree on what's offered. I'll add that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, to @howardjohn's point: we explicitly say in "Graduation Criteria" section that we require at least two OCG implementations and at least two mesh implementations. Leaving aside the choice of hills upon which to die... 🙂

Copy link
Member

Choose a reason for hiding this comment

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

it follows that it probably does make sense to add an explicit field to the Gateway and Mesh resources to say what the signalling mechanism is. That also permits warning Chihiro if the Gateway and Mesh disagree on what's offered. I'll add that.

This makes me a bit nervous in that we could end up with n different protocols that OCGs would need to support here. Maybe this is unavoidable, but I'd really like to minimize the variations here if we can. The larger the number of variations here, the less likely it is that an OCG is going to be able to support them.

- The mesh MUST use an mTLS certificate ultimately signed by a certificate in
the trust bundle provided to the OCG.

- The OCG MUST send the `ocg.gateway.networking.k8s.io/v1` ALPN protocol
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not comfortable making this a MUST. Custom ALPNs are certainly a way to signal mTLS, but different implementations may use tunneling protocols like HBONE instead.

@kflynn kflynn changed the title Add API for Off-Cluster Gateways API for Off-Cluster Gateways Jul 1, 2025
@youngnick
Copy link
Contributor

I won't get much of a chance to watch this one further, but the main point I wanted to add is that, because this is TLS config for a Gateway, it's important that we define the interaction (or lack thereof) with consumer BackendTLSPolicy as per #3875.

FTR, I think that saying "they are for different things, the only interaction is to end up with TLS-in-TLS, which is dumb, so you should avoid that". is fine by me.

for [Chihiro] and [Ian], _and_ it limits us to only having entire
namespaces meshed.

6. Add a label selector to the Gateway resource and declare that Routes with

Choose a reason for hiding this comment

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

just a thought - how about an explicit mesh MTLS policy that targetRefs a service? the meshMTLS policy would indicate to both the OCG and Mesh Clients that they need to use Mesh MTLS to talk to the service.
the explicit meshMTLS policy can be either created by the user or the mesh controller creates a default one for every service that is meshed. The user would override the default one if they wish to tweak the default settings - for e.g override the SAN checks, or SNI or disable/enable MTLS perhaps (any kind of outbound setting).

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW in Istio (and probably linkerd and every other mesh), the mesh TLS is a property of a workload (Pod) not service. So workloads within the same Service may not actually have the same properties

Copy link
Member

Choose a reason for hiding this comment

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

@howardjohn I don't think that we should expect Gateways to be able to differentiate TLS configuration per workload, that would be a huge increase in scope/complexity for many Gateway implementations. Instead, it seems simpler to focus on the common attributes that Gateways can understand (Service, Namespace, etc).

(You may not have been suggesting that Gateways should be able to understand per-Pod TLS config, so sorry if I'm misunderstanding here).

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not necessarily suggesting we do, but to properly handle all cases you would need to

as application-level mTLS that they should treat as an opaque data stream,
or they may simply refuse it. This alternative, therefore, both shifts the
entire burden of implementation to the meshes, and probably makes it
impossible to correctly handle application-level mTLS.
Copy link

@karthikbox karthikbox Jul 7, 2025

Choose a reason for hiding this comment

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

just wanted to mention that GKE Mesh is a notable exception (atleast partially). We use simply use bare mtls connection. And yes, we're subject to the downsides mentioned above. But the upside of interoperability between various GCP (off-GCP) data planes with GKE Mesh workloads using standard MTLS was/is deemed to be more important (i.e don't run into the protocol problem).

my intention with this comment is NOT to say custom protocol shouldn't be supported, but to point out that there are implementations that just use bare/standard mtls.

gatewayClassName: ocg-gateway-class
...
mesh: # All mesh-related configuration goes here
trustBundle:

Choose a reason for hiding this comment

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

can we allow for some kind of extensibility here to indicate Platform MTLS? The Platform MTLS is a feature of the cloud platform (e.g GKE Managed Workload Certificates) or the mesh vendor (e.g Istio) where the certs and trust bundle is provisioned by the platform for each workload and OCG automatically. In such cases, User need not configure the k8s Secret explicitly reducing toil.

Choose a reason for hiding this comment

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

same comment for the counterpart in Mesh resource.

Choose a reason for hiding this comment

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

or would clusterTrustBundle (or the gkeClusterTrustBundle) be able carry the info for the platform MTLS? @ahmedtd to confirm. If that's the case, then supporting clusterTrustBundle be the path forward for indicating platform MTLS.

Copy link

Choose a reason for hiding this comment

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

GKE Managed Workload Certificates uses GKEClusterTrustBundle, which is an identical copy of ClusterTrustBundle as a custom resource. We intend to migrate to ClusterTrustBundle for in-cluster distribution of trust anchors.

Copy link
Member

Choose a reason for hiding this comment

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

@ahmedtd @karthikbox just to make sure I'm following this thread correctly, it sounds like ClusterTrustBundle (or an equivalent) would work well here, even for Platform mTLS?

Comment on lines 349 to 436
3. Add a field to the Route resource that indicates whether the Route is
meshed. This feels like quite a bit of an imposition on [Ana] (and, again,
if we do our jobs correctly, [Ana] shouldn't need to think about this).
Copy link
Member

@LiorLieberman LiorLieberman Jul 8, 2025

Choose a reason for hiding this comment

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

Maybe I am missing something, cant we use parentRef: <ANY_SERVICE>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The OCG won't be able to see a Route unless it has a parentRefs entry for the OCG itself. It feels quite strange to also have the OCG (a Gateway) look at other parentRefs entries to figure out if a mesh is involved?

Copy link
Member

@robscott robscott left a comment

Choose a reason for hiding this comment

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

Thanks @kflynn, this is really well written, appreciate the time you've put into this!

Comment on lines 289 to 360
- The OCG MUST use an mTLS certificate ultimately signed by a certificate in
the trust bundle provided to the mesh.
Copy link
Member

Choose a reason for hiding this comment

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

I thought this trust bundle was configured on the mesh resource? This may be saying that, but it's a bit confusing to me.

- The OCG MUST use an mTLS certificate ultimately signed by a certificate in
the trust bundle provided to the mesh.

- The mesh MUST use an mTLS certificate ultimately signed by a certificate in
Copy link
Member

Choose a reason for hiding this comment

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

Can we call this a client cert? Is the Gateway supposed to generate this on their own, or can/should a mesh provide client cert(s) for Gateway(s) to use?

- The mesh MUST use an mTLS certificate ultimately signed by a certificate in
the trust bundle provided to the OCG.

- The OCG MUST send the `ocg.gateway.networking.k8s.io/v1` ALPN protocol
Copy link
Member

Choose a reason for hiding this comment

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

it follows that it probably does make sense to add an explicit field to the Gateway and Mesh resources to say what the signalling mechanism is. That also permits warning Chihiro if the Gateway and Mesh disagree on what's offered. I'll add that.

This makes me a bit nervous in that we could end up with n different protocols that OCGs would need to support here. Maybe this is unavoidable, but I'd really like to minimize the variations here if we can. The larger the number of variations here, the less likely it is that an OCG is going to be able to support them.

Comment on lines 334 to 424
The discovery problem is that not every workload in the cluster is required to
be meshed, which means that the OCG needs a way to know whether a given
connection must participate in the mesh or not. In practice, this isn't
actually a question of _workloads_ but of _Routes_: the point of interface
between a Gateway and a workload in the cluster is not a Pod or a Service, but
rather a Route.
Copy link
Member

Choose a reason for hiding this comment

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

It seems like we care less about which workloads have a mesh Route, and more about which workloads have automatic mTLS provided by a Mesh. My understanding is that most mesh implementations provide automatic mTLS/mesh transport for a broader set of workloads, and that's what we want Gateways to care about when connecting to backends with mTLS following this mesh config.

for [Chihiro] and [Ian], _and_ it limits us to only having entire
namespaces meshed.

6. Add a label selector to the Gateway resource and declare that Routes with
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 trying to understand the mechanics of this. Does this selector only apply to Routes that are attached to each relevant Gateway? Are Gateway implementations supposed to look at mesh Routes?

for [Chihiro] and [Ian], _and_ it limits us to only having entire
namespaces meshed.

6. Add a label selector to the Gateway resource and declare that Routes with
Copy link
Member

Choose a reason for hiding this comment

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

@howardjohn I don't think that we should expect Gateways to be able to differentiate TLS configuration per workload, that would be a huge increase in scope/complexity for many Gateway implementations. Instead, it seems simpler to focus on the common attributes that Gateways can understand (Service, Namespace, etc).

(You may not have been suggesting that Gateways should be able to understand per-Pod TLS config, so sorry if I'm misunderstanding here).

gatewayClassName: ocg-gateway-class
...
mesh: # All mesh-related configuration goes here
trustBundle:
Copy link
Member

Choose a reason for hiding this comment

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

Elsewhere in GW API when we've dealt with configure CA certs we've started with config maps with the idea that we'd add support for ClusterTrustBundle as it became more broadly available. That seems like a reasonable approach here, with the distinction that ClusterTrustBundle is likely going to go to GA in v1.35, so it would be good to consider that our default starting point with ConfigMap as the legacy backfill option from the outset.

spec:
gatewayClassName: ocg-gateway-class
...
mesh: # All mesh-related configuration goes here
Copy link
Member

Choose a reason for hiding this comment

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

Why is this on the Gateway? This feels like configuration that could live on the Mesh resource?

Comment on lines 436 to 523
selector:
matchLabels:
linkerd.io/inject: "true" # or whatever label is appropriate
Copy link
Member

Choose a reason for hiding this comment

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

As I understand it, this selector is intended to select namespaces and routes. I'm very nervous about a multi-resource selector here though. My understanding is that the primary reason for considering Routes here is when only a portion of a namespace is part of a mesh. Would it be reasonable to keep a label selector for namespaces, and then opt-out per Service or Service Port?

The rationale for that would be:

  1. The selector is clearly for a single kind of resource
  2. We still provide a way to opt-out subsets of a namespace
  3. We're using granularities that are already well understood by a Gateway (my guess is that it will be difficult for some implementations to configure mTLS per route rule, but quite simple per backend as we're already doing with BackendTLSPolicy)

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 17, 2025
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 22, 2025
@kflynn kflynn marked this pull request as draft July 22, 2025 03:24
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 22, 2025
@kflynn kflynn mentioned this pull request Jul 22, 2025
@kflynn kflynn force-pushed the flynn/gep-3792 branch 2 times, most recently from a5e438e to f5a7b01 Compare July 23, 2025 19:46
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 23, 2025
@kflynn kflynn changed the title API for Off-Cluster Gateways Move GEP-3792 to Memorandum with API in other GEPs Jul 23, 2025
@kflynn
Copy link
Contributor Author

kflynn commented Jul 23, 2025

I'm making this PR ready for review again because the API stuff is moving. However, I'm leaving many comments unresolved since they're relevant for other GEPs.

@kflynn kflynn marked this pull request as ready for review July 23, 2025 20:23
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 23, 2025
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: kflynn
Once this PR has been reviewed and has the lgtm label, please assign robscott for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 26, 2025
kflynn added 4 commits July 26, 2025 09:51
Signed-off-by: Flynn <[email protected]>
…e Mesh resource, and define that the API will be different GEPs.

Signed-off-by: Flynn <[email protected]>
Signed-off-by: Flynn <[email protected]>
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 26, 2025
@k8s-ci-robot
Copy link
Contributor

@kflynn: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-gateway-api-verify 9c215ac link true /test pull-gateway-api-verify

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@@ -1,10 +1,17 @@
# GEP-3792: Out-of-Cluster Gateways

* Issue: [#3792](https://github.com/kubernetes-sigs/gateway-api/issues/3792)
* Status: Provisional
* Status: Memorandum
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Status: Memorandum
* Status: Deferred

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. kind/gep PRs related to Gateway Enhancement Proposal(GEP) release-note-none Denotes a PR that doesn't merit a release note. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants