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

The virtual_domains not generated correctly with AUTO_REACHABLE_SERVICES and MeshTrafficPermission #12273

Closed
Icarus9913 opened this issue Dec 16, 2024 · 8 comments · Fixed by #12340
Assignees
Labels
kind/bug A bug triage/accepted The issue was reviewed and is complete enough to start working on it

Comments

@Icarus9913
Copy link
Contributor

What happened?

version: 2.9.2

What happened?

I eanbled the AUTO_REACHABLE_SERVICES feature and create 2 MTPs and found the virtual_domains was not generate correctly from the XDS configuration

Steps to reproduce

  1. create a single zone with 2.9.2
  2. enable auto_reachable_services with ENV KUMA_EXPERIMENTAL_AUTO_REACHABLE_SERVICES
  3. Apply the following yamls:
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  meshServices:
    mode: Exclusive
  mtls:
    enabledBackend: ca-1
    backends:
    - name: ca-1
      type: builtin
---
apiVersion: kuma.io/v1alpha1
kind: HostnameGenerator
metadata:
  name: default
  namespace: kuma-system
spec:
  selector:
    meshService:
      matchLabels:
        kuma.io/origin: zone
  template: "{{ .DisplayName }}.{{ .Namespace }}.default.gg.mesh"
  1. Create 2 applications with sidecar injected:
apiVersion: v1
kind: Namespace
metadata:
  labels:
    kuma.io/sidecar-injection: enabled
  name: kuma-demo
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    kuma.io/sidecar-injection: enabled
  name: kuma-one
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: 2048-app
  namespace: kuma-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: 2048-app
  template:
    metadata:
      labels:
        app: 2048-app
    spec:
      containers:
      - name: 2048-app
        image: ghcr.io/daocloud/dao-2048:v1.4.1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: service-2048-app
  namespace: kuma-demo
spec:
  type: ClusterIP
  selector:
    app: 2048-app
  ports:
    - name: http
      appProtocol: http
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: kuma-one
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:stable
        ports:
          - containerPort: 80
            name: http-web-svc
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: kuma-one
spec:
  selector:
    app: nginx
  ports:
  - name: name-of-service-port
    appProtocol: http
    protocol: TCP
    port: 80
    targetPort: http-web-svc
  1. Create the following MTPs one by one:
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
  name: mtp-allow-kuma-one
  namespace: kuma-system
  labels:
    kuma.io/mesh: default
spec:
  targetRef:
    kind: Mesh
  from:
  - targetRef:
      kind: MeshSubset
      tags:
        k8s.kuma.io/namespace: kuma-one
    default:
      action: Allow
---
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
  name: mtp-allow-kuma-other-ns-and-tag
  namespace: kuma-system
  labels:
    kuma.io/mesh: default
spec:
  targetRef:
    kind: Mesh
  from:
  - targetRef:
      kind: MeshSubset
      tags:
        asdfasdfasdf: asdfasdfasdf
        k8s.kuma.io/namespace: kuma-other
    default:
      action: Allow

Result

