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

Add HealthCheck for KubernetesCRD ExternalName services #10467

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

Conversation

marcmognol
Copy link
Contributor

@marcmognol marcmognol commented Feb 23, 2024

What does this PR do?

This PR adds the possibility to configure HealthChecks for external named services.

Motivation

In some cases, we need to be able to configure HealthChecks on ExternalName services configured with CRD.
With this PR it will be possible to do the following :

---
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr
spec:
  weighted:
    services:
       - name: external-svc1
         scheme: https
         port: 443
       - name: external-svc2
         scheme: https
         port: 443
         healthCheck:
           hostname: static.ifs.asf.pri
           path: /landing-page
           interval: 15
           followRedirects: false

Big thanks to @StephanSalas for the inspiration.

Closes #8147
Closes #8541

More

  • Added/updated tests
  • Added/updated documentation

Additional Notes

@marcmognol
Copy link
Contributor Author

marcmognol commented Feb 23, 2024

Hi @emilevauge,

This PR is related to issue #8147 for which you requested help from the community.
I would like, if you may, tell me if I am on the right direction with this draft PR ?

Then, if it is ok, I'll add unit tests and documentation.

I tested these modifications and it answers my need.

Thanks for your help.

Marc

@marcmognol marcmognol marked this pull request as ready for review February 25, 2024 10:55
@marcmognol
Copy link
Contributor Author

Hello,

Do I have to rebase it on v2.11 or can I keep it on master ?

Thanks.

@nmengin
Copy link
Contributor

nmengin commented Feb 26, 2024

Hey @marcmognol,

