GithubHelp home page GithubHelp logo

microsoft / service-fabric-traefik Goto Github PK

View Code? Open in Web Editor NEW
14.0 18.0 13.0 63.08 MB

service-fabric-traefik contains services to fetch endpoint information from Service Fabric and expose Traefik endpoints.

License: MIT License

PowerShell 23.10% Batchfile 2.45% Shell 5.08% Go 68.88% Dockerfile 0.49%

service-fabric-traefik's Introduction

ServiceFabricTraefik 1.1.0

The reverse proxy is an application, supplied out of band from the service fabric distribution, that customers deploy to their clusters and handles proxying traffic to backend services. The service, that potentially runs on every node in the cluster, takes care of handling endpoint resolution, automatic retry, and other connection failures on behalf of the clients. The reverse proxy can be configured to apply various policies as it handles requests from client services.

Using a reverse proxy allows the client service to use any client-side HTTP communication libraries and does not require special resolution and retry logic in the service. The reverse proxy is mostly a terminating endpoint for the TLS connections unless the TCP option is used.

Note that, at this time, this is a reverse proxy built-in replacement and not a generic service fabric “gateway” able to handle partition queries, but that might be added (via customer written plugins or similar) in the future.

How it works

As of this release, the services need to be explicitly exposed via service extension labels, enabling the proxying (HTTP/TCP) functionality for a particular service and endpoint. With the right labels’ setup, the reverse proxy will expose one or more endpoints on the local nodes for client services to use. The ports can then be exposed to the load balancer in order to get the services available outside of the cluster. The required certificates needed should be already deployed to the nodes where the proxy is running as is the case with any other Service Fabric application.

Using the application

You can clone the repo, build, and deploy or simply grab the latest ZIP/SFPKG application from Releases section, modify configs, and deploy.

alt text

alt text

Deploy it using PowerShell

After either downloading the sf app package from the releases or cloning the repo and building, you need to adjust the configuration settings to meet to your needs (this means changing settings in Settings.xml, ApplicationManifest.xml and any other changes needed for the traefik-template.yaml configuration).

If you need a quick test cluster, you can deploy a test Service Fabric managed cluster following the instructions from here: SFMC, or via this template if you already have a client certificate and thumbprint available: Deploy

Retrieve the cluster certificate TP using: $serverThumbprint = (Get-AzResource -ResourceId /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCEGROUP/providers/Microsoft.ServiceFabric/managedclusters/$CLUSTERNAME).Properties.clusterCertificateThumbprints

#cd to the top level directory where you downloaded the package zip
cd \downloads

#Expand the zip file

Expand-Archive .\service-fabric-traefik.zip -Force

#cd to the directory that holds the application package

cd .\service-fabric-traefik\windows\

#create a $appPath variable that points to the application location:
#E.g., for Windows deployments:

$appPath = "C:\downloads\service-fabric-traefik\windows\TraefikProxyApp"

#For Linux deployments:

#$appPath = "C:\downloads\service-fabric-traefik\linux\TraefikProxyApp"

#Connect to target cluster, for example:

Connect-ServiceFabricCluster -ConnectionEndpoint @('sf-win-cluster.westus2.cloudapp.azure.com:19000') -X509Credential -FindType FindByThumbprint -FindValue '[Client_TP]' -StoreLocation LocalMachine -StoreName 'My' # -ServerCertThumbprint [Server_TP]

# Use this to remove a previous Traefik Application
#Remove-ServiceFabricApplication -ApplicationName fabric:/traefik -Force
#Unregister-ServiceFabricApplicationType -ApplicationTypeName TraefikType -ApplicationTypeVersion 1.1.0 -Force

#Copy and register and run the Traefik Application
Copy-ServiceFabricApplicationPackage -CompressPackage -ApplicationPackagePath $appPath # -ApplicationPackagePathInImageStore traefik
Register-ServiceFabricApplicationType -ApplicationPathInImageStore traefik

#Fill the right values that are suitable for your cluster and application (the default ones below will work without modification if you used a Service Fabric managed cluster Quickstart template with one node type. Adjust the placement constraints to use other node types)
$p = @{
    ReverseProxy_InstanceCount="1"
    ReverseProxy_FetcherEndpoint="7777"
    ReverseProxy_HttpPort="8080"
    ReverseProxy_CertificateSearchKeyword=""
    ClusterEndpoint="https://localhost:19080"
    CertStoreSearchKey="sfmc"
    ClientCertificate=""
    ClientCertificatePK=""
    ReverseProxy_EnableDashboard="true"
    #ReverseProxy_PlacementConstraints="NodeType == NT2"
}
$p
New-ServiceFabricApplication -ApplicationName fabric:/traefik -ApplicationTypeName TraefikType -ApplicationTypeVersion 1.1.0 -ApplicationParameter $p


