© Rahul Sharma, Akshay Mathur 2021
R. Sharma, A. MathurTraefik API Gateway for Microserviceshttps://doi.org/10.1007/978-1-4842-6376-1_2

2. Configure Traefik

Rahul Sharma1   and Akshay Mathur2
(1)
Patpargunj, Delhi, India
(2)
Gurgaon, Haryana, India
 

In the last chapter, you looked at how the adoption of microservices has changed the requirements of behaviors expected from a gateway component. Traefik was built to support all these needs. There are various ways to configure Traefik; configuration can be passed from a file, parameters, or environment variables. It has sensible defaults for all unspecified configuration. You also looked at the API and the dashboard available in Traefik. In this chapter, let’s build upon where you left off by taking a deep dive into various ways to configure Traefik to expose a few endpoints.

This chapter covers the basics of routing. It discusses the various components used in routing. We introduce a small sample application that you use throughout this chapter. The Traefik routing configuration is applied to expose this application to the external world. In this chapter, you try to manually configure Traefik to expose a simple service. In later chapters, you can build upon this to leverage Traefik’s autoconfiguration capabilities.

Configuration Topics

Let’s cover the following Traefik configuration to expose a sample application on the Traefik gateway.
  • Entrypoints

  • Providers

  • Routers
    • Rules

    • Middleware

  • Services

The interaction between these configuration pieces is shown in Figure 2-1. We describe each in detail as you move forward.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig1_HTML.jpg
Figure 2-1

Traefik configuration architecture

Introduction to Sample Web Service

Before proceeding to the Traefik configuration, let’s look at the sample application to expose in Traefik. We use this simple web API throughout this chapter to serve traffic through Traefik.

