containous / traefik-extra-service-fabric

Traefik extra: Service Fabric Provider
Apache License 2.0
12 stars 14 forks source link

Service Fabric endpoint selection not working when listening on multiple ports #45

Closed lurock closed 4 years ago

lurock commented 5 years ago

Do you want to request a feature or report a bug?

Bug

What did you do?

I setup service fabric configuration with two listening endpoints. One for the web endpoint and one for a healthcheck endpoint. Here is the service fabric configuration with Traefik labels:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="CustomerApiPkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType. 
         This name must match the string used in RegisterServiceType call in Program.cs. -->
    <StatelessServiceType ServiceTypeName="CustomerApiType">
      <Extensions>
        <Extension Name="Traefik">
          <Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
            <Label Key="traefik.frontend.rule.customer">PathPrefix: /api/customer/</Label>
            <Label Key="traefik.portName">WebPort</Label>
            <Label Key="traefik.backend.healthcheck.path">/api/customer/</Label>
            <Label Key="traefik.backend.healthcheck.port">8261</Label>
            <Label Key="traefik.backend.healthcheck.interval">1s</Label>
            <Label Key="traefik.enable">true</Label>
            <Label Key="traefik.frontend.passHostHeader">true</Label>
          </Labels>
        </Extension>
      </Extensions>
    </StatelessServiceType>
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>CustomerApi.exe</Program>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
    <EnvironmentVariables>
      <EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value=""/>
    </EnvironmentVariables>
  </CodePackage>

  <!-- Config package is the contents of the Config directoy under PackageRoot that contains an 
       independently-updateable and versioned set of custom configuration settings for your service. -->
  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to 
           listen. Please note that if your service is partitioned, this port is shared with 
           replicas of different partitions that are placed in your code. -->
      <Endpoint Protocol="http" Name="WebPort" Type="Input" Port="80" />
      <Endpoint Protocol="http" Name="HealthCheckPort" Type="Input" Port="8261" />
    </Endpoints>
  </Resources>
</ServiceManifest>

What did you expect to see?

I expect Traefik to serve up the WebPort endpoint.

What did you see instead?

What happens is Traefik sometimes serves up the WebPort endpoint and then sometimes serves up the HealthCheckPort endpoint. It appears that the Traefik Label "traefik.portName" is having no affect over selecting the endpoint to serve web traffic through.

Output of traefik version: (What version of Traefik are you using?)

v1.7.6

What is your environment & configuration (arguments, toml, provider, platform, ...)?

Running Traefik as a guest executable on Service Fabric. Here is my toml configuration:

################################################################
# Global configuration
################################################################

# Enable debug mode
#
# Optional
# Default: false
#
debug = true

# Traefik logs file
# If not defined, logs to stdout
#
# Optional
#
# traefikLogsFile = "log/traefik.log"

# Log level
#
# Optional
# Default: "ERROR"

logLevel = "INFO"

# Entrypoints to be used by frontends that do not specify any entrypoint.
# Each frontend can specify its own entrypoints.
#
# Optional
# Default: ["http"]
#
defaultEntryPoints = ["http", "https"]

# Entrypoints definition
#
# Optional
# Default:
[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.traefik]
  address = ":9000"

# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
#
# [accessLog]

# Sets the file path for the access log. If not specified, stdout will be used.
# Intermediate directories are created if necessary.
#
# Optional
# Default: os.Stdout
#
# filePath = "/path/to/log/log.txt"

# Format is either "json" or "common".
#
# Optional
# Default: "common"
#
# format = "common"

################################################################
# API definition
################################################################

[api]
  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
  entryPoint = "traefik"

  # Enabled Dashboard
  #
  # Optional
  # Default: true
  #
  dashboard = true

  # Enable debug mode.
  # This will install HTTP handlers to expose Go expvars under /debug/vars and
  # pprof profiling data under /debug/pprof.
  # Additionally, the log level will be set to DEBUG.
  #
  # Optional
  # Default: false
  #
  debug = true

################################################################
# Service Fabric provider
################################################################

# Enable Service Fabric configuration backend
[servicefabric]

# Service Fabric Management Endpoint
clustermanagementurl = "http://localhost:19080"
# Note: use "https://localhost:19080" if you're using a secure cluster

# Service Fabric Management Endpoint API Version
apiversion = "3.0"

# Enable TLS connection.
#
# Optional
#
#[serviceFabric.tls]
#  cert = "certs/servicefabric.crt"
#  key = "certs/servicefabric.key"
#  insecureskipverify = true
lawrencegripper commented 5 years ago

Yes this is a bug in the current provider. #42 covers this in some more detail.

One option to workaround this limitation is to create a custom template which uses the getNamedEndpoint function. This can be used to return a specific endpoint for a service.

I think that with this set to use WebPort as the endpoint name the healthcheck and service should behave as normal but this is something that would need to be tested.

If you'd be interested in submitting a PR to look at addressing this issue for others too that would be awesome and very well received. The first steps would be to comment on #42 with a proposal for how you'd like to approach the fix and then we can do a quick review before you start working.

lawrencegripper commented 5 years ago

@lurock Thanks for the PR (#47) just referencing here to keep track.