Deploy custom plugins with Kong Gateway Operator
Build and push a plugin as a container image, then use a KongPluginInstallation
to register it with the operator. Reference it in your GatewayConfiguration
to
make it available in Data Planes and configure its behavior using a KongPlugin
resource.
Prerequisites
Kong Konnect
If you don’t have a Konnect account, you can get started quickly with our onboarding wizard.
- The following Konnect items are required to complete this tutorial:
- Personal access token (PAT): Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
-
Set the personal access token as an environment variable:
export KONNECT_TOKEN='YOUR KONNECT TOKEN'
Enable the Gateway API
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml
-
Create a
Gateway
andGatewayClass
instance to use.
echo "
apiVersion: v1
kind: Namespace
metadata:
name: kong
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
annotations:
konghq.com/gatewayclass-unmanaged: 'true'
spec:
controllerName: konghq.com/gateway-operator
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
" | kubectl apply -n kong -f -
Kong Gateway Operator running
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo update
-
Create a
kong
namespace:kubectl create namespace kong --dry-run=client -o yaml | kubectl apply -f -
-
Install Kong Ingress Controller using Helm:
helm upgrade --install kgo kong/gateway-operator -n kong-system --create-namespace \ --set image.tag=1.5 \ --set kubernetes-configuration-crds.enabled=true \ --set env.ENABLE_CONTROLLER_KONNECT=true \ --set env.ENABLE_CONTROLLER_KONGPLUGININSTALLATION=true
Required Kubernetes resources
This how-to requires some Kubernetes services to be available in your cluster. These services will be used by the resources created in this how-to.
kubectl apply -f https://developer.konghq.com/manifests/kic/echo-service.yaml -n kong
This how-to also requires 1 pre-configured route:
Plugin distribution using an OCI registry
Kong Gateway Operator can install Kong custom plugins packaged as container images. This guide shows how to package, install, and use a custom plugin in Kong Gateway instances managed by the Kong Gateway Operator.
Create a custom plugin (Optional)
If you already have a real plugin, you can skip this step.
mkdir myheader
echo 'local MyHeader = {}
MyHeader.PRIORITY = 1000
MyHeader.VERSION = "1.0.0"
function MyHeader:header_filter(conf)
-- do custom logic here
kong.response.set_header("myheader", conf.header_value)
end
return MyHeader
' > myheader/handler.lua
echo 'return {
name = "myheader",
fields = {
{ config = {
type = "record",
fields = {
{ header_value = { type = "string", default = "roar", }, },
},
}, },
}
}
' > myheader/schema.lua
The directory should now look like this:
myheader
├── handler.lua
└── schema.lua
0 directories, 2 files
Build a container image (Optional)
This section is optional. The rest of this guide uses a pre-published image, and the following information is provided if you want to package your own custom plugin.
Plugin-related files should be at the root of the image, so the Dockerfile for the plugin would look like this:
echo 'FROM scratch
COPY myheader /
' > Dockerfile
In this example, myheader
is a directory that contains handler.lua
and schema.lua
.
Build the image:
docker build -t myheader:1.0.0 .
Next, push the image to a public or private registry available to the Kubernetes cluster where Kong Gateway Operator is running.
docker tag myheader:1.0.0 $YOUR_REGISTRY_ADDRESS/myheader:1.0.0
docker push $YOUR_REGISTRY_ADDRESS/myheader:1.0.0
In this example, the plugin is available in the public registry (Docker Hub) as kong/plugin-example:1.0.0
. The following steps use the same source.
Install the plugin
-
Install the plugin using the
KongPluginInstallation
resource. This resource makes the plugin available for instances of Kong Gateway resources:echo ' kind: KongPluginInstallation apiVersion: gateway-operator.konghq.com/v1alpha1 metadata: name: custom-plugin-myheader spec: image: kong/plugin-example:1.0.0 ' | kubectl apply -f -
Verify that the plugin is fetched and available by examining the status of the
KongPluginInstallation
resource:kubectl get kongplugininstallations.gateway-operator.konghq.com -o jsonpath-as-json='{.items[*].status}'
The output should look like this:
[ { "conditions": [ { "lastTransitionTime": "2024-10-09T19:39:39Z", "message": "plugin successfully saved in cluster as ConfigMap", "observedGeneration": 1, "reason": "Ready", "status": "True", "type": "Accepted" } ], "underlyingConfigMapName": "custom-plugin-myheader-hnzf9" } ]
In case of problems, the respective
conditions
or respective resources will provide more information.The
KongPluginInstallation
resource creates aConfigMap
with the plugin content. AdditionalConfigMap
s are created when a plugin is referenced by other resources. The operator automatically manages the lifecycle of all theseConfigMap
s. -
Make the plugin available in a
Gateway
resource by referencing it in thespec.dataPlaneOptions.spec.pluginsToInstall
field of theGatewayConfiguration
resource. Plugins can be referenced across namespaces without any additional configuration.echo ' kind: GatewayConfiguration apiVersion: gateway-operator.konghq.com/v1beta1 metadata: name: kong namespace: default spec: dataPlaneOptions: deployment: replicas: 2 podTemplateSpec: spec: containers: - name: proxy image: kong/kong-gateway:3.10 pluginsToInstall: - name: custom-plugin-myheader controlPlaneOptions: deployment: podTemplateSpec: spec: containers: - name: controller image: kong/kubernetes-ingress-controller:3.4 --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: kong spec: controllerName: konghq.com/gateway-operator parametersRef: group: gateway-operator.konghq.com kind: GatewayConfiguration name: kong namespace: default ' | kubectl apply -f -
-
Deploy an example service and expose it by configuring
HTTPRoute
with the custom plugin:kubectl apply -f https://developer.konghq.com/assets/kubernetes-ingress-controller/examples/echo-service.yaml
Next, add the
HTTPRoute
with the custom plugin. The configuration of the plugin is provided with theKongPlugin
CRD, where the fieldplugin
is set to the name of theKongPluginInstallation
resource.echo " apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: name: myheader namespace: kong annotations: kubernetes.io/ingress.class: kong plugin: custom-plugin-myeader config: header_value: my-first-plugin " | kubectl apply -f -
Next, apply the
KongPlugin
resource by annotating theservice
resource:kubectl annotate -n kong service echo konghq.com/plugins=myheader
Validate your configuration
Ensure that everything is up and running and make a request to the service.
curl "$PROXY_IP/echo"
You should see the following header:
myheader: my-first-plugin
curl "$PROXY_IP/echo"
You should see the following header:
myheader: my-first-plugin