#OR if updating existing version:  

Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/traefik -ApplicationTypeVersion 1.1.0 -Monitored -FailureAction rollback

Add the right labels to your services

ServiceManifest file

This is a sample SF enabled service showing some of the supported labels. If the sf name is fabric:/pinger/PingerService, the endpoint [endpointName] will be expose at that prefix: '/pinger/PingerService/'.

  ...
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="PingerServiceType" UseImplicitHost="true">
      <Extensions>
        <Extension Name="traefik">
        <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
          <Label Key="traefik.http.defaultEP">true</Label>
          <Label Key="traefik.http.defaultEP.service.loadbalancer.passhostheader">true</Label>
          <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.path">/</Label>
          <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.interval">10s</Label>
          <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.scheme">http</Label>
        </Labels>
        </Extension>
      </Extensions>
    </StatelessServiceType>
  </ServiceTypes>
  ...

The only required label to expose a service via the reverse proxy is the traefik.http.[endpointName] set to true. Setting only this label will expose the service on a well known path and handle the basic scenarios.

http(s)://<Cluster FQDN | internal IP>:Port/ApplicationInstanceName/ServiceInstanceName?PartitionGuid=xxxxx

If you need to change the routes or add middleware then you can add different labels configuring them.

Supported Labels

Most of all the traefik http, tcp and tls dynamic configurations can be configured via their corresponding service extension label. The list below is only an overview of all supported labels. Refer to exampleServiceManifest.xml under /eng to view a more comprehensive list. If a label is missing then follow a similar format to add the traefik config that you desire.

Http enable section

  • traefik.http.[endpointName] Enables exposing an http service via the reverse proxy ['true']

Router section

  • traefik.http.[endpointName].router.rule Traefik rule to apply [PathPrefix(/api))]. This rule is added on top of the default path generation. If this is set, you have to define a middleware to remove the prefix for the service to receive the stripped path.
  • traefik.http.[endpointName].router.tls.options Enable TLS on the route ['optionName'].

Loadbalancer section

  • traefik.http.[endpointName].service.loadbalancer.passhostheader passhostheaders ['true'/'false']
  • traefik.http.[endpointName].service.loadbalancer.serversTransport serversTransport name ['serversTransportName']
  • traefik.http.[endpointName].service.loadbalancer.healthcheck.path Healthcheck endpoint path ['/healtz']
  • traefik.http.[endpointName].service.loadbalancer.healthcheck.interval Healthcheck interval ['10s']
  • traefik.http.[endpointName].service.loadbalancer.healthcheck.scheme Healthcheck scheme ['http']
  • traefik.http.[endpointName].service.loadbalancer.timeout.interval Healthcheck timeout ['30s']
  • traefik.http.[endpointName].service.loadbalancer.sticky.cookie.sameSite Sticky session affinity cookie ['none'/'lax'/'strict']

Middleware section

  • traefik.http.[endpointName].middlewares.[middlewareName].stripPrefix.prefixes prefix to strip ['/api']

TLS section

  • traefik.tls.option.[optionName].minVersion tls min version option ['VersionTLS12']
  • traefik.tls.store.default.[defaultCertificate].certFile path to cert ['path/to/cert.crt']
  • traefik.tls.store.default.[defaultCertificate].keyFile path to cert key ['path/to/cert.key']
  • traefik.tls.certificate.[certName].certFile path to cert ['path/to/cert.cert']
  • traefik.tls.certificate.[certName].keyFile path to cert key ['path/to/cert.key']

ServersTransport section

  • traefik.http.serversTransport.[serversTransportName].insecureSkipVerify disables SSL certificate verification ['true'/'false']

Sample Test application

A sample test application, that is included in the release, can be deployed to test everything is working. After deployment, you should be able to reach it at:

https://ClusterFQDN:8080/pinger0/PingerService/id

Note that the service is going to be exposed on https since the service has a label for the route.tls option. You can explore that looking at the service manifest for this app.

# Sample pinger app for validating (navidate to /pinger0/PingerService/id on https)
#Remove-ServiceFabricApplication -ApplicationName fabric:/pinger$i -Force
#Unregister-ServiceFabricApplicationType -ApplicationTypeName PingerApplicationType -ApplicationTypeVersion 1.0 -Force

$appPath = "C:\downloads\service-fabric-traefik\windows\pinger-traefik"

Copy-ServiceFabricApplicationPackage -CompressPackage -ApplicationPackagePath $appPath -ApplicationPackagePathInImageStore pinger-traefik
Register-ServiceFabricApplicationType -ApplicationPathInImageStore pinger-traefik

$p = @{
    "Pinger_Instance_Count"="3"
    "Pinger_Port"="7000"
    #"Pinger_PlacementConstraints"= "NodeType == NT2"
}

New-ServiceFabricApplication -ApplicationName fabric:/pinger0 -ApplicationTypeName PingerApplicationType -ApplicationTypeVersion 1.0 -ApplicationParameter $p

Traefik Reverse Proxy for Service Fabric Integration

Project Structure

This repo includes:

  • TraefikProxyApp: an example Service Fabric application, referencing two guest executables:
    • server.exe: Performs service discovery on a sf cluster, fetches endpoint information and publishes the config to be consumed in real-time
    • traefik.exe: Implements a reverse proxy using Traefik config read from the dynamic config file

Clone, Build and get Latest Executables

  1. Users can clone the github repo and make changes to server/fetcher app under /serviceFabricDiscoveryService. Once changes have been made the binary can be manually built ("go build ./cmd/server") and moved to the correct sf code package ("./TraefikProxyApp/ApplicationPackageRoot/TraefikPkg/Fetcher.Code").

  2. Get latest traefik.exe from traefik github page and place it under its corresponding sf code package ("./TraefikProxyApp/ApplicationPackageRoot/TraefikPkg/Code")

Updating manifest file

TraefikProxyApp comes with an ApplicationManifest and ServiceManifest for both windows and linux. By default the .xml files contains the content for a windows cluster deployment. For a linux deployment need to replace with the linux xml content.

Also, you can open TraefikSF.sln at the root of the repo with Visual Studio 2019. Running builds and deploying to local or remote SF clusters instead of using local powershell prompt.

serviceFabricDiscoveryService

serviceFabricDiscoveryService is a service that connects to a Service Fabric cluster and exposes discovery data and changes [async] over websockets or, locally, via a file. Changes on names (applications/services) and endpoint mapping information is sent as messages over the websocket as they happen, the client doesn't have to poll the server.

The service exposes several websocket routes that have specific functionality.

Running the server

NAME:
   discoveryService - exposes service fabric application and service metadata over websockets

USAGE:
   server.exe [global options] command [command options] [arguments...]

COMMANDS:
   run      runs as a server
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --loglevel value, -l value  debug level, one of: info, debug (default: "info") [%LOGLEVEL%]
   --help, -h                  show help (default: false)
NAME:
   server.exe run - runs as a server

USAGE:
   server.exe run [command options] [arguments...]

