How to Install Kong Custom Go Plugin

In the previous post we talked about how to use custom Lua lua plugin with Kong. In today’s post, I want to talk about custom Go Plugin.

Go plugin runs on a process that is separated from Kong gateway itself. Therefore we need a plugin server to run go plugins. There are two method of using plugin server. The first method is to compile a standalone plugin-server. The other method is to embedded plugin server to plugin itself, please check official doc for more information.

You may be able to build plugin server executables yourself and mount it to docker container but I could not get this to work. I have to build custom image if I want to use go plugins.

I will be using Kong’s go plugin repo to show you how to build your image and use the plugin.

Below is the command I will be using . You need to substitute <ENV_VARIABLES> with the environment variables in below examples.

1
2
3
4
5
6
7
8
docker run --rm -d --name kong-demo \
-p "8000-8001:8000-8001" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-e "KONG_DATABASE=off" \
-e "KONG_PLUGINS=bundled,go-hello" \
<ENV_VARIABLES>
kong-demo

Standalone plugin server

This method had been deprecated and previous method failed to run. Please use embedded plugin server instead.

Embedded plugin server

Build image

We will use below Dockerfile to build our image. As you can see from this code, we did not build plugin server because go-hello.go has it embededded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM golang:alpine as builder

RUN apk add --no-cache git gcc libc-dev curl
RUN mkdir /go-plugins
RUN curl https://raw.githubusercontent.com/Kong/go-plugins/master/go-hello.go -o /go-plugins/go-hello.go

RUN cd /go-plugins && \
go mod init kong-go-plugin && \
go get github.com/Kong/go-pdk && \
go mod tidy && \
go build go-hello.go

FROM kong:2.4-alpine
COPY --from=builder /go-plugins/go-hello /usr/local/bin/

Let’s run docker build --no-cache -t kong-demo . to build our image.

Start Kong

We just need to use below environment variables to substitute <ENV_VARIABLES> above to start Kong.

1
2
-e "KONG_PLUGINSERVER_NAMES=go-hello" \
-e "KONG_PLUGINSERVER_GO_HELLO_QUERY_CMD=go-hello -dump" \

Check plugin

1
curl http://localhost:8001 -s | jq .plugins | grep go-hello

We should see "go-hello": true in the result.

Use custom plugin

Same as above Lua plugin example, we need to pass our declarative config to Kong.

go-hello plugin will add a x-hello-from-go header in response as x-hello-from-go: Go says <config.message> to ${host}.

Create Config file

I only need 1 route for this demo and I enabled go-hello plugin globally with a hello from go plugin as my config.message.

I am expecting to see x-hello-from-go: Go says hello from go plugin to localhost:8000 in the response.

Let’s save this file as test.yaml in our folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_format_version: "2.1"
_transform: true

services:
- name: first-demo
url: https://httpbin.org/anything
routes:
- name: first-demo-route
paths:
- /demo

plugins:
- config:
message: hello from go plugin
enabled: true
name: go-hello

Test Plugin

  1. First we apply config to Kong.

    1
    curl -X POST http://localhost:8001/config -F [email protected]
  2. Test first-demo-route
    We should reach httpbin with below request.

    1
    curl http://localhost:8000/demo -i

We can see we get the expected header in the response which means the plugin is working.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl http://localhost:8000/demo -I

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 464
Connection: keep-alive
x-hello-from-go: Go says hello from go plugin to localhost:8000
Date: Mon, 21 Jun 2021 04:21:49 GMT
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 1013
X-Kong-Proxy-Latency: 2
Via: kong/2.4.1

That’s all I want to share with you today.

Thanks for reading.