Skip to content

Conversation

@alexsnaps
Copy link
Member

No description provided.

Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Signed-off-by: Alex Snaps <[email protected]>
Resource](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/), and as such will be
managed by some controller. But unlike a regular [Kubernetes
Controller](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-controllers),
it also needs to reconcile when changes to properties of the Gateway API it uses are observed. For that reason, the
Copy link

@thomasmaas thomasmaas Mar 6, 2025

Choose a reason for hiding this comment

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

Suggested change
it also needs to reconcile when changes to properties of the Gateway API it uses are observed. For that reason, the
it also needs to reconcile when it observes changes to properties of the Gateway API it uses. For that reason, the

Or is it not the metapolicy controller that observes the changes?

Copy link

@thomasmaas thomasmaas Mar 6, 2025

Choose a reason for hiding this comment

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

In the case it's the KuadrantController that observes the changes I would make that explicit:

Suggested change
it also needs to reconcile when changes to properties of the Gateway API it uses are observed. For that reason, the
it also needs to reconcile when changes to properties of the Gateway API it uses are observed by the `KuadrantController`. For that reason, the

deployment: embedded
```

The `UserMetaPolicy` will need to be packaged with a custom Docker image containing the plugin. It'll be automatically

Choose a reason for hiding this comment

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

If a plugin contains one MetaPolicy, do we need to distinguish? Or you're think plugins might contain other "things" in the future?

Copy link
Member Author

@alexsnaps alexsnaps Mar 6, 2025

Choose a reason for hiding this comment

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

The Plugin in this case is the extension point that the Kuadrant controller needs to know about. It so happens that this extension is a "metacontroller" that effectively cares about changes to its own resources, e.g. UserMetaPolicy CRs and the changes to relevant Gateway API resources (i.e. the DAG).

Now there is no reason the Plugin couldn't be more or something entirely different than a "metacontroller". It simply formalizes the API that such a plugin talks with the Kuadrant controller. That, and "sandboxes" it, so that plugins failing don't affect each other.

Because in this case the Plugin is "embedded", the Kuadrant controller will also be responsible to start it, shut it down, and keep it running.

return reconcile.Result{}, nil
}
```
It on differs in three ways from the original example:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
It on differs in three ways from the original example:
It only differs in three ways from the original example:

1. It uses the `evaluateExpression` to resolve the CEL expression `kuadrant.gatewaysFor(self)[0].metadata.name` instead
of using a fixed string for the label's value.

Because that expression is evaluated upon creation, the `KuadrantRuntime` will make sure to reconcile whenever that cel
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Because that expression is evaluated upon creation, the `KuadrantRuntime` will make sure to reconcile whenever that cel
Because that expression is evaluated upon creation, the `KuadrantRuntime` will make sure to reconcile whenever that CEL

}

// resolve the CEL expression using the `KuadrantContext`
label := kuadrant.evaluateExpression("kuadrant.gatewaysFor(self)[0].metadata.name")
Copy link
Collaborator

Choose a reason for hiding this comment

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

self here would be the metapolicy object?

Copy link
Member Author

@alexsnaps alexsnaps Mar 7, 2025

Choose a reason for hiding this comment

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

yes... where gatewaysFor would probably provide "overloads", as CEL calls them, to act upon certain types. I don't know actually that we can do it, in this case, for anything that has targetRef, a la structural typing... so, might have to be gatewaysFor(self.targetRef), where that then resolves to a known-type for which there is an overload.

### Deployment

> [!IMPORTANT]
> This would initially be deployed as their own processes running alongside the kuadrant controller. They'd communicate
Copy link
Collaborator

@maleck13 maleck13 Mar 7, 2025

Choose a reason for hiding this comment

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

When you say along side. Does that mean in the same pod and as part of the same deployment object? So for example the Kuadrant Operator would add in the new container to the existing deployment. The plugin(s) would then read from the socket and act on the streamed data.

Actually re-reading I think I answered my own question:
"in-pod/embedded"

Copy link
Collaborator

Choose a reason for hiding this comment

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

One consideration may be limiting the resources that such a container can have. I think we would also want to understand to protect the kuadrant operator from a bad plugin crashing and potentially causing the pod to get restarted

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

@maleck13 if you want a little more hands-on details, I started some work here, but tl;dr this would be orthogonal. They'd be "out of process" (for the reasons you mention), and they would all be isolated from the operator and from each other. The Kuadrant operator lifecycles them. But in anycase, the advantage I see is that it's "non binding", i.e. given it's gRPC over a unix socket, we can perfectly have RemotePlugins that would communicate using a tcp/ip socket.

> Later, we could support different deployment models, as all that'd be needed is being able to use gRPC essentially.

- [ ] Known location for plugins to live in; one per directory
- [ ] Unix socket opened within the same location?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Possibly use a volume mount of type emptyDir. Th https://kubernetes.io/docs/concepts/storage/volumes/#emptydir

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 was, for now certainly, not looking into making this a "first class citizen" per se, so you'd probably docker compose the base image to add e.g. the /plugins/myPlugin/myPlugin executable to the kuadrant operator.

> Discuss prior art, both the good and the bad, in relation to this proposal.
> A few examples of what this can include are:
>
> - Does another project have a similar feature?
Copy link
Member

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants