Traefik Kubernetes Gateway API with Cross-Namespace routing

Hello,

Does Traefik support the Kubernetes Gateway API Cross-Namespace routing ? I have tried to use it for that purpose but without success.

To give more contexte : I have a k8s cluster with multiple nginx container deployed on two different namespace. I want to be able to access the container on the first namespace from http://<node-ip>/testing and those of the second namespace from http://<node-ip>/second.

Because I want to access service for differents namespace the Kubernetes Gateway API is more suited than the Kubernetes ingress. Unfortunately my requests return a 404 page not found for the moment.

I have the following files :

00-rbac.yml

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gateway-role
rules:
  - apiGroups:
      - ""
    resources:
      - namespaces
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - gateway.networking.k8s.io
    resources:
      - gatewayclasses
      - gateways
      - httproutes
      - referencegrants
      - tcproutes
      - tlsroutes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - gateway.networking.k8s.io
    resources:
      - gatewayclasses/status
      - gateways/status
      - httproutes/status
      - tcproutes/status
      - tlsroutes/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gateway-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: gateway-role
subjects:
  - kind: ServiceAccount
    name: traefik-controller
    namespace: default

00-namespace.yml

apiVersion: v1
kind: Namespace
metadata:
  name: second
  labels:
    shared-gateway-access: "true"
---
apiVersion: v1
kind: Namespace
metadata:
  name: testing
  labels:
    shared-gateway-access: "true"
---

01-traefik.yml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-controller

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik-lb

  template:
    metadata:
      labels:
        app: traefik-lb

    spec:
      serviceAccountName: traefik-controller
      containers:
        - name: traefik
          image: traefik:v3.0
          args:
            - --entryPoints.web.address=:80
            - --entryPoints.websecure.address=:443
            - --experimental.kubernetesgateway
            - --providers.kubernetesgateway

          ports:
            - name: web
              containerPort: 80

            - name: websecure
              containerPort: 443

---
apiVersion: v1
kind: Service
metadata:
  name: traefik

spec:
  type: NodePort
  selector:
    app: traefik-lb

  ports:
    - protocol: TCP
      port: 80
      nodePort: 30000
      targetPort: web
      name: web

    - protocol: TCP
      port: 443
      targetPort: websecure
      name: websecure

03-gateway.yml

---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: traefik-gateway

spec:
  controllerName: traefik.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-gateway

spec:
  gatewayClassName: traefik-gateway
  listeners:
  - protocol: HTTP
    port: 80
    name: http
    allowedRoutes:
      kinds:
      - kind: HTTPRoute
      namespaces:
        from: Selector
        selector:
          matchLabels:
            shared-gateway-access: "true"


---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: second-app
  namespace: second
spec:
  parentRefs:
  - name: shared-gateway
  rules:
  - matches:
    - path:
        value: /second
  - backendRefs:
    - name: nginx
      port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: testing-app
  namespace: testing
spec:
  parentRefs:
  - name: shared-gateway
  rules:
  - matches:
    - path:
        value: /testing
  - backendRefs:
    - name: nginx
      port: 80

app.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        command:
          - "/bin/sh"
          - "-c"
        args:
          - 'echo "node hostname: $MY_NODE_NAME; namespace: $MY_POD_NAMESPACE" > /usr/share/nginx/html/index.html && exec nginx -g "daemon off;"'
        env:
          - name: MY_NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: MY_POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: kubernetes.io/hostname

svc.yml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

Note: I have added the label shared-gateway-access: "true" to the default namespace. The nginx deployment and services have been created in the testing and second namespace.

Have I misconfigured my gateway and/or my HTTProute or does Traefik doesn't currently support the cross-namespace routing ?