Custom Traefik (local) plugin

Traefik has implemented a lot of middleware by default, which can meet most of our daily needs, but in actual work, users still have custom middleware needs. To solve this problem, the official launch of a Traefik Pilot[1]

Traefik Pilot

Traefik Pilot is a SaaS platform that links with Traefik to expand its functions. It provides many functions, through a global control panel and Dashboard to enhance the observation and control of Traefik:

  • Indicators of network activity of Traefik agents and agent groups

  • Service health issues and security breach alerts

  • Plug-ins to extend Traefik's functionality

    Before Traefik can use the functions of Traefik Pilot, they must be connected first. We only need to make a few changes to the static configuration of Traefik.
     

    The Traefik proxy must be able to access the Internet to connect to Traefik Pilot. The connection is established on port 443 via HTTPS.

    First we need to create an account on the Traefik Pilot homepage (https://pilot.traefik.io/), register a new instance of Traefik and start using Traefik Pilot. After logging in, you can create a new instance by selecting Register New Traefik Instance.
     

    In addition, when our Traefik is not connected to Traefik Pilot, a bell icon will appear in Traefik Web UI, we can choose Connect with Traefik Pilot to navigate to Traefik Pilot UI for operation.
        

    After logging in, Traefik Pilot will generate a token for a new instance. We need to add this Token to the Traefik static configuration.
     

    Enable the configuration of Pilot in the Traefik installation configuration file:

    1. # Activate Pilot integration 
    2. pilot: 
    3.   enabled: true 
    4.   token: "e079ea6e-536a-48c6-b3e3-f7cfaf94f477" 

      After the update is complete, we can see Traefik Pilot UI related information in Traefik's Web UI.
        

     
      Next, we can select the plug-in we want to use on the plug-in page of Traefik Pilot. For example, we use the Demo Plugin[2] plug-in here.
     

    Click the Install Plugin button in the upper right corner to install the plug-in and a dialog box will pop up to remind us how to install it.
     

    First, we need to register the current Traefik to Traefik Pilot (completed), then we need to add this plugin to Traefik in a static configuration, and then add plugin startup parameters:

    1. # Activate Pilot integration 
    2. pilot: 
    3.   enabled: true 
    4.   token: "e079ea6e-536a-48c6-b3e3-f7cfaf94f477" 
    5.  
    6. additionalArguments: 
    7. #Add support for demo plugin 
    8. - --experimental.plugins.plugindemo.modulename=github.com/traefik/plugindemo 
    9. - --experimental.plugins.plugindemo.version=v0.2.1 
    10. # Other configuration

      After the update is complete, create a Middleware object as shown below:

      1. ➜ cat <<EOF | kubectl apply -f - 
      2. apiVersion: traefik.containo.us/v1alpha1 
      3. kind: Middleware 
      4. metadata: 
      5.   name: myplugin 
      6. spec: 
      7.   plugin: 
      8.     plugindemo:  # Plug-in name
      9.       Headers: 
      10.         X-Demo: test 
      11.         Foo: bar 
      12. EOF 

     Then add it to the IngressRoute object of the whoami application above:

    1. apiVersion: traefik.containo.us/v1alpha1 
    2. kind: IngressRoute 
    3. metadata: 
    4.   name: ingressroute-demo 
    5.   namespace: default 
    6. spec: 
    7.   entryPoints: 
    8.   - web 
    9.   routes: 
    10.   - match: Host(`who.qikqiak.com`) && PathPrefix(`/notls`) 
    11.     kind: Rule 
    12.     services: 
    13.     - name: whoami  # K8s Service 
    14.       port: 80 
    15.     middlewares: 
    16.     - name: myplugin  # Use the newly created middleware above

      After the update is complete, when we visit http://who.qikqiak.com/notls, we can see that the two headers defined in the above plugins have been added.
       

      Of course, in addition to using the plug-ins provided by the developers on Traefik Pilot, we can also develop our own plug-ins according to our own needs. You can refer to the plug-in development document [3].

      Local private plugin 

      Above we introduced that you can use Traefik Pilot to use plugins, but this is a SaaS service platform, which is not very suitable for most enterprise scenarios. We need to load plugins in the local environment in more scenarios. To solve this problem, in Traefik After the v2.5 version, a new method of loading plugins directly from the local storage directory is provided. There is no need to enable Traefik Pilot. You only need to put the plugin source code into a new directory named /plugins-local, which is relative to the current work. Directory to create this directory. For example, if we directly use the traefik docker image, the entry point is the root directory/. Traefik itself will build your plug-in, so all we have to do is write the source code and put it in In the correct directory, let Traefik load it

      It should be noted that the plug-in is only loaded once every time it is started, so if we want to reload your plug-in source code, we need to restart Traefik.

      Below we use a simple custom plug-in example to illustrate how to use private plug-ins. First, we define a Dockerfile file named Dockerfile.demo, first clone the plug-in source code from the git repository, and then use traefik:v2.5 as the base image to copy the plug-in source code to the /plugins-local directory, as shown below:

      1. FROM alpine:3 
      2. ARG PLUGIN_MODULE=github.com/traefik/plugindemo 
      3. ARG PLUGIN_GIT_REPO=https://github.com/traefik/plugindemo.git 
      4. ARG PLUGIN_GIT_BRANCH=master 
      5. RUN apk add --update git && \ 
      6.     git clone ${PLUGIN_GIT_REPO} /plugins-local/src/${PLUGIN_MODULE} \ 
      7.       --depth 1 --single-branch --branch ${PLUGIN_GIT_BRANCH} 
      8.  
      9. FROM traefik:v2.5 
      10. COPY --from=0 /plugins-local /plugins-local 

        The demo plug-in we use here is the same plug-in demonstrated in Pilot above, and we can customize the request header information through this plug-in.

        Then under the Dockerfile.demo directory, build the image:

        1. image: 
        2.   name: cnych/traefik-private-demo-plugin 
        3.   tag: 2.5.4 
        4.  
        5. # Other omissions
        6.  
        7. #No need to open pilot
        8. pilot: 
        9.   enabled: false 
        10.  
        11. additionalArguments: 
        12. # Add local support for demo plugin

        13. - --experimental.localPlugins.plugindemo.moduleName=github.com/traefik/plugindemo 
        14. # Other omitted

          Note that we used --experimental.localPlugins when adding Traefik's startup parameters above. After the update is complete, you can use our private plug-in to create a Middleware object:

          1. ➜ cat <<EOF | kubectl apply -f - 
          2. apiVersion: traefik.containo.us/v1alpha1 
          3. kind: Middleware 
          4. metadata: 
          5.   name: my-private-plugin 
          6. spec: 
          7.   plugin: 
          8.     plugindemo:  #Plug-in name
          9.       Headers: 
          10.         X-Demo: private-demo 
          11.         Foo: bar 
          12. EOF 

     Then add it to the IngressRoute object of the whoami application above:

    1. apiVersion: traefik.containo.us/v1alpha1 
    2. kind: IngressRoute 
    3. metadata: 
    4.   name: ingressroute-demo 
    5.   namespace: default 
    6. spec: 
    7.   entryPoints: 
    8.   - web 
    9.   routes: 
    10.   - match: Host(`who.qikqiak.com`) && PathPrefix(`/notls`) 
    11.     kind: Rule 
    12.     services: 
    13.     - name: whoami  # K8s Service 
    14.       port: 80 
    15.     middlewares: 
    16.     - name: my-private-plugin  # Use the newly created middleware above

      After updating the above resource object, we can visit http://who.qikqiak.com/notls and we can see that two new headers defined in the above plug-ins have been added, which proves that our private plug-in configuration is successful:
       

      With the support of local private plug-ins, Traefik really started to take off, right?

      Reference 

      [1]Traefik Pilot: https://pilot.traefik.io/

      [2]Demo Plugin: https://github.com/traefik/plugindemo

      [3]Plugin dev doc: https://doc.traefik.io/traefik-pilot/plugins/plugin-dev/