Managing Plugin Bindings by CRD
In this guide you’ll learn how to use the KongPluginBinding
to bind plugins to Konnect entities
from within your Kubernetes cluster.
Prerequisites: Install Kong Gateway Operator and create a valid KonnectAPIAuthConfiguration and KonnectGatewayControlPlane in your cluster.
Prerequisites
Install Kong Gateway Operator
Update the Helm repository:
helm repo add kong https://charts.konghq.com
helm repo update kong
Install Kong Gateway Operator with Helm:
helm upgrade --install kgo kong/gateway-operator -n kong-system --create-namespace --set image.tag=1.4 \
--set kubernetes-configuration-crds.enabled=true \
--set env.ENABLE_CONTROLLER_KONNECT=true
You can wait for the operator to be ready using kubectl wait
:
kubectl -n kong-system wait --for=condition=Available=true --timeout=120s deployment/kgo-gateway-operator-controller-manager
Create an access token in Konnect
You may create either a Personal Access Token (PAT) or a Service Account Token (SAT) in Konnect. Please refer to the
Konnect authentication documentation for more information. You will need this token
to create a KonnectAPIAuthConfiguration
object that will be used by the Kong Gateway Operator to authenticate
with Konnect APIs.
Create a Kong Konnect API auth configuration
Depending on your preferences, you can create a KonnectAPIAuthConfiguration
object with the token specified
directly in its spec or as a reference to a Kubernetes Secret. The serverURL
field should be set to the Konnect API
URL in a region where your Kong Konnect account is located. Please refer to the list of available API URLs
for more information.
You can verify the KonnectAPIAuthConfiguration
object was reconciled successfully by checking its status.
kubectl get konnectapiauthconfiguration konnect-api-auth
The output should look like this:
NAME VALID ORGID SERVERURL
konnect-api-auth True <your-konnect-org-id> https://us.api.konghq.tech
Create a Kong Gateway control plane
Creating the KonnectGatewayControlPlane
object in your Kubernetes cluster will provision a Kong Konnect Gateway
control plane in your Gateway Manager. The KonnectGatewayControlPlane
CR
API allows you to
explicitly set a type of the Kong Gateway control plane, but if you don’t specify it, the default type is
a Self-Managed Hybrid
gateway control plane.
You can create one by applying the following YAML manifest:
echo '
kind: KonnectGatewayControlPlane
apiVersion: konnect.konghq.com/v1alpha1
metadata:
name: gateway-control-plane
namespace: default
spec:
name: gateway-control-plane # Name used to identify the Gateway Control Plane in Konnect
konnect:
authRef:
name: konnect-api-auth # Reference to the KonnectAPIAuthConfiguration object
' | kubectl apply -f -
You can see the status of the Gateway Control Plane by running:
kubectl get konnectgatewaycontrolplanes.konnect.konghq.com gateway-control-plane
If the Gateway Control Plane is successfully created, you should see the following output:
NAME PROGRAMMED ID ORGID
gateway-control-plane True <konnect-control-plane-id> <your-konnect-ord-id>
Having that in place, you will be able to reference the gateway-control-plane
in your Kong Konnect entities as their parent.
Introduction of KongPluginBinding
CRD
The KongPluginBinding
is the CRD used to manage the binding relationship between plugins and attached Konnect entities, including services, routes, consumers, and consumer groups, or a supported combination of these entities.
This CRD has two parts for the binding description in its specification:
-
spec.pluginRef
: Refers to aKongPlugin
resource which contains the plugin name and configuration of the plugin. -
spec.targets
: Refers to the entity or combination of entities that the plugin is attached to. Thespec.controlPlaneRef
refers to the Kong Konnect control plane thisKongPluginBinding
is associated with.
Each KongPluginBinding
represents a plugin on Konnect.
Using an unmanaged KongPluginBinding
You can directly create a KongPluginBinding
to bind your plugin to a Konnect entity. Assume that you have an existing and programmed KonnectGatewayControlPlane
with the name cp
in the default
namespace.
First, create a service and a plugin by KongService
and KongPlugin
CRD:
echo '
kind: KongService
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: service-example
spec:
host: example.com
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
Then, create a KongPlugin
:
echo '
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: rate-limiting-minute-10
plugin: rate-limiting
config:
policy: local
minute: 10
' | kubectl apply -f -
And you can create a KongPluginBinding
to bind them together.
echo '
kind: KongPluginBinding
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: binding-service-example-rate-limiting
spec:
pluginRef:
kind: KongPlugin
name: rate-limiting-minute-10
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: service-example
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
Then the plugin will be successfully attached to the service in Konnect.
Attaching plugins to multiple entities
Kong Gateway Operator also supports attaching plugins to a combination of entities by KongPluginBinding
.
Supported combinations include:
-
Service
andRoute
-
Service
andConsumer
-
Service
andConsumerGroup
-
Service
,Route
, andConsumer
-
Service
,Route
, andConsumerGroup
-
Consumer
andConsumerGroup
For example, we can configure a rate-limiting
plugin to a service and a consumer like this:
Create a service:
echo '
kind: KongService
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: service-plugin-binding-combination
spec:
host: example.com
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
Create a consumer:
echo '
kind: KongConsumer
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: consumer-plugin-binding-combination
username: consumer-test
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
Create a plugin:
echo '
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: rate-limiting-minute-10
plugin: rate-limiting
config:
policy: local
minute: 10
' | kubectl apply -f -
Then, you can create a KongPluginBinding
including both references to the KongService
and the KongCosumer
to attach the plugin to the service and the consumer:
echo '
kind: KongPluginBinding
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: binding-combination-service-consumer
spec:
pluginRef:
kind: KongPlugin
name: rate-limiting-minute-10
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: service-plugin-binding-combination
consumerRef:
name: consumer-plugin-binding-combination
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
Using annotations to bind plugins to other entities
NOTE: This approach is considered legacy and using
KongPluginBinding
CRD is recommended instead. Users can expect thatkonghq.com/plugins
annotation support will be removed at some point in the future.
You can also use the konghq.com/plugins
annotation to attach plugins to other entities like it’s done in Kong Ingress Controller.
The Kong Gateway Operator will create KongPluginBinding
resources for the annotations and configure them in Konnect.
In the example above, you can create a KongPlugin
and a KongService
like this:
echo '
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: rate-limiting-minute-10
plugin: rate-limiting
config:
policy: local
minute: 10
' | kubectl apply -f -
echo '
kind: KongService
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: service-example
annotations:
konghq.com/plugins: rate-limiting-minute-10
spec:
host: example.com
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
At this point you can see the plugin is attached to the service in Konnect.
You can also check the KongPluginBinding
resource by running.
kubectl get kongpluginbinding
You can see the created KongPluginBinding
like this:
NAME PLUGIN-KIND PLUGIN-NAME PROGRAMMED
rate-limiting-minute-10-a0z1x KongPlugin rate-limiting-minute-10 True
Attaching plugins to multiple entities
NOTE: Binding plugins with this approach has limited observability and can yield unexpected results when multiple different resources are attached to the same plugin (e.g. a service already has a plugin attached to it and we’re annotating consumer with the same plugin). Users are advised to use
KongPluginBinding
CRD instead for better control and auditability.
Similar to those introduced above, you can also attach a plugin to multiple entities by configuring annotations of attached entities.
If a plugin appears in the konghq.com/plugins
annotation of multiple entities, a KongPluginBinding
will be created for the binding relationship between the plugin and the combination of these entities.
Taking the example above where a plugin is attached to a service and a consumer:
echo '
kind: KongPlugin
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: rate-limiting-minute-10
plugin: rate-limiting
config:
policy: local
minute: 10
' | kubectl apply -f -
echo '
kind: KongService
apiVersion: configuration.konghq.com/v1alpha1
metadata:
namespace: default
name: service-plugin-binding-combination
annotations:
konghq.com/plugins: rate-limiting-minute-10
spec:
host: example.com
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
echo '
kind: KongConsumer
apiVersion: configuration.konghq.com/v1
metadata:
namespace: default
name: consumer-plugin-binding-combination
annotations:
konghq.com/plugins: rate-limiting-minute-10
username: consumer-test
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: cp
' | kubectl apply -f -
A KongPluginBinding
with both serviceRef
and consumerRef
in its spec.targets
will be created like:
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
creationTimestamp: "2024-10-14T07:14:05Z"
generateName: rate-limiting-minute-10-
name: rate-limiting-minute-10-xyz98
namespace: default
ownerReferences:
- apiVersion: configuration.konghq.com/v1
blockOwnerDeletion: true
kind: KongPlugin
name: rate-limiting-minute-10
uid: 01234567-89ab-cdef-fdec-ba9876543210
spec:
controlPlaneRef:
konnectNamespacedRef:
name: test1
namespace: default
type: konnectNamespacedRef
pluginRef:
kind: KongPlugin
name: rate-limiting-minute-10
targets:
consumerRef:
name: consumer-plugin-binding-combination
serviceRef:
group: configuration.konghq.com
kind: KongService
name: service-plugin-binding-combination