XDS configurations:

        {
          "name": "kuma:dns",
          "active_state": {
            "version_info": "64c1c7c1-8609-40a6-b7c3-ea3949b850e1",
            "listener": {
              "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
              "name": "kuma:dns",
              "listener_filters": [
                {
                  "name": "envoy.filters.udp.dns_filter",
                  "typed_config": {
                    "@type": "type.googleapis.com/envoy.extensions.filters.udp.dns_filter.v3.DnsFilterConfig",
                    "stat_prefix": "kuma_dns",
                    "server_config": {
                      "inline_dns_table": {}
                    }
                  }
                }
              ],
@Icarus9913 Icarus9913 added triage/pending This issue will be looked at on the next triage meeting kind/bug A bug labels Dec 16, 2024
@Icarus9913
Copy link
Contributor Author

Icarus9913 commented Dec 16, 2024

I created one PR to build the local test: #12274

The direct problem here is:

rule := r.backendRules[noPort].Compute(core_rules.SubsetFromTags(fromTags))
if rule == nil {
return false
}

@Icarus9913
Copy link
Contributor Author

I read the codes and found in rules.go, we'll assemble all of the MTPs tags then we'll have subsets as:

{
"asdfasdfasdf": "asdfasdfasdf",
"k8s.kuma.io/namespace": "kuma-other",
"k8s.kuma.io/namespace": "kuma-one"
}

But we'll return false due to this judgement:

for _, tag := range ss {
oTags, ok := otherByKeys[tag.Key]
if !ok {
return false
}

@Icarus9913
Copy link
Contributor Author

Icarus9913 commented Dec 16, 2024

Here's my humble workaround but not sure if it's correct:

// IsSubset returns true if 'other' is a subset of the current set.
// Empty set is a superset for all subsets.
func (ss Subset) IsSubset(other Subset) bool {
	if len(ss) == 0 {
		return true
	}
	if len(other) == 0 {
		return false
	}

	otherByKeys := map[string][]Tag{}
	for _, t := range other {
		otherByKeys[t.Key] = append(otherByKeys[t.Key], t)
	}

	noMatchedCount := 0
	for _, tag := range ss {
		oTags, ok := otherByKeys[tag.Key]
		if !ok {
			noMatchedCount++
			continue
			//return false
		}
		for _, otherTag := range oTags {
			if !isSubset(tag, otherTag) {
				return false
			}
		}
	}
	if noMatchedCount == len(ss) {
		return false
	}

	return true
}

@lobkovilya
Copy link
Contributor

lobkovilya commented Dec 16, 2024

I think the method IsSubset should stay untouched. But you're right the problem is here:

rule := r.backendRules[noPort].Compute(core_rules.SubsetFromTags(fromTags))
if rule == nil {
return false
}

We need to rewrite the method Compute so it doesn't use the IsSubset but uses some other method with the right logic.

The semantic of IsSubset is to check if one set "is subset" of another set. So it's relation between 2 sets. We need Compute to call a function that's called something like IsPointInSet(p Point). Though both Point and Subset are defined by key-value pairs, the output of IsSubset and IsPointInSet is different. For example:

set1 := map[string]string{
     "key1": "value1",
     "key2": "value2",
}
set2 := map[string]string{
     "key1": "value1",
}
fmt.Println(set1.IsSubset(set2)) // false

but

set1 := map[string]string{
     "key1": "value1",
     "key2": "value2",
}
point := map[string]string{
     "key1": "value1",
}
fmt.Println(set1.IsPointInSet(point)) // true

@lobkovilya
Copy link
Contributor

fyi I think this issue is about the same thing #8155

@lukidzi
Copy link
Contributor

lukidzi commented Dec 16, 2024

Triage: We should implement the new method IsPointSelectedBy and use it to Compute for autoreachable services. We should also introduce new aliases because the current gives confusion. We should use Selector and Point

@lukidzi lukidzi added triage/accepted The issue was reviewed and is complete enough to start working on it and removed triage/pending This issue will be looked at on the next triage meeting labels Dec 16, 2024
@lahabana
Copy link
Contributor

So is this issue a dupe of #8155?

@Icarus9913
Copy link
Contributor Author

So is this issue a dupe of #8155?

Yeah, I think so

@Icarus9913 Icarus9913 self-assigned this Dec 19, 2024
@lahabana lahabana changed the title The virtual_domains wasn't generate correctly with AUTO_REACHABLE_SERVICES and MeshTrafficPermission The virtual_domains not generated correctly with AUTO_REACHABLE_SERVICES and MeshTrafficPermission Dec 19, 2024
Icarus9913 added a commit to Icarus9913/kuma that referenced this issue Jan 12, 2025
…q#12340)

## Motivation

1. When I went through the policy matching subset `Intersect` method, I
found the behavior is incorrect with one case
2. Rewrite the rule's `Compute` method to use the new `ContainsElement`
method instead of using the old `IsSubset` method

## Implementation information

Introduce one new type `type Element map[string]string` for
differentiation by `IsSubset`.

## Supporting documentation

<!-- Is there a MADR? An Issue? A related PR? -->

Fix kumahq#12319
Fix kumahq#12273

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry
here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

---------

Signed-off-by: Icarus Wu <[email protected]>
Signed-off-by: Ilya Lobkov <[email protected]>
Co-authored-by: Ilya Lobkov <[email protected]>
Icarus9913 added a commit to Icarus9913/kuma that referenced this issue Jan 12, 2025
…ort of kumahq#12340)

1. When I went through the policy matching subset `Intersect` method, I
found the behavior is incorrect with one case
2. Rewrite the rule's `Compute` method to use the new `ContainsElement`
method instead of using the old `IsSubset` method

Introduce one new type `type Element map[string]string` for
differentiation by `IsSubset`.

<!-- Is there a MADR? An Issue? A related PR? -->

Fix kumahq#12319
Fix kumahq#12273

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry
here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

---------

Signed-off-by: Icarus Wu <[email protected]>
Signed-off-by: Ilya Lobkov <[email protected]>
Co-authored-by: Ilya Lobkov <[email protected]>
Icarus9913 added a commit to Icarus9913/kuma that referenced this issue Jan 12, 2025
…q#12340)

1. When I went through the policy matching subset `Intersect` method, I
found the behavior is incorrect with one case
2. Rewrite the rule's `Compute` method to use the new `ContainsElement`
method instead of using the old `IsSubset` method

Introduce one new type `type Element map[string]string` for
differentiation by `IsSubset`.

<!-- Is there a MADR? An Issue? A related PR? -->

Fix kumahq#12319
Fix kumahq#12273

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry
here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

---------

Signed-off-by: Icarus Wu <[email protected]>
Signed-off-by: Ilya Lobkov <[email protected]>
Co-authored-by: Ilya Lobkov <[email protected]>
Icarus9913 added a commit to Icarus9913/kuma that referenced this issue Jan 12, 2025
…ort of kumahq#12340)

1. When I went through the policy matching subset `Intersect` method, I
found the behavior is incorrect with one case
2. Rewrite the rule's `Compute` method to use the new `ContainsElement`
method instead of using the old `IsSubset` method

Introduce one new type `type Element map[string]string` for
differentiation by `IsSubset`.

<!-- Is there a MADR? An Issue? A related PR? -->

Fix kumahq#12319
Fix kumahq#12273

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry
here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

---------

Signed-off-by: Icarus Wu <[email protected]>
Signed-off-by: Ilya Lobkov <[email protected]>
Co-authored-by: Ilya Lobkov <[email protected]>
Icarus9913 added a commit to Icarus9913/kuma that referenced this issue Jan 12, 2025
…ort of kumahq#12340)

1. When I went through the policy matching subset `Intersect` method, I
found the behavior is incorrect with one case
2. Rewrite the rule's `Compute` method to use the new `ContainsElement`
method instead of using the old `IsSubset` method

Introduce one new type `type Element map[string]string` for
differentiation by `IsSubset`.

<!-- Is there a MADR? An Issue? A related PR? -->

Fix kumahq#12319
Fix kumahq#12273

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry
here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

---------

Signed-off-by: Icarus Wu <[email protected]>
Signed-off-by: Ilya Lobkov <[email protected]>
Co-authored-by: Ilya Lobkov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug A bug triage/accepted The issue was reviewed and is complete enough to start working on it
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants