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

docs(MADR): add policy matching for MeshService #10152

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

michaelbeaumont
Copy link
Contributor

Checklist prior to review

Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
@michaelbeaumont michaelbeaumont added the ci/skip-test PR: Don't run unit and e2e tests (maybe this is just a doc change) label May 2, 2024
@michaelbeaumont michaelbeaumont marked this pull request as ready for review May 6, 2024 07:46
@michaelbeaumont michaelbeaumont requested a review from a team as a code owner May 6, 2024 07:46
@michaelbeaumont michaelbeaumont requested review from slonka, Automaat and lobkovilya and removed request for a team May 6, 2024 07:46

### Negative Consequences

* Relative complexity of the semantics of various combinations
Copy link
Contributor

Choose a reason for hiding this comment

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

how do we select multiple services? Can MeshService just select multiple services or do we introduce MeshServiceGroup?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be covered by using labels instead of name

Copy link
Contributor

Choose a reason for hiding this comment

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

It's also not super clear where you can use a set of services vs a single service

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to differentiate it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be clear, I don't mind if we want to introduce another kind for groups, as long as the naming is consistent.

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 concerned with the same targetRef and merging. How do you order policies?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you order MeshServiceGroup before MeshService, you order MeshService + labels before MeshService + name.
There's no information lost between the two representations.

Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Comment on lines 129 to 135
If `kuma.io/zone` is set, a missing `namespace` field means we
refer to _all_ `MeshServices` with this name.
If no `kuma.io/zone` is set, the `namespace` is assumed to be the namespace of
the policy making the reference.

This means we don't infer any similarity between the local namespace
and the other zone's namespace.
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 is not as nice as I thought. So we don't want to assume namespace similarity, that's good. But how do you refer to a MeshService from another zone then?

targetRef:
  namespace: other-zone-ns
  labels:
    kuma.io/zone: other-zone

isn't ideal because the real object is not found at this namespace, rather at kuma-system.

so do we have

targetRef:
  namespace: kuma-system
  labels:
    kuma.io/zone: other-zone
    k8s.kuma.io/namespace: other-zone-ns

? This is the cleanest but it's very verbose.

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't it be k8s.kuma.io/namespace: other-zone-ns in the second example?

Copy link
Contributor

Choose a reason for hiding this comment

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

So this means that you need to create policy in kuma-system namespace in order to target MeshService in different zone? While discussing policies on namespace MADR we talked that in best case scenario SO won't need to apply anything on kuma-system namespace

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, TBH it's not drastically more verbose than the first examples. I'd stick with the more verbose version in favor of preserving the rule that we reference real objects

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with Ilya here ☝️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK spoke with @jakubdyszkiewicz and we decided to just disallow namespace when using labels, and all namespaces will be matched. This makes it more verbose for the local case of a group of MeshServices but 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this means that you need to create policy in kuma-system namespace in order to target MeshService in different zone?

I don't think so, it's just about namespace in the target ref itself. Updated the YAML to make it clearer.

Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Copy link
Contributor

@lahabana lahabana 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 type of matching makes sense to me. Only thing I'd like discussed is using kind: MeshService as a top level targetRef similar to kind: MeshHTTPRoute. In such case the to[].targetRef.kind would always need to be Mesh. I'd love to see pros and cons of this.
The fact we're moving to MeshService might an opportunity to iron out issues on the policy matching story that exists nowadays.

Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
Copy link
Contributor

@lahabana lahabana 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 starting to like this. I have a bit of a concern now that we're talking about product vs consumer policies that I think we need to give good thoughts on

add `labels` but use `port` in `backendRefs`.
* use exactly one of `labels` or `name`/`namespace`
* no new top level fields besides `labels`

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth saying something like: When a targetRef selects multiple MeshServices and ports this behaves as a "foreach" on each individual entity ?

namespace as the policy.
* with `namespace`, only that namespace is searched for matching `MeshServices`

On a universal zone, `namespace` is not valid.
Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC when you are trying to match a policy on a namespace in a different zone you'd need to use labels like:

kind: MeshService
labels:
  kuma.io/zone: other-zone
  k8s.kuma.io/namespace: my-namespace
  kuma.io/display-name: the-service-I-consume

Is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes. our goal was to reserve name/namespace for real objects on this cluster.

port: 8080
labels:
kuma.io/display-name: frontend
kuma.io/zone: east
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if this matches multiple MeshService? Is it equivalent to having N entries (N is the number of services matched) in backendRefs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And in particular, what happens to weight? Not sure...


Similar to Gateway API conditions, we report back as status conditions
if a route targets a
`MeshService`/port tuple that doesn't exist.
Copy link
Contributor

Choose a reason for hiding this comment

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

Status on the policy? On the Dataplane?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the policy/route for sure.

kind: MeshService
labels:
kuma.io/display-name: backend
kuma.io/zone: other-zone
Copy link
Contributor

Choose a reason for hiding this comment

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

With the producer and consumer model we're building up in: #10148
It's not super clear how things work as now zone policies could be synced to other zones.

  1. For example I have a backend service:
kind: MeshService
metadata:
  name: my-backend
  namespace: my-backend-ns
spec:
  selector:
      dataplaneTags:
        app: my-backend
  ports:
    - port: 80
       targetPort: 8080
       name: http
       appProtocol: http
  1. Intuitively I'd write this timeout policy that would affect all consumers of my service (in ALL zones):
kind: MeshTimeout
metadata:
  name: my-backend
  namespace: my-backend-ns
spec:
  targetRef:
     kind: Mesh
  to:
    - targetRef:
          kind: MeshService
          name: my-backend
          port: 80 # (subquestion 1: here the alternative sectionName: http is valid too right?)
      default:
         timeout: 5s
  1. Then I'd want to write a consumer policy in the same zone as:
kind: MeshTimeout
metadata:
   namespace: my-frontend-ns
   name: override-my-backend
spec:
  targetRef:
     kind: Mesh
  to:
    - targetRef:
          kind: MeshService
          name: my-backend
          namespace: my-backend-ns
          port: 80 # (subquestion 1: here the alternative sectionName: http is valid too right?)
      default:
         timeout: 5s
  1. And I'd write a consumer policy in a different zone as:
kind: MeshTimeout
metadata:
   namespace: my-frontend-ns-in-another-zone
   name: override-my-backend
spec:
  targetRef:
     kind: Mesh
  to:
    - targetRef:
          kind: MeshService
          sectionName: http
          labels:
            kuma.io/display-name: my-backend
            k8s.kuma.io/namespace: my-backend-ns
            kuma.io/zone: my-other-k8s-cluster
      default:
         timeout: 10s

1 and 2 gets synced to remote zones. 3 and 4 don't. @lobkovilya is this correct?

Multiple questions come up to me:

  • Do we find it acceptable that matching MeshService in the same zone vs cross zone is syntactically very different (Using labels for remote vs using name/ns for local)?
  • With producer policies these gets synced to remote zones now. Is it still straight-forward to do the matching (do we use the synced labels to enhance the matcher)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Policy from the step 2 won't pass the new validation, it is created in my-backend-ns, it targets kind: Mesh, but it doesn't specify k8s.kuma.io/namespace: my-backend-ns and kuma.io/zone: zone-with-backend in each item of to[], so it should be:

kind: MeshTimeout
metadata:
  name: my-backend
  namespace: my-backend-ns
spec:
  targetRef:
     kind: Mesh
  to:
    - targetRef:
          kind: MeshService
          labels:
            kuma.io/display-name: my-backend
            kuma.io/zone: zone-with-backend
            k8s.kuma.io/namespace: my-backend-ns
          port: 80 # (subquestion 1: here the alternative sectionName: http is valid too right?)
      default:
         timeout: 5s

Same for the policy from step 3:

kind: MeshTimeout
metadata:
   namespace: my-frontend-ns
   name: override-my-backend
spec:
  targetRef:
     kind: MeshSubset
     tags:
       k8s.kuma.io/namespace: my-frontend-ns
       kuma.io/zone: zone-with-frontend
  to:
    - targetRef:
          kind: MeshService
          name: my-backend
          namespace: my-backend-ns
          port: 80 # (subquestion 1: here the alternative sectionName: http is valid too right?)
      default:
         timeout: 5s

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 talking about these rules:

The validation rules for namespace-scoped policy are the following:

  • to-policy when placed into the custom namespace must have the namespace and zone either in the top-level targetRef or in each to-item
  • from-policy when placed into the custom namespace must always have the namespace and zone in the top-level targetRef

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci/skip-test PR: Don't run unit and e2e tests (maybe this is just a doc change)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants