external-dns icon indicating copy to clipboard operation
external-dns copied to clipboard

No endpoints could be generated from HTTPRoute for no reason

Open pkit opened this issue 1 year ago • 6 comments

time="2024-05-07T03:58:32Z" level=debug msg="No endpoints could be generated from HTTPRoute foo/bar"

And that's it. There's no other logs that can shed any light on why it cannot be generated. Looking at this atrocity I see a lot of places where it can go wrong, but zero debug logging. Nice!

pkit avatar May 07 '24 04:05 pkit

Namespace discrepancy between Gateway and HttpRoute. eh Why not print a log line on that?

pkit avatar May 07 '24 15:05 pkit

We also stumbled about this. But we would really like to be able define gateways and route in different namespaces.

@pkit Do you know if Is this not possible (rbac or whatever) or just not implemented as a feature?

jakoberpf avatar Jun 11 '24 14:06 jakoberpf

Gateways can have many different Listeners and Routes aren't required to match all of them. The logs would be really noisy if every non-match was logged when this is a commonly expected case. However, it is not expected for a Gateway to have accepted a Route AND for no Listener match to be found. This case is logged in the code you linked.

https://github.com/kubernetes-sigs/external-dns/blob/fa17f9d06cbfe3315430529151324fae5a421e43/source/gateway.go#L360

It also logs several other potential issues...

  • If the parent is an unknown/unsupported type (i.e. not a Gateway): https://github.com/kubernetes-sigs/external-dns/blob/fa17f9d06cbfe3315430529151324fae5a421e43/source/gateway.go#L298
  • If the Gateway couldn't be found: https://github.com/kubernetes-sigs/external-dns/blob/fa17f9d06cbfe3315430529151324fae5a421e43/source/gateway.go#L305
  • If the Gateway is attached to the Route but hasn't accepted it: https://github.com/kubernetes-sigs/external-dns/blob/fa17f9d06cbfe3315430529151324fae5a421e43/source/gateway.go#L310

Gateways, Routes, and Services can cross namespace boundaries, but this must be explicitly allowed. It doesn't happen by default. In your case, @pkit, this is why the Gateway never attached to the Route. Please see the Gateway API's security model for more details (cc @jakoberpf).

I think external-dns should do its best to convert the state of your cluster resources to DNS entries. I don't think it should try to determine the user's true intentions and diagnose misconfigurations of resource specifications. It just takes what it's given.

That said, since it's already logging that no endpoints were found it could also specify that no Gateways were attached.

abursavich avatar Jul 13 '24 23:07 abursavich

@abursavich Thanks for elaborating that. Indeed providing the right namespace allow selectors on the gateway fixed my issue.

jakoberpf avatar Jul 20 '24 08:07 jakoberpf

Faced completely the same issue. For instance, I want to terminate TLS on GW side, so there is certificate attached to listener section.

listeners:  
    - allowedRoutes:
        namespaces:
          from: All
      name: web-secure
      port: 8443
      hostname: example.com
      protocol: HTTPS
      tls:
        certificateRefs:
          - kind: Secret
            group: ""
            name: example-secret
        mode: Terminate

So on GW side it is HTTPS protocol, while with HTTPRoute there is no protocol (per se) that you can specify. Now why I think DNS cannot be provisioned.

It is b/c of this function.

There it says if protocols do not match between GW & HTTPRoute that route will be just skipped.

// Confirm that the Listener and Route protocols match.
if !gwProtocolMatches(rt.Protocol(), lis.Protocol) {
  continue
}

Regarding HTTPRoute the only protocol is the one defined by kubernetes service and when web based it is TCP.

Can you advise which protocol is taken into consideration on HTTPRoute side, or perhaps it can be good enough if that condition would be omitted? Thanks.

zargor avatar Aug 28 '24 14:08 zargor

@zargor, HTTPRoute matches both HTTP and HTTPS protocols on the Listener.

The first thing to look for is if the Route has been accepted by the Gateway. You can check the Route status for that. If the Gateway hasn't accepted the Route the Gateway won't serve the Route, so ExternalDNS won't match them together either. If the Route has been accepted by the Gateway, then there might be a problem with ExternalDNS. In either case, I'd be happy to help you debug your issue if you provide the full Gateway and HTTPRoute resources, including status. Feel free to obscure the IPs and hostnames if desired, but not so much that it changes the hostname matching semantics.

abursavich avatar Aug 28 '24 15:08 abursavich