This simple service is written in Go (as shown in Listing 2-1) and listens on HTTP port 9080. It returns a “Hello World” string on the default path “/”.
main.go
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", handler)
log.Println("Server listening on port 9080...")
log.Fatal(http.ListenAndServe(":9080", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
}
Listing 2-1

Simple Web API Written in Go

Note

You need to have Go 1.1.3 installed on your system to run this example. However, it does not need any other special requirements apart from that. A discussion of Go installation and execution is beyond the scope of this book; however, the official Go documentation is very comprehensive.

In the last chapter, you saw how to install and set up Traefik in stand-alone mode on the machine. Here, you use Traefik CLI. All the examples in this chapter are run on macOS. However, you should be able to easily follow along if you have Go and Traefik CLI installed.

When you run the Go service, you see the console message in Listing 2-2.
hello-world-service> go run main.go
2020/05/02 20:34:26 Server listening on port 9080...
Listing 2-2

Running the Go web API

When you open this URL in the browser, you see the following (see Figure 2-2).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig2_HTML.jpg
Figure 2-2

Screenshot of browser open to URL http://localhost:9080/

And you see the following with curl on the command line (see Listing 2-3).
hello-world-service> curl localhost:9080
Hello, World
Listing 2-3

Testing the API endpoint with curl

For the rest of this chapter, we run this sample application and configure Traefik to expose this application’s endpoint. In the course of this, we explore the various Traefik configuration pieces.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig3_HTML.jpg
Figure 2-3

Exposing “Hello World” Go service on Traefik

Note

For the rest of this chapter, the terms upstream and downstream describe directional requirements in relation to the message flow: all messages flow from upstream to downstream. The terms inbound and outbound describe directional requirements in relation to the request route: inbound means toward the origin server and outbound means toward the user agent. This is per the HTTP specification RFC 7230 Section 2.3 (https://tools.ietf.org/html/rfc7230#section-2.3).

Traefik Configuration

Traefik has two ways of providing configuration: static and dynamic (see Figure 2-4).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig4_HTML.jpg
Figure 2-4

Different configuration types in Traefik

Static configuration is provided at startup time through the following mechanisms. It does not change once Traefik starts up.
  • File

  • CLI

  • Environment variables

For static configuration, you configure Traefik first through CLI, then environment variables, and finally, static file configuration.

You define entrypoints in a static configuration—a file or CLI. Entrypoints are the port definition for the ports on which Traefik listens for incoming TCP/UDP traffic.

Providers are the other part of the puzzle which must be specified in a static startup configuration. Providers give Traefik its power. Dynamic configuration , such as routers and services, is changed and refreshed at runtime and configured through providers. Instead of having to manually configure each downstream service, Traefik can instead talk to your service catalog via a set of preconfigured providers. There are providers for Docker, Kubernetes, and Consul, as well as stores such as files and key-value stores such as etcd. This allows Traefik to automatically expose downstream services on the edge. In this chapter, you are specifying the dynamic configuration by manually using FileProvider. In later chapters, you take a deeper dive into how Traefik integrates with other providers, such as Consul and Kubernetes.

Entrypoints

Traefik configuration defines a set of entrypoints (or port numbers) where incoming requests are listened for. These entrypoints can serve HTTP, TLS, gRPC, or TCP traffic. You can define an entrypoint for each backend service you want to expose through the Traefik edge gateway. Entrypoints define the low-level details of addresses, protocols, headers, transport details such as timeouts, and TLS details.

Before you get started defining the entrypoints, let’s first revisit how you want to run Traefik and establish how you are observing the defined configuration at runtime. You start Traefik from the command line without any other configuration. To observe the results of the configuration in further steps, you also enable the Traefik web dashboard by passing the '--api.dashboard=true' flag.

Starting Traefik with CLI Arguments

➜  ~ ./traefik --api.dashboard=true --api.insecure=true
INFO[0000] Configuration loaded from flags.
Listing 2-4

Start Traefik with command line arguments

Listing 2-4 starts up Traefik on localhost on port 8080 with the Traefik dashboard exposed with the default configuration. The dashboard is served up under the /api/dashboard/ route.

By default, Traefik recommends exposing the dashboard in secure mode; since you just want to see the dashboard right now without much configuration, you start it in insecure mode with the '--api.insecure=true' flag. Note that this is not recommended for a production use case.

As you can see in Figure 2-5, the Traefik dashboard has a set of sections that allow you to observe all the capabilities configured and enabled in Traefik. Currently, only the default configuration is exposed yet in the Traefik instance.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig5_HTML.jpg
Figure 2-5

Screenshot of Traefik dashboard open on http://localhost:8080/

There are two entrypoints defined by default.
  • A default HTTP entrypoint listening on port 80

  • An entrypoint named Traefik listening on port 8080 which provides access to the dashboard

The dashboard is not exposed via any special mechanism. Traefik exposes it using a standard entrypoint configuration. Below the entrypoints, you see the routers, middleware, and services categorized by protocol—HTTP, TCP, and UDP. As you move forward, you drill down into these further sections you see on the dashboard.

As you can see, there a bunch of entrypoints, routers, middleware, and services defined by Traefik. The next step is to expose a downstream service using these same mechanisms.

As you have seen, by default Traefik already listens on port 80 (default HTTP) and 8080 (dashboard HTTP) when you enable the web dashboard.

Let’s define the own entrypoint to expose the “Hello World” Go service already discussed through Traefik.

First, you need to define an entrypoint. This is done at startup time in a static configuration using one of the following approaches.
  • CLI arguments

  • Environment variables

  • Configuration file traefik.yml in the current directory

Starting Traefik with Entrypoint Defined with CLI

➜ ~ ./traefik --api.dashboard=true --api.insecure=true  --entryPoints.web.address=:80
INFO[0000] Configuration loaded from flags.
Listing 2-5

Traefik entrypoint defined through command line argument

Listing 2-5 defines an entrypoint called the web that listens on port 80. This overrides the default HTTP entrypoint that you saw earlier on port 80 (see Figure 2-6).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig6_HTML.jpg
Figure 2-6

Entrypoints in Traefik dashboard open on http://localhost:8080/

When you try accessing this port on the localhost from cURL, you see the output in Listing 2-6. Traefik is listening to this port, but there is no service at the backend connected to this port yet.
hello-world-service> curl localhost
404 page not found
Listing 2-6

Testing the localhost 80 port with curl

We successfully exposed the entrypoint using command-line parameters to define the static configuration. Next, let’s try doing the same using environment variables.

Starting Traefik with Entrypoint Defined in Environment Variables

You execute the following commands in the terminal to start up Traefik with an entrypoint named web exposed on port 80 (see Listing 2-7).
traefik-config> export TRAEFIK_API_DASHBOARD=true
traefik-config> export TRAEFIK_API_INSECURE=true
traefik-config> export TRAEFIK_ENTRYPOINTS_WEB_ADDRESS=":80"
traefik-config> traefik
INFO[0000] Configuration loaded from environment variables.
Listing 2-7

Starting Traefik with entrypoint configuration in environment variables

When you access this endpoint in the browser, you see the same results as before (see Figure 2-7).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig7_HTML.jpg
Figure 2-7

No backend service connected to port 80 yet

Command-line arguments and environment variables are fine to play around with; however, for the rest of this chapter, you are providing all configuration via files. This is the recommended way to configure Traefik as file configuration is simple and less prone to typos and errors. It can also be tracked easily in source control, enabling more of a GitOps model. Next, let’s see how to achieve that.

Entrypoint Defined with Config File Traefik.yml in the Current Directory

The Traefik static configuration file can be supplied in multiple ways.
  • Traefik.yml file in the current directory

  • Traefik.yml file in $HOME/.config

  • Location of the file passed in as a command-line argument to the CLI

    --configFile=path/to/traefik-static-config.yml

For simplicity, we restrict the Traefik configuration file to the current directory for the rest of this chapter.

TOML vs. YAML

There are two competing formats to define file configuration in Traefik: TOML and YAML .

While the Traefik team prefers TOML, all the configuration examples in this chapter are in YAML. TOML is a lesser-known and obscure format, while YAML is widely supported in various platforms and is the default declarative state configuration format for both the Docker and Kubernetes ecosystems. Instead of learning a new format for defining simple configuration, let’s stick to YAML for all needs. YAML has full-feature parity with TOML in all matters of Traefik configuration.

The traefik.yml file in the current directory specifies the entrypoint, as shown in Listing 2-8. You also add the configuration to enable the dashboard here in this file instead of enabling it in the command line.
# Entrypoints have to be defined as static configuration in traefik.yml
entryPoints:
  web:
   address: ":80"
api:
  insecure: true
  dashboard: true
Listing 2-8

Traefik Static YAML Configuration

For comparison, the same configuration in TOML format is defined in Listing 2-9. You do not use this; it is just included for reference.
# Entrypoints have to be defined as static configuration in traefik.yml
[entryPoints]
  [entryPoints.web]
  address = ":80"
[api]
insecure = true
dashboard = true
Listing 2-9

Traefik Static TOML Configuration

Let’s now start up Traefik with the static YAML configuration.
traefik-config> ./traefik
INFO[0000] Configuration loaded from file: /Users/akshay/traefik-book/traefik-config/traefik.yml
Listing 2-10

Startup Traefik with static file configuration

When you start up Traefik (see Listing 2-10), it automatically picks up the traefik.yml file in the current directory. The result of this is the same as seen in the previous two subsections.

Routers

For each entrypoint exposed by Traefik, corresponding routers must be attached to route traffic flow further. Routers consist of two components.
  • A set of rules. Each incoming request on an entrypoint is matched against this set of rules.

  • A set of middleware. Each request matched by a rule can be transformed using a corresponding middleware. Middleware is where all the specialized gateway capabilities of authentication and rate limiting are carried out.

Now that the entrypoint is exposed, connect the backend Go API to the entrypoint using router configuration. Let’s first look at the default routers defined in the Traefik dashboard.

There are two HTTP routers defined by default. When you click ‘Explore ->’ in the Routers section on the main page, you see the what’s shown in Figure 2-8.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig8_HTML.jpg
Figure 2-8

Drill down to default HTTP routers.

  • The first route defined under ‘/api’ is the default parent route named api@internal.

  • The second route under ‘/’ is the dashboard route named ‘dashboard@internal’.

You can drill down further into these routers and check their details (see Figures 2-9 and 2-10). These routes serve the traffic for the API and dashboard, respectively.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig9_HTML.jpg
Figure 2-9

Detail view of api@internal HTTP router

../images/497627_1_En_2_Chapter/497627_1_En_2_Fig10_HTML.jpg
Figure 2-10

Detail view of dashboard@internal HTTP router

You must define the HTTP routers to show similarly on the Traefik dashboard. From this point onward, you are leveraging the FileProvider to specify the dynamic configuration. Traefik can talk to the service discovery mechanism of your platform through supported providers. For the simple use case, you are specifying all the configuration in a file, which is easily supported by Traefik. All configuration for routers, middleware, and services is specified through dynamic configuration. There are two ways to specify the FileProvider configuration .
  • The individual file specified through the filename

  • The entire directory of configuration files, which is the recommended method in production because you can divide up the various configurations into multiple files

In Listing 2-11, you specify a single filename in the current directory where you put all the dynamic configurations. Traefik then watches this file for any changes, and configuration is refreshed automatically within Traefik.
# Entrypoints have to be defined as static configuration in traefik.yml
entryPoints:
  web:
   address: ":80"
providers:
  file:
    filename: "traefik-dynamic-conf.yml"
    watch: true
api:
  insecure: true
  dashboard: true
Listing 2-11

Dynamic configuration file name defined in static cofiguration

Router Rules

In the traefik-dynamic-conf.yml dynamic configuration file, you first define the HTTP router and its routing rule (see Listing 2-12).
http:
  routers:
    router0:
      entryPoints:
      - web
      service: hello-world
      rule: Path(`/hello-world`)
Listing 2-12

traefik-dynamic-conf.yml dynamic configuration file

Once all the configuration is set up, you run Traefik CLI in the same directory (see Listing 2-13).
traefik-config> ./traefik
INFO[0000] Configuration loaded from file: /Users/akshay/code/k8s/traefik-book/traefik-config/traefik.yml
ERRO[2020-05-13T09:22:17+05:30] the service "hello-world@file" does not exist entryPointName=web routerName=router0@file
ERRO[2020-05-13T09:22:18+05:30] the service "hello-world@file" does not exist entryPointName=web routerName=router0@file
Listing 2-13

Running Traefik with router rule in dynamic configuration file

You defined a rule to match a request path (/hello-world) to a backend service that is not yet configured, so Traefik throws up a console error on startup. You see a similar error in the dashboard (see Figure 2-11). The HTTP router section shows an error. Also of interest is the Providers section at the bottom of the page, which now has an entry for FileProvider.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig11_HTML.jpg
Figure 2-11

Dashboard view with HTTP router

The next piece of the router to configure should be middleware; however, we will skip it for now and come back later. First, you configure the service backend and get the communication working end-to-end.

Services

Services define the actual targets where the request must be routed. They are the actual API endpoints that you want to expose through Traefik. Note that the service type must match the router type (e.g., HTTP router can only be attached to HTTP service). After matching and transforming requests, routers forward them to services you wish to expose.

Before defining the service, let’s look at the default services configured in the Traefik dashboard. There are three HTTP services defined. When you click ‘Explore ->’ in the Services section, you see what’s shown in Figure 2-12.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig12_HTML.jpg
Figure 2-12

Dashboard default services

You can drill down further into each of these services. The api@internal service handles Traefik API requests (see Figure 2-13).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig13_HTML.jpg
Figure 2-13

Dashboard default service api@internal

The dashboard@internal service (see Figure 2-14) handles dashboard requests. Both services are implicitly registered by Traefik when the API and dashboard are enabled.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig14_HTML.jpg
Figure 2-14

Dashboard default service dashboard@internal

../images/497627_1_En_2_Chapter/497627_1_En_2_Fig15_HTML.jpg
Figure 2-15

Dashboard default service noop@internal

There is also a noop@internal (as seen in Figure 2-15) which is used in redirection.

Listing 2-14 defines a backend service in traefik-dynamic-conf.yml to fulfill the rule set up in the previous section to route traffic to the Go “Hello World” service. Please recall that the service runs on localhost port 9080.
# Dynamic configuration
http:
  routers:
    router0:
      entryPoints:
      - web
      service: hello-world
      rule: Path(`/hello-world`)
  services:
    hello-world:
      loadBalancer:
        servers:
        - url: http://localhost:9080/
Listing 2-14

Service configuration in dynamic configuration file

You now start up Traefik and try to access the Go service on the Traefik port 80 on the subpath ‘/hello-world’. When you use a curl, you see the output in Listing 2-15.
➜  traefik-config> curl localhost/hello-world
Hello, World
Listing 2-15

Access service endpoint on localhost with curl

You have now successfully exposed the backend service on port 80 in Traefik. Let’s look at what shows up in the Traefik dashboard. You see the HTTP routers, services, and middleware on the main dashboard page (see Figure 2-16).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig16_HTML.jpg
Figure 2-16

Router and service configured

You can drill down to the HTTP services page where you see a new entry for the hello-world service (see Figure 2-17).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig17_HTML.jpg
Figure 2-17

Drill down to configured HTTP services.

You can then drill down to the hello-world service to view its details (see Figure 2-18). This also shows the backend service URL in the Servers section.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig18_HTML.jpg
Figure 2-18

Drill down to configured Hello World file HTTP service

You then navigate back to the main Dashboard page (see Figure 2-19).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig19_HTML.jpg
Figure 2-19

Traefik dashboard before configuring middleware

From here, you can drill down to the HTTP routers (see Figure 2-20).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig20_HTML.jpg
Figure 2-20

Drill down to configured HTTP routers

You can then drill down to the HTTP router, which attaches the hello-world service to the web entrypoint (see Figure 2-21).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig21_HTML.jpg
Figure 2-21

HTTP router connected to hello-world service

Middleware

Now that you have successfully exposed the first service in Traefik, let’s circle back and add a middleware to the router to add extra API gateway capabilities.

Two HTTP middleware are defined by default. When you click ‘Explore ->’ in the Middlewares section, you see what’s shown in Figure 2-22.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig22_HTML.jpg
Figure 2-22

Default middleware

You can easily navigate down to view the details of the implicitly defined middleware. They are automatically enabled along with the dashboard and are useful for special handling of the URL pattern (see Figures 2-23 and 2-24). This way, even internal Traefik services follow the same configuration mechanism as user-defined services.
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig23_HTML.jpg
Figure 2-23

Default dashboard redirect middleware

../images/497627_1_En_2_Chapter/497627_1_En_2_Fig24_HTML.jpg
Figure 2-24

Default stripprefix middleware

For the use case, you define the built-in basic auth middleware to protect the Hello World API.

Let’s start by generating a username-password pair using the htpasswd command-line tool. This is the recommended method on the basic auth page in the Traefik documentation. If you do not have this tool on your system, you can use any other compliant password hashing utility. You use admin as username and admin@123 as the password. The username can be specified as plain-text, but the password must be supplied hashed in MD5, SH1, or BCrypt format (see Listing 2-16).
➜  traefik-config> htpasswd -nb admin admin@123
admin:$apr1$JsindKAS$zCWAvabJOgQvI.Dd3zjtE.
Listing 2-16

Generate username password pair for authentication

You copy this value to the Traefik dynamic configuration (see Listing 2-17).
# Dynamic configuration
http:
  routers:
    router0:
      entryPoints:
      - web
      middlewares:
      - basic-auth
      service: hello-world
      rule: Path(`/hello-world`)
  services:
    hello-world:
      loadBalancer:
        servers:
        - url: "http://localhost:9080/"
# Declaring the basic auth middleware with the user credentials
  middlewares:
    basic-auth:
      basicAuth:
        users:
          - "admin:$apr1$JsindKAS$zCWAvabJOgQvI.Dd3zjtE."
Listing 2-17

Basic auth middleware configuration in dynamic configuration file

Now let’s try the /hello-world endpoint in the browser. You get a basic auth prompt in the browser where you are asked to enter the username and password (see Figure 2-25). After entering these, you can see the response of the hello-world service (see Figure 2-26).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig25_HTML.jpg
Figure 2-25

Browser basic authentication

../images/497627_1_En_2_Chapter/497627_1_En_2_Fig26_HTML.jpg
Figure 2-26

Final authenticated Hello World

Let’s try the same with curl on the command line (see Listing 2-18).
➜  traefik-config> curl localhost/hello-world
401 Unauthorized
➜  traefik-config> curl -u admin localhost/hello-world
Enter host password for user 'admin':
Hello, World
Listing 2-18

Testing basic auth middleware applied on localhost endpoint

Now that this is working, let’s take one final look at the configuration in the Traefik dashboard. You see that the HTTP Middlewares tile on the main page now shows another middleware in the count (see Figure 2-27).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig27_HTML.jpg
Figure 2-27

Final configuration

You drill down to the Middlewares page where you can view the defined basic-auth@file middleware . Traefik automatically assigns the name. You also see other implicit middleware (see Figure 2-28).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig28_HTML.jpg
Figure 2-28

Drill down to configured HTTP middleware

You then drill down further and view the configuration for the middleware. You can also see the user you defined for authentication (see Figure 2-29).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig29_HTML.jpg
Figure 2-29

Configured basic auth middleware

From this page, you can directly navigate to the associated router for this middleware and view its details (see Figure 2-30).
../images/497627_1_En_2_Chapter/497627_1_En_2_Fig30_HTML.jpg
Figure 2-30

Routers, services, and middleware connected

Summary

In this chapter, you looked at basic configuration pieces of Traefik and how to manually configure Traefik to expose an API on a particular port and route traffic to the corresponding backend service. You looked at various ways to configure Traefik and passed configuration from a file, CLI parameters, and environment variables. You also did a deep dive into the Traefik dashboard to understand how to work with it to understand the configuration.

Until now, you have simply been routing traffic to one instance of a backing service. In the next chapter you deep dive into the load balancer capabilities of Traefik, for HTTP as well as TCP traffic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.150.231