Skip to content

Commit d2f9187

Browse files
authored
Add sample for custom routing with Kong Gateway (knative#4110)
* Add sample for custom routing with Kong Gateway * Remove frontmatter * Fix Markdown formatting
1 parent d45fdde commit d2f9187

File tree

8 files changed

+482
-0
lines changed

8 files changed

+482
-0
lines changed

config/nav.yml

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ nav:
173173
- Scala: serving/samples/hello-world/helloworld-scala/README.md
174174
- Shell: serving/samples/hello-world/helloworld-shell/README.md
175175
- Routing services - Go: serving/samples/knative-routing-go/README.md
176+
- Routing services with Kong - Go: serving/samples/kong-routing-go/README.md
176177
- multi-container samples: serving/samples/multi-container/README.md
177178
- RESTful service - Go: serving/samples/rest-api-go/README.md
178179
- Secrets - Go: serving/samples/secrets-go/README.md

docs/serving/samples/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Serving resources and how they can be applied across common use cases.
1414
| Github Webhook | A simple webhook handler that demonstrates interacting with Github. | [Go](gitwebhook-go/README.md) |
1515
| gRPC | A simple gRPC server. | [Go](grpc-ping-go/README.md) |
1616
| Knative Routing | An example of mapping multiple Knative services to different paths under a single domain name using the Istio VirtualService concept. | [Go](knative-routing-go/README.md) |
17+
| Kong Routing | An example of mapping multiple Knative services to different paths under a single domain name using the Kong API gateway. | [Go](kong-routing-go/README.md) |
1718
| Knative Secrets | A simple app that demonstrates how to use a Kubernetes secret as a Volume in Knative. | [Go](secrets-go/README.md) |
1819
| REST API | A simple Restful service that exposes an endpoint defined by an environment variable described in the Knative Configuration. | [Go](rest-api-go/README.md) |
1920
| Traffic Splitting | This samples builds off the [Creating a RESTful Service](rest-api-go) sample to illustrate applying a revision, then using that revision for manual traffic splitting. | [YAML](../../developer/serving/traffic-management.md) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2021 The Knative Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM golang AS builder
16+
17+
WORKDIR /go/src/github.com/knative/docs/
18+
ADD . /go/src/github.com/knative/docs/
19+
20+
RUN CGO_ENABLED=0 go build ./docs/serving/samples/kong-routing-go/
21+
22+
FROM gcr.io/distroless/base
23+
24+
EXPOSE 8080
25+
COPY --from=builder /go/src/github.com/knative/docs/kong-routing-go /sample
26+
27+
ENTRYPOINT ["/sample"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
# Routing across multiple Knative services with Kong
2+
3+
This example shows how to map multiple Knative services to different paths under
4+
a single domain name using [Kong Gateway](https://docs.konghq.com/gateway-oss/).
5+
Kong Gateway is a general-purpose reverse proxy and API gateway built on
6+
[Nginx](https://www.nginx.com/), therefore these directions can also be used to
7+
configure routing based on other request data such as headers, or even to map
8+
Knative and external resources under the same domain name.
9+
10+
In this sample, we set up two web services: _Search_ service and _Login_
11+
service, which simply read in an env variable `SERVICE_NAME` and print
12+
`"${SERVICE_NAME} is called"`. We'll then define routing rules via [Kong's
13+
Kubernetes Ingress
14+
Controller](https://docs.konghq.com/kubernetes-ingress-controller/) and [Kong's
15+
request transformer
16+
plugin](https://docs.konghq.com/hub/kong-inc/request-transformer/), so that
17+
`example.com/search` maps to the _Search_ service, and `example.com/login` maps
18+
to the _Login_ service.
19+
20+
## Prerequisites
21+
22+
1. A Kubernetes cluster with [Knative Serving](../../../install/) and
23+
[Kong](https://docs.konghq.com/kubernetes-ingress-controller/1.3.x/guides/using-kong-with-knative/)
24+
installed.
25+
1. Install
26+
[Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment).
27+
1. Acquire a domain name.
28+
- In this example, we use `example.com`. If you don't have a domain name,
29+
you can modify your hosts file (on macOS or Linux) to map `example.com` to
30+
your cluster's ingress IP.
31+
- If you have configured a custom domain for your Knative installation, we
32+
will refer to it as `<YOUR_DOMAIN_NAME>` in the rest of this document
33+
1. Check out the code:
34+
35+
```bash
36+
go get -d github.com/knative/docs/docs/serving/samples/kong-routing-go
37+
```
38+
39+
## Setup
40+
41+
To check the domain name, run the following command:
42+
43+
```bash
44+
kubectl get cm -n knative-serving config-domain -o yaml
45+
```
46+
47+
Then, check the value for `data`. The domain name should be in the format of
48+
`<YOUR_DOMAIN_NAME>: ""`, if it is available.
49+
50+
Build the application container and publish it to a container registry:
51+
52+
1. Move into the sample directory:
53+
54+
```bash
55+
cd $GOPATH/src/github.com/knative/docs
56+
```
57+
58+
1. Set your preferred container registry:
59+
60+
If you use Google Container Registry (GCR), you will need to enable the [GCR
61+
API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com)
62+
in your GCP project.
63+
64+
```bash
65+
export REPO="gcr.io/<YOUR_PROJECT_ID>"
66+
```
67+
68+
If you use Docker Hub as your Docker image registry, replace `<username>`
69+
with your Docker Hub username and run the following command:
70+
71+
```bash
72+
export REPO="docker.io/<username>"
73+
```
74+
75+
1. Use Docker to build your application container:
76+
77+
```bash
78+
docker build \
79+
--tag "${REPO}/kong-routing-go" \
80+
--file=docs/serving/samples/kong-routing-go/Dockerfile .
81+
```
82+
83+
1. Push your container to a container registry:
84+
85+
```bash
86+
docker push "${REPO}/kong-routing-go"
87+
```
88+
89+
1. Replace the image reference path with our published image path in the
90+
configuration file `docs/serving/samples/kong-routing-go/sample.yaml` in one
91+
of the following ways:
92+
93+
- Manually replace `image:
94+
github.com/knative/docs/docs/serving/samples/kong-routing-go` with `image:
95+
${REPO}/kong-routing-go`. If you manually changed the `.yaml` file, you
96+
must replace `${REPO}` with the correct path on your local machine.
97+
- Run this command:
98+
```bash
99+
perl -pi -e "[email protected]/knative/docs/docs/serving/samples@${REPO}@g" docs/serving/samples/kong-routing-go/sample.yaml
100+
```
101+
102+
## Deploy the Service
103+
104+
Deploy the Knative Serving sample:
105+
106+
```bash
107+
kubectl apply -f docs/serving/samples/kong-routing-go/sample.yaml
108+
```
109+
110+
Inspect the deployed Knative services with:
111+
112+
```bash
113+
kubectl get ksvc
114+
```
115+
116+
You should see 2 Knative services: `search-service` and `login-service`.
117+
118+
## Exploring the Routes
119+
120+
Kong Gateway serves all incoming traffic to services managed by Knative. You can
121+
inspect the corresponding Kubernetes service for the gateway:
122+
123+
```bash
124+
INGRESSGATEWAY=kong-proxy
125+
126+
kubectl get svc $INGRESSGATEWAY -n kong --output yaml
127+
```
128+
129+
### Access the Services
130+
131+
1. Find the gateway IP and export it as an environment variable:
132+
133+
```bash
134+
export GATEWAY_IP=`kubectl get svc $INGRESSGATEWAY -n kong \
135+
--output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"`
136+
```
137+
138+
1. Find the _Search_ service URL:
139+
140+
```bash
141+
kubectl get route search-service --output=custom-columns=NAME:.metadata.name,URL:.status.url
142+
```
143+
144+
The output should looks like this:
145+
146+
```
147+
NAME URL
148+
search-service http://search-service.default.example.com
149+
```
150+
151+
1. Make a cURL request to the service:
152+
153+
```bash
154+
curl http://${GATEWAY_IP} --header "Host:search-service.default.example.com"
155+
```
156+
157+
The output should look like this:
158+
159+
```
160+
Search Service is called!
161+
```
162+
163+
1. Similarly, you can also directly access _Login_ service:
164+
165+
```bash
166+
curl http://${GATEWAY_IP} --header "Host:login-service.default.example.com"
167+
```
168+
169+
The output should look like this:
170+
171+
```
172+
Login Service is called!
173+
```
174+
175+
## Apply Custom Routing Rule
176+
177+
1. Apply the custom routing rules defined in the `routing.yaml` file:
178+
179+
```bash
180+
kubectl apply -f docs/serving/samples/kong-routing-go/routing.yaml
181+
```
182+
183+
If you have configured a custom domain name for your service, please replace
184+
all mentions of `example.com` in `routing.yaml` with `<YOUR_DOMAIN_NAME>`.
185+
186+
In addition, you need to verify how your domain template is defined. By
187+
default, we use the format of {% raw %}`{{.Name}}.{{.Namespace}}`{% endraw
188+
%}, like `search-service.default` and `login-service.default`. However, some
189+
Knative environments may use other formats like {% raw
190+
%}`{{.Name}}-{{.Namespace}}`{% endraw %}. You can find out the format by
191+
running the command:
192+
193+
```bash
194+
kubectl get cm config-network -n knative-serving -o yaml
195+
```
196+
197+
Then, look for the value for `domainTemplate`. If it is {% raw
198+
%}`{{.Name}}-{{.Namespace}}.{{.Domain}}`{% endraw %}, you need to change
199+
`search-service.default` into `search-service-default` and
200+
`login-service.default` into `login-service-default` as well in
201+
`routing.yaml`.
202+
203+
1. The `routing.yaml` file will create an ingress that forwards incoming
204+
requests at `example.com/search` to `search-service.default.example.com` by
205+
updating the "Host" header to `search-service.default.example.com` and
206+
stripping the request path. This modified request is then forwarded to the
207+
Knative ingress (Kong) and routed to the service as usual. Another ingress
208+
like this is also created for the _Login_ service.
209+
210+
```bash
211+
kubectl get ingress {search,login}-service-ingress -n kong --output yaml
212+
```
213+
214+
1. Send a request to the _Search_ service and the _Login_ service by using
215+
their corresponding URLs. You should get the same results as directly
216+
accessing these services.
217+
218+
- Send a request to the _Search_ service:
219+
```bash
220+
curl http://${GATEWAY_IP}/search --header "Host: example.com"
221+
```
222+
or
223+
```bash
224+
curl http://${GATEWAY_IP}/search --header "Host: <YOUR_DOMAIN_NAME>"
225+
```
226+
for the case using your own domain.
227+
228+
- Send a request to the _Login_ service:
229+
```bash
230+
curl http://${GATEWAY_IP}/login --header "Host: example.com"
231+
```
232+
or
233+
```bash
234+
curl http://${GATEWAY_IP}/login --header "Host: <YOUR_DOMAIN_NAME>"
235+
```
236+
for the case using your own domain.
237+
238+
## How It Works
239+
240+
When a request with host `example.com` or your own domain name reaches Kong
241+
Gateway, Kong will check if the URL path prefix is `/search` or `/login`. If the
242+
URL matches on of the two rules, then the "Host" header of the request will be
243+
rewritten into the host of the _Search_ service or _Login_ service,
244+
respectively, and the path will be stripped. The modified request will be
245+
forwarded to Kong again. Kong will check the "Host" header and forward the
246+
request to the _Search_ or _Login_ service according to the header value.
247+
248+
![Object model](images/kong-routing-sample-flow.png)
249+
250+
## Clean Up
251+
252+
To clean up the sample resources:
253+
254+
```bash
255+
kubectl delete --filename docs/serving/samples/kong-routing-go/sample.yaml
256+
kubectl delete --filename docs/serving/samples/kong-routing-go/routing.yaml
257+
```
Loading

0 commit comments

Comments
 (0)