Sure @abursavich , thanks, here are described gateway and httroute respectfully:

Gateway:

Name:         traefik-g2
Namespace:    traefik
Labels:       app.kubernetes.io/instance=traefik-traefik
              app.kubernetes.io/name=traefik
Annotations:  <none>
API Version:  gateway.networking.k8s.io/v1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2024-08-30T14:27:54Z
  Generation:          1
  Resource Version:    1361676557
  UID:                 cecaf3f9-ecaa-495e-805d-0856580077f7
Spec:
  Gateway Class Name:  traefik
  Listeners:
    Allowed Routes:
      Namespaces:
        From:  All
    Name:      web
    Port:      8000
    Protocol:  HTTP
    Allowed Routes:
      Namespaces:
        From:  All
    Name:      web-mtls
    Port:      8443
    Protocol:  HTTPS
    Tls:
      Certificate Refs:
        Group:
        Kind:   Secret
        Name:   server-secret
      Mode:     Terminate
Status:
  Conditions:
    Last Transition Time:  2024-08-30T14:27:54Z
    Message:               Gateway successfully scheduled
    Observed Generation:   1
    Reason:                Accepted
    Status:                True
    Type:                  Accepted
    Last Transition Time:  2024-08-30T14:27:54Z
    Message:               Gateway successfully scheduled
    Observed Generation:   1
    Reason:                Programmed
    Status:                True
    Type:                  Programmed
  Listeners:
    Attached Routes:  0
    Conditions:
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                Programmed
      Status:                True
      Type:                  Programmed
    Name:                    web
    Supported Kinds:
      Group:          gateway.networking.k8s.io
      Kind:           HTTPRoute
    Attached Routes:  1
    Conditions:
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:               No error found
      Observed Generation:   1
      Reason:                Programmed
      Status:                True
      Type:                  Programmed
    Name:                    web-mtls
    Supported Kinds:
      Group:  gateway.networking.k8s.io
      Kind:   HTTPRoute
Events:       <none>

HTTPRoute:

Name:         route-ws
Namespace:    some-namespace
Labels:       <none>
Annotations:  external-dns.alpha.kubernetes.io/hostname: example.com
API Version:  gateway.networking.k8s.io/v1
Kind:         HTTPRoute
Metadata:
  Creation Timestamp:  2024-08-29T12:22:29Z
  Generation:          1
  Resource Version:    1361676554
  UID:                 b5535d72-5b5e-400f-80f3-9654f21f92a3
Spec:
  Hostnames:
    example.com
  Parent Refs:
    Group:         gateway.networking.k8s.io
    Kind:          Gateway
    Name:          traefik-g2
    Namespace:     traefik
    Port:          8443
    Section Name:  web-mtls
  Rules:
    Backend Refs:
      Group:
      Kind:    Service
      Name:    ws-deployment
      Port:    8443
      Weight:  1
    Matches:
      Path:
        Type:   PathPrefix
        Value:  /
Status:
  Parents:
    Conditions:
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2024-08-30T14:27:54Z
      Message:
      Observed Generation:   1
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
    Controller Name:         traefik.io/gateway-controller
    Parent Ref:
      Group:         gateway.networking.k8s.io
      Kind:          Gateway
      Name:          traefik-g2
      Namespace:     traefik
      Port:          8443
      Section Name:  web-mtls
Events:              <none>

zargor avatar Aug 30 '24 14:08 zargor

@zargor, the only thing that's jumping out at me is that the Gateway doesn't have any IP addresses in its status. The Gateway and the HTTPRoute are attached and ExternalDNS should agree, but it doesn't have any addresses to use for DNS records.

https://github.com/kubernetes-sigs/external-dns/blob/master/docs/sources/gateway.md#targets

abursavich avatar Aug 30 '24 15:08 abursavich

@zargor, the only thing that's jumping out at me is that the Gateway doesn't have any IP addresses in its status. The Gateway and the HTTPRoute are attached and ExternalDNS should agree, but it doesn't have any addresses to use for DNS records.

https://github.com/kubernetes-sigs/external-dns/blob/master/docs/sources/gateway.md#targets

In this case, it is about external NLB which comes with its own generic/default dns record. But yes, I suppose there can be an issue, since gateway Address is not populated. On the other hand ,my sense is that external dns should try to create CNAME based on the k8s service, which is responsible for NLB.

zargor avatar Sep 09 '24 07:09 zargor