OPTIONS:
   --clusterEndpoint value, -e value     cluster endpoint [http://localhost:19080] [%CLUSTER_ENDPOINT%]
   --clientCertificate value             path or content for the client certificate [%CLIENT_CERT%]
   --clientCertificatePK value           path or content for the client certificate private key [%CLIENT_CERT_PK%]
   --certStoreSearchKey value, -k value  keyword to look for searching the cluster certificate (windows cert store) [%CLUSTER_CERT_SEARCH_KEY%]
   --httpport value, -p value            port for the HTTP rest endpoint (server will be disabled if not provided) (default: 0) [%HTTP_PORT%]
   --insecureTLS, -i                     allow skip checking server CA/hostname (default: false) [%INSECURE_TLS%]
   --publishFilePath value, -f value     filename to write to, empty won't write anywhere [%PUBLISH_FILE_PATH%]
   --help, -h                            show help (default: false)

Supported routes

ws://{hostname:port}/api/traefik:

This route exposes a stream of Traefik 2.x compatible yaml data that can be fed directly into the Traefik file provider. The returned data maps routing rules for service instances running on the cluster, taking into account the Health and Status of each of the services in order to ensure requests are only routed to healthy service instances.

Running Locally

  • Deploy TraefikProxyApp to the local cluster

  • Deploy the pinger test application mentioned in Sample-Test-Application. Using a browser access https://localhost/pinger0/PingerService. If all works, you should get a 200 OK response with contents resembling the following:

    {
      "Pinger: I'm alive on ... "
    }

Credits

The discovery mechanism is based on Traefik made by Traefik Labs.

License

This software is released under the MIT License

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

service-fabric-traefik's People

Contributors

craftyhouse avatar dario-ms avatar dariopb avatar egaribay77 avatar mahons avatar microsoft-github-operations[bot] avatar microsoftopensource avatar mmatur avatar nmengin avatar nokjuh avatar shesamian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

service-fabric-traefik's Issues

Loadbalancer labels not being picked up.

Label configuration :

  <Extensions>
    <Extension Name="Traefik">
      <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
        <Label Key="traefik.http.PingerEndpoint0">true</Label>
        <Label Key="traefik.http.PingerEndpoint0.router.entrypoints">websecure</Label>
        <Label Key="traefik.http.PingerEndpoint0.router.rule">PathPrefix(`/weatherforecast`)</Label>
        <Label Key="traefik.http.PingerEndpoint0.loadbalancer.passhostheader">true</Label>
        <Label Key="traefik.http.PingerEndpoint0.loadbalancer.healthcheck.path">/weatherforecast</Label>
        <Label Key="traefik.http.PingerEndpoint0.loadbalancer.healthcheck.interval">10s</Label>
        <Label Key="traefik.http.PingerEndpoint0.loadbalancer.healthcheck.scheme">https</Label>
      </Labels>
    </Extension>
  </Extensions>

Fetcher Out put :

fabric-Application3-Web1-http-PingerEndpoint0-317677a7-7d03-4406-8d36-929eb6658f8b:
  loadBalancer:
    passHostHeader: null
    servers:
    - Port: ""
      Scheme: ""
      url: http://ASAZ-XXXXXXXX:9022

None of the load balancer values are written to the traefik configuration file

Brief window of routing traffic to container before it's ready

• Service Fabric publishes container instance endpoints immediately as the instance starts, but before the application in the container is ready to handle traffic. This will cause Traefik to start routing requests there, even though they will fail. Traefik health check will then notice that the instance is not available, and stop routing traffic there until the instance is available.
• This causes about 5 to 30 second period when some requests may go to the new instance before it's ready, and will fail.
• This probably only causes issues with new connections, since existing connections will have sticky session cookie pointing to another instance.
• Fixing this would require Service Fabric to publish endpoints only when the instance is ready. This info is available to Service Fabric through Docker health checks (in use in our containers) and a Readiness Check (not currently enabled in our containers). However, neither of those will currently prevent the endpoints from being published. Microsoft received our feedback on Azure Connection Programs Yammer about the Readiness Check not working as expected, but did not promise anything.
• Alternatively Traefik could change its behavior to not assume new endpoints are healthy, if not as default then at least as an option. There is an open feature request for this, opened in 2019: traefik/traefik#4544

Fetcher generating duplicate routers & services

The fetcher appears to be generating duplicate routers and services for every router and service defined as part of a single application.

See below example of dynamically generated config whereby routers and service config differs only by name.

http:
  middlewares:
    sf-stripprefixregex_nonpartitioned:
      stripPrefixRegex:
        regex:
        - ^/[^/]*/[^/]*/*
  routers:
    fabric-Application2-Web1-http-defaultEP:
      entryPoints:
      - websecure
      middlewares:
      - sf-stripprefixregex_nonpartitioned
      rule: PathPrefix(`/WeatherForecast`)
      service: fabric-Application2-Web1-http-defaultEP
      tls:
        options: "false"
    fabric-Application2-Web1-http-defaultEP-861ef74e-6895-4f76-b4d0-d257f48a923d:
      entryPoints:
      - websecure
      middlewares:
      - sf-stripprefixregex_nonpartitioned
      rule: PathPrefix(`/WeatherForecast`)
      service: fabric-Application2-Web1-http-defaultEP-861ef74e-6895-4f76-b4d0-d257f48a923d
      tls:
        options: "false"
  services:
    fabric-Application2-Web1-http-defaultEP:
      loadBalancer:
        healthCheck:
          followRedirects: null
          interval: 10s
          path: /healthcheck
          scheme: http
        passHostHeader: true
        servers:
        - Port: ""
          Scheme: ""
          url: http://machinename:8311
    fabric-Application2-Web1-http-defaultEP-861ef74e-6895-4f76-b4d0-d257f48a923d:
      loadBalancer:
        healthCheck:
          followRedirects: null
          interval: 10s
          path: /healthcheck
          scheme: http
        passHostHeader: true
        servers:
        - Port: ""
          Scheme: ""
          url: http://machinename:8311

ServiceManifest labels defined :

<ServiceTypes>
    <!-- This is the name of your ServiceType. 
         This name must match the string used in RegisterServiceType call in Program.cs. -->
    <StatelessServiceType ServiceTypeName="Web1Type" >
      <Extensions>
        <Extension Name="traefik">
          <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
            <Label Key="traefik.http.defaultEP">true</Label>
            <Label Key="traefik.http.defaultEP.router.entryPoints">websecure</Label>
            <Label Key="traefik.http.defaultEP.router.rule">PathPrefix(`/WeatherForecast`)</Label>
            <Label Key="traefik.http.defaultEP.router.tls.options">false</Label>
            <Label Key="traefik.http.defaultEP.service.loadbalancer.passhostheader">true</Label>
            <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.path">/healthcheck</Label>
            <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.interval">10s</Label>
            <Label Key="traefik.http.defaultEP.service.loadbalancer.healthcheck.scheme">http</Label>
          </Labels>
        </Extension>
      </Extensions>
    </StatelessServiceType>
  </ServiceTypes>

Is this by design?

sf-stripprefixregex_nonpartitioned

It appears that middleware is automatically assigned to any routes which are picked up from the traefik labels.

the middleware assigned is :

sf-stripprefixregex_nonpartitioned:

      stripPrefixRegex:
        regex:
        - ^/[^/]*/[^/]*/*

for the following traefik labels

<Label Key="traefik.http.api">true</Label>
<Label Key="traefik.http.api.router.entrypoints">websecure</Label>
<Label Key="traefik.http.api.router.rule">PathPrefix(`/part1/part2/`)</Label>
<Label Key="traefik.http.api.router.tls.options" />
<Label Key="traefik.http.api.service.loadbalancer.passhostheader">true</Label>
<Label Key="traefik.http.api.service.loadbalancer.healthcheck.path">/part1/part2/v1/healthcheck</Label>
<Label Key="traefik.http.api.service.loadbalancer.healthcheck.interval">10s</Label>
<Label Key="traefik.http.api.service.loadbalancer.healthcheck.scheme">https</Label>

This results in the path being stripped and any request to ,for example, /part1/part2/v1/healthcheck is re-written to be v1/healthcheck which no longer matches a valid route.

The only solution found so far to prevent the rewriting is to specify a specific middleware rule which does not match. for example

<Label Key="traefik.http.api.middlewares.ignoreStrip.stripPrefix.prefixes">/nomatch</Label>

This ensures the path is not re-written using the sf-stripprefixregex_nonpartitioned middleware rule but is obviously not very elegant

Configuring TLS

According to your documentation :

traefik.http.[endpointName].router.tls.options Enable TLS on the route ['true'/'false']. 

This results in the following router set up

    fabric-Application2-Web1-http-defaultEP-1d6dda1e-6a45-4bb9-bbd9-2ed7c11a4fe9:
      entryPoints:
      - websecure
      middlewares:
      - sf-stripprefixregex_nonpartitioned
      rule: PathPrefix(`/WeatherForecast`)
      service: fabric-Application2-Web1-http-defaultEP-1d6dda1e-6a45-4bb9-bbd9-2ed7c11a4fe9
      tls:
        options: "true"

The intended use of options is to provide a reference to defined options, rather than a Boolean value

https://doc.traefik.io/traefik/routing/routers/#tls

Also there is no way to configure TLS with no options specified ie

http:
  routers:
    Router-1:
      rule: "Host(`foo-domain`) && Path(`/foo-path/`)"
      service: service-id
      # will terminate the TLS request
      tls: {}

Træfik not starting on a one-box windows dev cluster

I tried deploying the release pkg to my one-box dev cluster (1 node configuration).
But traefik does not start (the pinger service seems to start just fine).

I tried figuring out how the scripts are invoked and how they are supposed to configure traefik in an atttempt to start it manually first (and see any errors), but there seems to be multiple script files included an multiple partial yaml templates as well.

I understand the lack of docs at this point, so:
Is there something special I need to be aware of when running this on my local machine (instead of a managed instance in Azure).

Unexpected labels cause failure

If an unexpected label is encountered it causes the fetcher application to crash. This results in no configuration file written at all.

This could cause an outage across all services if the label configuration in just one service is incorrect,

The fetcher should skip a service upon unexpected labels, and should still continue to iterate the remaining services and output the configuration for all the services with good label configuration.

Legacy Traefik and Managed Cluster

Can we deploy legacy Traefik to a managed cluster? It requires certificate info for TLS connection, and we are not sure where to get that for managed clusters. We have been trying different settings with no luck.

Support multiple routing rules with separate health checks

Service Fabric plugin should support different routing and health checks for each hostname per instance.

E.g. we may direct contoso.example.com and sample.example.com traffic to a specific container application. Currently the health check is on the container instance level, so either any hostname can be directed to an instance or none will be directed there. However, it is possible that e.g. contoso.example.com is not responding correctly on one instance, even if the instance level health check succeeds and sample.example.com requests work on that instance.

In that case we would like to be able to stop directing traffic with contoso.example.com to the one instance where it's not working, but continue routing sample.example.com traffic to that instance.

v2 labels do not work side by side with v1 labels.

Sample configuration of service labels for traefik V1

<Extensions>
            <Extension Name="Traefik">
                <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
                    <Label Key="traefik.enable">true</Label>
                    <Label Key="traefik.frontend.passHostHeader">true</Label>
                    <Label Key="traefik.frontend.rule">PathPrefix: /weatherforecast</Label>
                    <Label Key="traefik.backend.healthcheck.path">/healthcheck</Label>
                </Labels>
            </Extension>
  </Extensions>

To allow for the seamless transition of V1 to V2 it would be helpful if both sets of labels could be supported side by side.

Currently any service with the above v1 configuration causes the fetcher application to crash . (Related to #10)

Service Fabric plugin does not work with Traefik 3.0

The same configuration that works with Traefik 2.9.6 and Service Fabric plugin 1.0.0 breaks when updating Traefik to 3.0.0-beta2. I would expect the Service Fabric plugin to continue working after updating Traefik.

Broken with beta of Traefik 3.0:
2022-12-28T08:47:36Z INF Traefik version 3.0.0-beta2 built on 2022-12-07T16:32:34Z version=3.0.0-beta2
2022-12-28T08:47:36Z INF
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://doc.traefik.io/traefik/contributing/data-collection/

2022-12-28T08:47:36Z INF Starting provider aggregator aggregator.ProviderAggregator
2022-12-28T08:47:36Z INF Starting provider *file.Provider
2022-12-28T08:47:36Z INF Starting provider *traefik.Provider
2022-12-28T08:47:36Z INF Starting provider *acme.ChallengeTLSALPN
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 5, expected one of [1]" entryPointName=web routerName=fabric-Contoso1-Contoso-http-Contoso-e0327b43-b1ac-45cc-b97c-1c7ea028aed9@file
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 3, expected one of [1]" entryPointName=web routerName=fabric-Contoso2-Contoso-http-Contoso@file
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 3, expected one of [1]" entryPointName=web routerName=fabric-Contoso2-Contoso-http-Contoso-9210ff31-e116-411c-bf64-f9c0da4edeb1@file
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 3, expected one of [1]" entryPointName=web routerName=fabric-Contoso3-Contoso-http-Contoso@file
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 3, expected one of [1]" entryPointName=web routerName=fabric-Contoso3-Contoso-http-Contoso-32ede899-f044-4ed9-a442-ec4da2340a5a@file
2022-12-28T08:47:37Z ERR error="unexpected number of parameters; got 5, expected one of [1]" entryPointName=web routerName=fabric-Contoso1-Contoso-http-Contoso@file
2022-12-28T08:47:37Z WRN No domain found in rule PathPrefix(/), the TLS options applied for this router will depend on the SNI of each request entryPointName=internal routerName=api@file
2022-12-28T08:47:42Z ERR Error while Peeking first bytes error=EOF
2022-12-28T08:47:43Z ERR Error while Peeking first bytes error=EOF
2022-12-28T08:47:43Z ERR Error while Peeking first bytes error=EOF
2022-12-28T08:47:47Z ERR Error while Peeking first bytes error=EOF

The "Peeking first bytes" errors continue indefinitely and no requests go through.

Working after reverting back to the current latest release:
time="2022-12-28T09:22:05Z" level=info msg="Traefik version 2.9.6 built on 2022-12-07T14:17:58Z"
time="2022-12-28T09:22:05Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n"
time="2022-12-28T09:22:05Z" level=info msg="Starting provider aggregator aggregator.ProviderAggregator"
time="2022-12-28T09:22:05Z" level=info msg="Starting provider *file.Provider"
time="2022-12-28T09:22:05Z" level=info msg="Starting provider *traefik.Provider"
time="2022-12-28T09:22:05Z" level=info msg="Starting provider *acme.ChallengeTLSALPN"
time="2022-12-28T09:22:05Z" level=warning msg="No domain found in rule PathPrefix(/), the TLS options applied for this router will depend on the SNI of each request" entryPointName=internal routerName=api@file

Fetcher Logging

Is there any option to output fetcher logging to Application Insights?

Sticky session support missing

Load balancer sticky session support is missing, along with related settings which are required for modern browsers. This is present in the Traefik 1.7 plugin. For us this is necessary to be able to use Traefik.

      <Label Key="traefik.http.loadbalancer.stickiness">true</Label>
      <Label Key="traefik.http.loadbalancer.stickiness.secure">true</Label>
      <Label Key="traefik.http.loadbalancer.stickiness.httpOnly">true</Label>
      <Label Key="traefik.http.loadbalancer.stickiness.sameSite">none</Label>
      <Label Key="traefik.http.loadbalancer.stickiness.cookieName">stickycookie</Label>

See below for how this was implemented in the previous repository:
dariopb/traefikServiceFabricPlugin@eed4680

Allow using a certificate from the Windows certificate store via key word matching

Users usually rely on loading the TLS certs from files into Traefik, which works pretty well on containers. When Traefik is running directly on a windows VM it would be better to reference the certificate from the cert store. Currently, Traefik doesn't have any certificate store implementation on the OSS version, other than a file as mentioned.

Traefik is working on making a more generic library but already has the building blocks to support additional certificate stores. There is no ETA when this will be added as Traefik team is still discussing the priority and effort from their side.

If there is a need use a certificate from the Windows certificate store via key word matching, please refer to this commit to add this support on Traefik: dariopb/traefik@59ddd47. This will require forking the repo and adding the above changes and building the go app to retrieve the traefik executable. After this configure the env variable "ReverseProxy_CertificateSearchKeyword" as part of sf application manifest when deploying sf traefik app.

Support Service Fabric Request Drain

• When a container goes down, there is about 5 to 30 second time when requests may still be routed there, before Traefik health check notices the instance is down.
• For planned container downtime, Service Fabric offers Request Drain feature. This should stop returning the endpoints from Service Fabric API for a time before actually taking them down.
• Traefik uses GetReplicas method to get the endpoints (https://github.com/dariopb/serviceFabricDiscoveryService/blob/e4b897a1a9f5c6d2e0e8c5980ba7bb3284c9daa0/pkg/discovery/discoveryworker.go#L244, https://github.com/jjcollinge/servicefabric/blob/8eebe170fa1ba25d3dfb928b3f86a7313b13b9fe/servicefabric.go#L140)
• The problem is that the current Service Fabric API method (GetReplicas) used to get the endpoints, does not stop advertising them during the request drain period (microsoft/service-fabric#1264). There is another method (ResolvePartition) which stops advertising the endpoints as expected, but it returns stale information unless given a parameter which needs to be changed in every call (microsoft/service-fabric#80).
• Fixing this would require one of the following:
• Microsoft fixes the current GetReplicas method used by Traefik
• Or that Microsoft fixes the ResolvePartition method and Traefik plugin is changed to use the other method
• Or that Traefik switches to using the ResolvePartition method with its current implementation, and e.g. makes 2 calls each time: First to get stale data and the parameter needed to get updated information, and second to get the updated information.

Using stripPrefix and addprefix middlewares together is not supporting

Using multiple middlewares stripPrefix and addprefix at a time is not working, as it is considering single middleware which mentioned in last.
Please see the sample below.

`

  <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
      <Label Key="traefik.http.defaultEP">true</Label>
      <Label Key="traefik.http.defaultEP.router.rule">PathPrefix(`/sample`)</Label>
      <Label Key="traefik.http.defaultEP.middlewares.1.stripPrefix.prefixes">/sample</Label>
      <Label Key="traefik.http.defaultEP.middlewares.2.addprefix.prefix">/api</Label>
  </Labels>
` @Mahons Any suggestion on this

Traefik returning 404 while cluster is performing rolling upgrade

Good afternoon @craftyhouse ,

Two questions in regards to this, and I apologize if this is in the wrong place to bring this up.

Background: An issue we are experiencing with using traefik (legacy has traefik running in a docker container on the sf cluster) and not necessarily the repo in question. The issue is when SF upgrades and a node goes down, services that are being communicated with through traefik are being migrated to another node and no longer on the node with traefik. Traefik on that node then receives a request for the service in question and returns a 404 since traefik on that node doesn't have an application of that instance.

Questions

  1. Do you know if this new repo would address this issue? I'm assuming it would potentially address this issue by being aware that the sf cluster is currently shutting down the node in question and handle it in some given way.
  2. Do you know if this scenario would persist when this reverse proxy solution eventually gets implemented, or would it be handled gracefully by the cluster and the built in reverse proxy.

Support multiple container endpoints

Currently the Traefik Service Fabric plugin only routes traffic to one container endpoint, the first one it happens to find (https://github.com/dariopb/serviceFabricDiscoveryService/blob/e4b897a1a9f5c6d2e0e8c5980ba7bb3284c9daa0/pkg/discovery/discoveryworker.go#L284).

It should allow configuring routing to different endpoints with different rules. E.g. if path is /webclient, route to container endpoint "web", if path is /mobileclient, route to container endpoint "mobile".

Random 404 errors in traffic routing

When there are lots of requests going to a Service Fabric cluster, some of them will fail to 404 error. This varies how often it happens, between about 1 to 30 minutes between errors. Then there will be a period of a few seconds where some requests fail to 404 errors. These errors happen often enough that the Service Fabric plugin cannot be used in heavy production use. These errors did not happen with Traefik 1.7.

Based on analyzing the Traefik and Service Fabric plugin logs, this is caused by the Service Fabric dynamic configuration sometimes being read by Traefik as completely empty on one Service Fabric node's Traefik, then returning to normal a few seconds later the next time Traefik reads the configuration. Based on discussions with Traefik support, this seems to be caused by specific timing when reading the Service Fabric configuration, so that the configuration file is either missing or empty just as it's being read.

It seems that this is likely caused by the configuration file handling but I don't know it could be fixed.

err := os.WriteFile(disco.publishFilePath, data, 0644)

err := os.WriteFile(disco.publishFilePath, data, 0644)

The Traefik logs will show something like:
...00:00:05Z" level=debug msg="Skipping unchanged configuration." providerName=file
...00:00:08Z" level=debug msg="Configuration received:
...00:00:10Z" level=debug msg="Configuration received:
...00:00:12Z" msg="Skipping unchanged configuration." providerName=file

Service Fabric plugin debug logs will show:
...00:00:03Z" level=debug msg="New snapshot arrived:
...00:00:08Z" level=debug msg="New snapshot arrived:
...00:00:13Z" level=debug msg="New snapshot arrived:

Most likely the Service Fabric plugin is writing new configuration at 00:00:08 at some exact timing when Traefik is reading the configuration file, and Traefik gets empty or missing file.

Service Fabric plugin is configured to write the configuration (PUBLISH_FILE_PATH) to "..\work\sf_discovered.yaml" and Traefik is configured to read the directory (which has also traefik_dynamic.toml with other settings):
[providers]
[providers.file]
directory = "../work"
watch = true

This is currently preventing us from taking Traefik 2.x into use with Service Fabric.

Client certificates are not loaded when the Discovery URL doesn't use https

If you define your ClusterEndpoint as http://localhost:19080 as per the example (and my own use case), and you're using certificates to manage Authentication, then then the server app fails to connect to the cluster as the client certificate is not loaded.

I believe the first condition in the following code is unnecessary as this requires a client certificate, which has no bearing on the transport mechanism.

if strings.HasPrefix(p.clusterManagementURL, "https") &&
		(config.CertStoreSearchKey != "" || (config.CertificateKey != "" && config.Certificate != "")) {
		p.tlsConfig = &certstorehelper.ClientTLS{
			Cert:               config.Certificate,
			Key:                config.CertificateKey,
			CertStoreSearchKey: config.CertStoreSearchKey,
			InsecureSkipVerify: config.InsecureSkipVerify,
		}
	}

I'll raise a PR to update the code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.