haproxytech / kubernetes-ingress

HAProxy Kubernetes Ingress Controller
https://www.haproxy.com/documentation/kubernetes/
Apache License 2.0
713 stars 200 forks source link

Haproxy does not handle Services of the type ExternalName #100

Open martivo opened 4 years ago

martivo commented 4 years ago

Hi, when creating a service of the type "ExternalName" and an ingress pointing towards it, then the ingress controller keeps repeating:

2019/10/15 10:30:23 controller.go:194: Endpoint for service <service name> does not exists

This type of service will never have an endpoint. It would make sense to use the returned CNAME as the backend pool server that is returned by the service.

Tested with.

HAProxy Ingress Controller v1.2.3 7fc1cd6

See https://kubernetes.io/docs/concepts/services-networking/service/#externalname

This functionality does work with nginx-ingress controller.

martivo commented 4 years ago

I have tested the older haproxy ingress, it does work with it.

The backend configuration in haproxy pod is created properly:

backend default-test-80
    mode http
    balance roundrobin
    server loovsys.eu:80 loovsys.eu:80 weight 1 check inter 2s

The service YAML used:

apiVersion: v1
kind: Service
metadata:
  name: test
spec:
  externalName: loovsys.eu
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  sessionAffinity: None
  type: ExternalName

The ingress YAML used:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: test.entigo.com
    http:
      paths:
      - backend:
          serviceName: test
          servicePort: 80
        path: /

https://github.com/jcmoraisjr/haproxy-ingress/blob/master/pkg/common/ingress/controller/controller.go#L1386

From the source code of this project i found no mentions of ExternalName. Perhaps it is possible to implement it in the new haproxy ingress too.

bedis commented 4 years ago

That looks interesting! Basically, this means we must enable DNS resolver for this one.

Mo3m3n commented 3 years ago

Currently IC handles this but without runtime DNS resolution. Runtime DNS resolution is planned for 1.6

yogeek commented 3 years ago

Hello,

Sorry but I do not understand the previous comments regarding this issue

We installed the latest HA proxy ingress controller with helm (0.12.3 which seems to correspond to 2.2.13 haproxy version when we check in the pod) and we just encountered this issue with externalName service as a backend. Is this issue meant to be fixed in this version ? @Mo3m3n when you say Currently CI handles this : does it mean that it is meant to work with our version ?

mecampbellsoup commented 2 years ago

@Mo3m3n long time no see man!

I asked about (sort of) this same issue in Slack: https://haproxy.slack.com/archives/CR9N5UNAZ/p1634152029118800

Related issue seems to be that I cannot have multiple ingresses, which define different values for backend-config-snippet, to the same backend (only one backend ends up written to haproxy.cfg whose name seems to be of the format {namespace}-{serviceName}.

I tried to add ExternalName services for the additional ingresses I am adding but I get the same error described in this ticket:

2021-10-13T19:38:53.645964522Z 2021/10/13 19:38:53 INFO    controller.go:229 HAProxy restarted
2021-10-13T19:38:53.671083267Z [WARNING] 285/193853 (52) : parsing [/etc/haproxy/haproxy.cfg:178] : 'server SRV_1' : could not resolve address 'login.coreweave.cloud', disabling server.
2021-10-13T19:39:03.684371926Z [WARNING] 285/193853 (52) : parsing [/etc/haproxy/haproxy.cfg:191] : 'server SRV_1' : could not resolve address 'login.coreweave.test', disabling server.
pmorch commented 2 years ago

Has this been fixed?

https://github.com/haproxytech/kubernetes-ingress/releases/tag/v1.6.5 has as the only Changlog entry that:

de4ccd8 MAJOR: add option to disable forwarding to ExternalName Services

Presumably that means that forwarding to ExternalName Services otherwise works in version v1.6.4+

akarshjain40 commented 2 years ago

We have a Haproxy Ingress Controller and I have a requirement to forward request to cloudfront so I am using ExternalName service type with cloudfront url and I can see cloudfront url being added in haproxy config file But when I hit it returns 503, but if I give cloudfront ip it works , and also I am able to do dig/nslookup so I dont think its a dns issue . Can anyone please tell what might be the issue here and why its giving 503?

ivanmatmati commented 2 years ago

Hi @akarshjain40 can you post the configuration file especially the cloudfront backend part? I've tested externalName with latest IC version and google as external service. It seems to work.

akarshjain40 commented 2 years ago

apiVersion: v1 kind: Service metadata: name: frontend-cdn annotations: haproxy.org/check: "true" haproxy.org/backend-config-snippet: | default-server init-addr none sni req.hdr(Host) check-sni str(xxxxxx.xxxxx.net) resolve-prefer ipv4 spec: type: ExternalName externalName: xxxxx.xxxx.net ports:

davidledev commented 2 years ago

Hi, can you check with haproxy.org/check: "false, because I think if you have "ssl handshake failure", your haproxy configuration is not set. For me I have a error adding the annotation haproxy.org/server-ca: "ns/secret. I obtain the log msg="Fatal errors found in configuration.

akarshjain40 commented 2 years ago

Hi, I had checked with false its still same, and there is no log of ssl handshake failure its just 503 even when it is true

Mo3m3n commented 2 years ago

@mecampbellsoup When using ExternalName, the address of the backend server is a DNS name. If there is no resolvers configured in haproxy, it will only resolve it once at startup using system resolvers configured in your haproxy node. If this is not working for you, then maybe your config-snippet is messing with the setup, or it is just that there are no resolvers in you haproxy node. Anyway to go a step further and be able to resolve dns names at runtime in haproxy you will need to configure a resolvers section, which is a more robust solution cause the ip address of a DNS name may change at haproxy runtime.

Mo3m3n commented 2 years ago

@pmorch What you have mentioned is a different subject. Implementing ExternalNames can expose the CVE-2021-25740 vulnerability, so an option was added to disable ExternalNames support.

Mo3m3n commented 2 years ago

@akarshjain40

haproxy.org/backend-config-snippet: | default-server init-addr none sni req.hdr(Host) check-sni str(xxxxxx.xxxxx.net) resolve-prefer ipv4

This is the type of config-snippet that I was talking about here which is changing the resolving behavior at startup.
By default Ingress Controller configures init-addr last,libc,none which makes haproxy use the system resolver (libc). When you change it to none, haproxy won't do any resolution at startup.

EDIT: I suggest you remove the config-snippet cause even the sni part may not be required in your case, what you need instead is to set the server-ssl annotation to true since in your case the target server is expecting encrypted traffic (server port 443). However if you still want to change the default-server behavior then keep at least the init-addr last,libc,none

Should you need more help, please send the haproxy config of the corresponding backend and related haproxy traffic logs.

riyasyash commented 2 years ago

Hi, Do we have a workaround for supporting externalName?

renchap commented 1 year ago

There does not seem to be any support for this at the moment, when you configure a ExternalName service then your Ingress has this error: <error: endpoints "service-name" not found>

Edit: the error above shows when you describe the Ingress resource, but the haproxy configuration is correctly pointing to the external server. When configured properly (SNI, Hostname…) then everything works 🎉

riyasyash commented 11 months ago

Guess we can support ExternalName services by configuring this: Option 1:

controller:
  hostNetwork: false

Option 2: removed --disable-service-external-name

imdmahajankanika commented 1 week ago

Hello, Is there any update on this issue?