Skip to content

Commit f5619de

Browse files
committed
docs: add guide on using KongClusterPlugin
1 parent 7deb650 commit f5619de

File tree

2 files changed

+250
-0
lines changed

2 files changed

+250
-0
lines changed

docs/guides/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ Kong Ingress controller:
5252
- [Preserveing Client IP address](preserve-client-ip.md)
5353
This guide gives an overview of different methods to preserve the Client
5454
IP address.
55+
- [Using KongClusterPlugin resource](using-kongclusterplugin-resource.md)
56+
This guide walks through setting up plugins that can be shared across
57+
Kubernetes namespaces.
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# Using KongPlugin resource
2+
3+
In this guide, we will learn how to use KongClusterPlugin resource to configure
4+
plugins in Kong.
5+
The guide will cover configuring a plugin for services across different
6+
namespaces.
7+
8+
## Installation
9+
10+
Please follow the [deployment](../deployment) documentation to install
11+
Kong Ingress Controller onto your Kubernetes cluster.
12+
13+
## Testing connectivity to Kong
14+
15+
This guide assumes that `PROXY_IP` environment variable is
16+
set to contain the IP address or URL pointing to Kong.
17+
If you've not done so, please follow one of the
18+
[deployment guides](../deployment) to configure this environment variable.
19+
20+
If everything is setup correctly, making a request to Kong should return
21+
HTTP 404 Not Found.
22+
23+
```bash
24+
$ curl -i $PROXY_IP
25+
HTTP/1.1 404 Not Found
26+
Date: Fri, 21 Jun 2019 17:01:07 GMT
27+
Content-Type: application/json; charset=utf-8
28+
Connection: keep-alive
29+
Content-Length: 48
30+
Server: kong/1.2.1
31+
32+
{"message":"no Route matched with those values"}
33+
```
34+
35+
This is expected as Kong does not yet know how to proxy the request.
36+
37+
## Installing sample services
38+
39+
We will start by installing two services,
40+
an echo service and an httpbin service in their corresponding namespaces.
41+
42+
```bash
43+
$ kubectl create namespace httpbin
44+
namespace/httpbin created
45+
$ kubectl apply -n httpbin -f https://bit.ly/k8s-httpbin
46+
service/httpbin created
47+
deployment.apps/httpbin created
48+
```
49+
50+
```bash
51+
$ kubectl create namespace echo
52+
namespace/echo created
53+
$ kubectl apply -n echo -f https://bit.ly/echo-service
54+
service/echo created
55+
deployment.apps/echo created
56+
```
57+
58+
## Setup Ingress rules
59+
60+
Let's expose these services outside the Kubernetes cluster
61+
by defining Ingress rules.
62+
63+
```bash
64+
$ echo "
65+
apiVersion: extensions/v1beta1
66+
kind: Ingress
67+
metadata:
68+
name: httpbin-app
69+
namespace: httpbin
70+
annotations:
71+
konghq.com/strip-path: "true"
72+
spec:
73+
rules:
74+
- http:
75+
paths:
76+
- path: /foo
77+
backend:
78+
serviceName: httpbin
79+
servicePort: 80
80+
" | kubectl apply -f -
81+
ingress.extensions/demo created
82+
83+
$ echo "
84+
apiVersion: extensions/v1beta1
85+
kind: Ingress
86+
metadata:
87+
name: echo-app
88+
namespace: echo
89+
spec:
90+
rules:
91+
- http:
92+
paths:
93+
- path: /bar
94+
backend:
95+
serviceName: echo
96+
servicePort: 80
97+
" | kubectl apply -f -
98+
ingress.extensions/demo created
99+
```
100+
101+
Let's test these endpoints:
102+
103+
```bash
104+
# access httpbin service
105+
$ curl -i $PROXY_IP/foo/status/200
106+
HTTP/1.1 200 OK
107+
Content-Type: text/html; charset=utf-8
108+
Content-Length: 0
109+
Connection: keep-alive
110+
Server: gunicorn/19.9.0
111+
Date: Wed, 17 Jul 2019 21:38:00 GMT
112+
Access-Control-Allow-Origin: *
113+
Access-Control-Allow-Credentials: true
114+
X-Kong-Upstream-Latency: 2
115+
X-Kong-Proxy-Latency: 1
116+
Via: kong/1.2.1
117+
118+
# access echo service
119+
$ curl -i $PROXY_IP/bar
120+
HTTP/1.1 200 OK
121+
Content-Type: text/plain; charset=UTF-8
122+
Transfer-Encoding: chunked
123+
Connection: keep-alive
124+
Date: Wed, 17 Jul 2019 21:38:17 GMT
125+
Server: echoserver
126+
X-Kong-Upstream-Latency: 2
127+
X-Kong-Proxy-Latency: 1
128+
Via: kong/1.2.1
129+
130+
Hostname: echo-d778ffcd8-n9bss
131+
132+
Pod Information:
133+
node name: gke-harry-k8s-dev-default-pool-bb23a167-8pgh
134+
pod name: echo-d778ffcd8-n9bss
135+
pod namespace: default
136+
pod IP: 10.60.0.4
137+
<-- clipped -- >
138+
```
139+
140+
## Create KongClusterPlugin resource
141+
142+
```bash
143+
$ echo '
144+
apiVersion: configuration.konghq.com/v1
145+
kind: KongClusterPlugin
146+
metadata:
147+
name: add-response-header
148+
config:
149+
add:
150+
headers:
151+
- "demo: injected-by-kong"
152+
plugin: response-transformer
153+
' | kubectl apply -f -
154+
kongclusterplugin.configuration.konghq.com/add-response-header created
155+
```
156+
157+
Note how the resource is created at cluster-level and not in any specific
158+
namespace:
159+
160+
```bash
161+
$ kubectl get kongclusterplugins
162+
NAME PLUGIN-TYPE AGE
163+
add-response-header response-transformer 4s
164+
```
165+
166+
If you send requests to `PROXY_IP` now, you will see that the header is not
167+
injected in the responses. The reason being that we have created a
168+
resource but we have not told Kong when to execute the plugin.
169+
170+
## Configuring plugins on Ingress resources
171+
172+
We will associate the `KongClusterPlugin` resource with the two Ingress resources
173+
that we previously created:
174+
175+
```bash
176+
$ kubectl patch ingress -n httpbin httpbin-app -p '{"metadata":{"annotations":{"plugins.konghq.com":"add-response-header"}}}'
177+
ingress.extensions/httpbin-app patched
178+
179+
$ kubectl patch ingress -n echo echo-app -p '{"metadata":{"annotations":{"plugins.konghq.com":"add-response-header"}}}'
180+
ingress.extensions/echo-app patched
181+
```
182+
183+
Here, we are asking Kong Ingress Controller to execute the response-transformer
184+
plugin whenever a request matching any of the above two Ingress rules is
185+
processed.
186+
187+
Let's test it out:
188+
189+
```bash
190+
curl -i $PROXY_IP/foo/status/200
191+
HTTP/1.1 200 OK
192+
Content-Type: text/html; charset=utf-8
193+
Content-Length: 9593
194+
Connection: keep-alive
195+
Server: gunicorn/19.9.0
196+
Date: Wed, 17 Jul 2019 21:54:31 GMT
197+
Access-Control-Allow-Origin: *
198+
Access-Control-Allow-Credentials: true
199+
demo: injected-by-kong
200+
X-Kong-Upstream-Latency: 2
201+
X-Kong-Proxy-Latency: 1
202+
Via: kong/1.2.1
203+
204+
$ curl -I $PROXY_IP/bar
205+
HTTP/1.1 200 OK
206+
Content-Type: text/plain; charset=UTF-8
207+
Connection: keep-alive
208+
Date: Wed, 17 Jul 2019 21:54:39 GMT
209+
Server: echoserver
210+
demo: injected-by-kong
211+
X-Kong-Upstream-Latency: 2
212+
X-Kong-Proxy-Latency: 1
213+
Via: kong/1.2.1
214+
```
215+
216+
As can be seen in the output, the `demo` header is injected by Kong when
217+
the request matches the Ingress rules defined in our two Ingress rules.
218+
219+
## Updating plugin configuration
220+
221+
Now, let's update the plugin configuration to change the header value from
222+
`injected-by-kong` to `injected-by-kong-for-kubernetes`:
223+
224+
```bash
225+
$ echo '
226+
apiVersion: configuration.konghq.com/v1
227+
kind: KongClusterPlugin
228+
metadata:
229+
name: add-response-header
230+
config:
231+
add:
232+
headers:
233+
- "demo: injected-by-kong-for-kubernetes"
234+
plugin: response-transformer
235+
' | kubectl apply -f -
236+
kongclusterplugin.configuration.konghq.com/add-response-header configured
237+
```
238+
239+
If you repeat the requests from the last step, you will see Kong
240+
now responds with updated header value.
241+
242+
This guides demonstrates how plugin configuration can be shared across
243+
services running in different namespaces.
244+
This can prove to be useful if the persona controlling the plugin
245+
configuration is different from service owners that are responsible for the
246+
Service and Ingress resources in Kubernetes.
247+

0 commit comments

Comments
 (0)