No need to rebase the PR (it's an enhancement).
We mark it as design-review to allow the team to check your PR design before moving forward on the review.

@kevinpollet
Copy link
Member

Hello @marcmognol and thanks for this contribution,

Instead of allowing the user to define the server URLs in a TraefikService, we would prefer to leverage K8s ExternalName services and provide a property allowing the user to enable healtchecks for ExternalName services.

As explained in #8541 (comment), I think you can get some inspiration from #8663. If that is ok for you, could you please also give some credits to @StephanSalas in the pull request description?

@marcmognol
Copy link
Contributor Author

Hello @kevinpollet

Thank you for your reply.

I choose to do this way, because I thought it is easier to configure with the CRD only.

So, I followed your advice, and thanks to the PR of @StephanSalas I was able to add some changes to this PR.

Could you please tell me if I am in the right direction before going further ? Editing the title of this PR and add reference to the previous PR of @StephanSalas.

So, with this method, I can define Health Check on the service level.
My concerns is that when I define 2 services for a single Ingress Route, Traefik will create 3 services, 2 of type Load Balancer and one of type Weighted.

Is there any performance downside compared to a single service of type Load Balancer?
What is the difference between this configuration and a single Load Balancer?

Thanks for your answers.

Marc

@marcmognol
Copy link
Contributor Author

Hello @kevinpollet

I can achieve having single LoadBalancer with CRD when I use static Endpoints object for a Service. But I can only use IP address, I am not able to use FQDN of external services on the Endpoint.

That's why I think addind CRD LoadBalancer type can be a great idea.

Please let me know if we could also implement CRD for LoadBalancer?

Thanks

@kevinpollet
Copy link
Member

Hello @marcmognol and sorry for the late answer,

Is there any performance downside compared to a single service of type Load Balancer?
What is the difference between this configuration and a single Load Balancer?

There is not a real performance downside. This is because, in the IngressRoute configuration, it is possible to configure a weight for the service, which implies using a WRR. This is not true anymore since #10372, but this should not be changed in this PR.

I can achieve having single LoadBalancer with CRD when I use static Endpoints object for a Service. But I can only use IP address, I am not able to use FQDN of external services on the Endpoint.

Here I am not sure to follow can you elaborate?

Regarding the code, here https://github.com/traefik/traefik/pull/10467/files#diff-7d5c919304c65587ab6f978e73008d6d268e9bbb6db829eadf8d72f4f492e28fR306 the health check has to be set up only for external name services. For other services, we want to rely only on K8s healtcheck, did I miss something?

@marcmognol
Copy link
Contributor Author

Hello @kevinpollet,

Thanks for your reply.
It is good to know there is no performance downside regarding wrr and it seeams that it is something I could use in my situation.
I also need to pay attention that each request going through this ingressroute is transferred to the same service, so I need to use sticky cookie, but AFAIK the sticky cookie is set on the WRR level not the loabalancer itself.

In fact I would need to convert the following file configuration into CRDs:

  services:
    uat-service:
      loadBalancer:
        serversTransport: uat-transport
        servers:
          - url: https://localserver-1.asf.pri:443
          - url: https://localserver-2.asf.pri:443
        healthCheck:
          hostname: uat.local.pri
          path: /landing-page/
          interval: 15s
        sticky:
          cookie:
            secure: true
            httpOnly: true

Where keeping sticky cookie and health checks are mandatory.
That's why this PR implements the creation of CRD for LoadBalancer which is for my point of view the best solution.
But, feel free to tell what would be the best solution.

Thanks for your help on this.

@kevinpollet
Copy link
Member

kevinpollet commented Mar 26, 2024

Hello @marcmognol,

I think there is a misunderstanding, #8147 and #8541 are about adding the health check feature for ExternalName services. For other K8s service types, we want to use the orchestrator health check which adds or removes endpoints dynamically to the corresponding services.

If I am not missing something by using ExternalName services it is already possible to do what you want, we are just missing the healtcheck feature (please note that the following option has to be enabled).

Something like:

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: foo
spec:
  routes:
    - match: Host(`foo.com`)
      kind: Rule
      services:
        - name: wrr
          kind: TraefikService

---
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr
spec:
  weighted:
    services:
       - name: external-svc1
         scheme: https
         port: 443
       - name: external-svc2
         scheme: https
         port: 443

---
apiVersion: v1
kind: Service
metadata:
  name: external-svc1
spec:
  externalName: localserver-1.asf.pri
  type: ExternalName

---
apiVersion: v1
kind: Service
metadata:
  name: external-svc2
spec:
  externalName: localserver-2.asf.pri
  type: ExternalName

Does it make sense?

@marcmognol
Copy link
Contributor Author

Hello @kevinpollet

Yes it makes sense thank you. What about the sticky cookie which is required for me to ensure each request is routed to right service ?

If it is possible, then I'll update actual PR to add HealthCheck feature.

Marc

@kevinpollet
Copy link
Member

Hello @marcmognol,

Yes it makes sense thank you. What about the sticky cookie which is required for me to ensure each request is routed to right service ?

I missed to add the sticky configuration in the example, as explained in https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#stickiness-and-load-balancing it is possible to configure the stickiness at the WRR level.

@marcmognol marcmognol changed the title Add LoadBalancer type in TraefikService CRD Add HealthCheck for external name services Mar 28, 2024
@marcmognol marcmognol changed the title Add HealthCheck for external name services Add HealthCheck for KubernetesCRD ExternalNamedServices Mar 28, 2024
@marcmognol
Copy link
Contributor Author

Hello @kevinpollet
Thanks for everything. I've updated the PR. Could you please have a look ?

Thanks.

@kevinpollet
Copy link
Member

Hello @marcmognol, did I miss something, the code is still adding the health check configuration for all services? (https://github.com/traefik/traefik/pull/10467/files#diff-7d5c919304c65587ab6f978e73008d6d268e9bbb6db829eadf8d72f4f492e28fR306)

@marcmognol
Copy link
Contributor Author

Hello @kevinpollet
You're right, I've added a check (+ unit test) when service type is not ExternalName and HealthCheck is defined.
Am I in the right direction ?

Thanks

@marcmognol
Copy link
Contributor Author

@kevinpollet I rebased my branch and now tests are failing. Could you please tell me if I am in the right direction before fixing my code to fit new unit tests ?

Thanks

@kevinpollet kevinpollet changed the title Add HealthCheck for KubernetesCRD ExternalNamedServices Add HealthCheck for KubernetesCRD ExternalName services Apr 22, 2024
@kevinpollet
Copy link
Member

Hello @marcmognol,

Sorry for the late answer, you are in the right direction, I added some suggestions.
Thanks for the work.

@marcmognol
Copy link
Contributor Author

Hi @kevinpollet

Thanks for your feedback.
Feel free to tell me if I can do more for this PR.

Marc

@kevinpollet
Copy link
Member

Hi @marcmognol,

Last thing, could you add some documentation in the following section https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#kind-ingressroute?

Could you also rebase the pull request to fix the CI?

@marcmognol marcmognol marked this pull request as draft April 23, 2024 11:31
@marcmognol marcmognol force-pushed the load-balancer-crd branch 2 times, most recently from 3bcd690 to b6eb02b Compare April 23, 2024 11:56
@marcmognol marcmognol marked this pull request as ready for review April 23, 2024 12:00
@marcmognol
Copy link
Contributor Author

@kevinpollet

Thanks for your comment.
I've rebased the PR, but during this process I've made some mistakes, so I had to force push... Sorry.
I also added some documentation as requested.

Marc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants