Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routes entity page, router expressions, proxying #168

Merged
merged 38 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2d0e1ab
Start revising routes entity page
cloudjumpercat Dec 10, 2024
2804553
Continue revising routes entity, start drafting the rewrite URLs how to
cloudjumpercat Dec 10, 2024
9a845e9
Fix vale spelling error
cloudjumpercat Dec 11, 2024
117daae
Capitalize entities
cloudjumpercat Dec 11, 2024
c3c8da6
Revise how to after testing
cloudjumpercat Dec 11, 2024
ccbd48e
Plan out routing section for matching and priority section split
cloudjumpercat Dec 11, 2024
e9b3935
Apply suggestions from code review
cloudjumpercat Dec 12, 2024
5a74da6
Edit routes, upstream, add proxy page, update source file with doc links
cloudjumpercat Dec 12, 2024
2bd7119
Merge branch 'main' into routes-entity
cloudjumpercat Dec 13, 2024
89adbb6
Fix broken breadcrumb link
cloudjumpercat Dec 13, 2024
45b8d04
Revise a whole bunch of pages
cloudjumpercat Dec 13, 2024
5cf9492
Revise proxy reference and routing
cloudjumpercat Dec 16, 2024
6c175ce
Start adding the needed expressions router pages
cloudjumpercat Dec 16, 2024
3aefeb7
Add drafts of all expressions docs
cloudjumpercat Dec 17, 2024
3336680
Finish expressions router concept page
cloudjumpercat Dec 18, 2024
1f69366
Remove expressions router how to and move enabling info to other pages
cloudjumpercat Dec 18, 2024
7165bbc
Apply suggestions from code review
cloudjumpercat Dec 18, 2024
81e2355
Apply Angel's remaining feedback to the rewrite urls how to
cloudjumpercat Dec 18, 2024
34e2faa
Apply suggestions from code review
cloudjumpercat Dec 18, 2024
586509d
Apply Lena's feedback to Upstream entity page
cloudjumpercat Dec 18, 2024
e819205
Revise Routes entity based on feedback
cloudjumpercat Dec 18, 2024
1a1733d
Revise proxy reference
cloudjumpercat Dec 19, 2024
990afc6
Minor link fixes, make vale happy again
cloudjumpercat Dec 19, 2024
fc92c6f
Fix broken links
cloudjumpercat Dec 19, 2024
c5eb4b1
Remove upstream and target entity pages since they are now handled in…
cloudjumpercat Dec 19, 2024
318b8d6
Convert expressions router image to mermaid
cloudjumpercat Dec 19, 2024
4300032
Merge branch 'main' into routes-entity
cloudjumpercat Dec 19, 2024
1def049
Apply remaining feedback
cloudjumpercat Dec 19, 2024
5d27dfe
Add proxying ref placeholder page with todo
cloudjumpercat Jan 6, 2025
6adb293
Merge branch 'main' into routes-entity
lena-larionova Jan 8, 2025
3d090cf
Apply suggestions from code review
cloudjumpercat Jan 10, 2025
847bb93
Apply remaining feedback
cloudjumpercat Jan 10, 2025
5f9074c
Merge branch 'main' into routes-entity
cloudjumpercat Jan 10, 2025
e0b7bc2
Apply new feature table formatting
cloudjumpercat Jan 10, 2025
d03b20d
Fix feature table formatting
cloudjumpercat Jan 10, 2025
e6e72cf
Apply suggestions from code review
lena-larionova Jan 10, 2025
446ab46
fix centering issue in feature tables
lena-larionova Jan 10, 2025
d9cc8f6
fix faqs key
lena-larionova Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 232 additions & 28 deletions app/_gateway_entities/route.md

Large diffs are not rendered by default.

51 changes: 47 additions & 4 deletions app/_gateway_entities/target.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ tools:
- deck
- terraform

description: A target identifies a specific instance of an upstream service.
description: A target is an IP address/hostname with a port that identifies an instance of a backend service.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

related_resources:
- text: Upstreams entity
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
url: /gateway/entities/upstream/
- text: Routing in {{site.base_gateway}}
url: /gateway/routing/
- text: Proxying with {{site.base_gateway}}
url: /gateway/traffic-control/proxy/

schema:
api: gateway/admin-ee
Expand All @@ -21,12 +29,47 @@ schema:

## What is a target?
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

{{page.description}}
{{page.description}} Each [Upstream](/gateway/entities/upstream/) can have many Targets. Targets are used by Upstreams for [load balancing]<!--TODO link concept-->. For example, if you have an `example_upstream` upstream, you can point it to two different Targets: `httpbin.konghq.com` and `httpbun.com`. This is so that if one of the servers (like `httpbin.konghq.com`) is unavailable, it automatically detects the problem and routes all traffic to the working server (`httpbun.com`).
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

The following diagram illustrates how Targets are used by Upstreams for load balancing:

<!--vale off-->

{% mermaid %}
flowchart LR
A("`Route
(/mock)`")
B("`Service
(example_service)`")
C(Load balancer)
D(httpbin.konghq.com)
E(httpbun.com)

subgraph id1 ["`**KONG GATEWAY**`"]
A --> B --> C
end

## Use cases for targets
subgraph id2 ["`Targets (example_upstream)`"]
C --> D & E
end

The following are examples of common use cases for targets:
style id1 rx:10,ry:10
style id2 stroke:none
{% endmermaid %}

<!--vale on-->

## Schema

{% entity_schema %}

## Set up a Target

{% entity_example %}
type: target
data:
upstream:
description: example_upstream
id: 173a6cee-90d1-40a7-89cf-0329eca780a6
weight: 100
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
{% endentity_example %}
74 changes: 68 additions & 6 deletions app/_gateway_entities/upstream.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
---
title: Upstreams
title: Upstreams
content_type: reference
entities:
- upstream

products:
- gateway

tools:
- admin-api
- kic
Expand All @@ -12,19 +15,78 @@ tools:

description: An upstream refers to the service applications sitting behind {{site.base_gateway}}, to which client requests are forwarded.

related_resources:
- text: Gateway Services entity
url: /gateway/entities/service/
- text: Routes entity
url: /gateway/entities/route/
- text: Targets entity
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
url: /gateway/entities/target/
- text: Routing in {{site.base_gateway}}
url: /gateway/routing/
- text: Expressions router
url: /gateway/routing/expressions/
- text: Upstreams
url: /gateway/entities/upstream/
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
- text: Proxying with {{site.base_gateway}}
url: /gateway/traffic-control/proxy/

schema:
api: gateway/admin-ee
path: /schemas/Upstream

---

## What is an upstream?
## What is an Upstream?

{{page.description}} In {{site.base_gateway}}, an Upstream represents a virtual hostname and can be used to [health check, circuit break]<!--TODO link concept-->, and [load balance]<!--TODO link concept--> incoming requests over multiple [Gateway Services](/gateway/entities/service/). In addition, the upstream entity has more advanced functionality algorithms like least-connections, consistent-hashing, and lowest-latency.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

If you don't need to load balance hostnames, we recommend using the `host` header on a [Route](/gateway/entities/route/) as the preferred method for routing a request and proxying traffic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what "load balance hostnames" means, could you rephrase? This doesn't really tell me why I'd pick routes instead.

cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

## Upstream and Service interaction

You can configure a Service to point to an Upstream instead of a host.
For example, if you have a Service called `example_service` and an Upstream called `example_upstream`, you can point `example_service` to `example_upstream` instead of specifying a host.
The `example_upstream` Upstream can then point to two different [targets](/gateway/entities/target/): `httpbin.konghq.com` and `httpbun.com`.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
In a real environment, the Upstream points to the same Service running on multiple systems.

This setup allows you to [load balance]<!--TODO link concept--> between upstream targets.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
For example, if an application is deployed across two different servers or upstream targets, {{site.base_gateway}} needs to load balance across both servers.
This is so that if one of the servers (like `httpbin.konghq.com` in the previous example) is unavailable, it automatically detects the problem and routes all traffic to the working server (`httpbun.com`).
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

The following diagram shows how Upstreams interact with other {{site.base_gateway}} entities:

{% mermaid %}
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
flowchart LR
A(API client)
B("`Route
(/mock)`")
C("`Service
(example-service)`")
D(Upstream
application)

A <--requests
responses--> B
subgraph id1 ["`
**KONG GATEWAY**`"]
B <--requests
responses--> C
end
C <--requests
responses--> D

style id1 rx:10,ry:10

{% endmermaid %}

{{page.description}} In {{site.base_gateway}}, an upstream represents a virtual hostname and can be used to health check, circuit break, and load balance incoming requests over multiple [target](/gateway/entities/target/) backend services.
## Use cases for Upstreams

## Use cases for upstreams
The following are examples of common use cases for Upstreams:

The following are examples of common use cases for upstreams:
* **Load balance:<!--TODO link how-to-->** When an Upstream points to multiple upstream targets, you can configure the Upstream entity to load balance traffic between the targets.
* **Health check:<!--TODO link how-to-->** Configure Upstreams to dynamically mark a target as healthy or unhealthy. This is an active check where a specific HTTP or HTTPS endpoint in the target is periodically requested and the health of the target is determined based on its response.
* **Circuit break:<!--TODO link how-to-->** Configure Upstreams to allow {{site.base_gateway}} to passively analyze the ongoing traffic being proxied and determine the health of targets based on their behavior responding to requests.
**Note:** This feature is not supported in hybrid mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


## Schema

Expand Down
66 changes: 66 additions & 0 deletions app/_how-tos/create-complex-routes-with-the-expressions-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: How to create rate limiting tiers with {{site.base_gateway}}
content_type: how_to
related_resources:
- text: Consumer Group API documentation
url: /api/gateway/admin-ee/
- text: Rate Limiting Advanced plugin
url: /plugins/rate-limiting-advanced/

products:
- gateway

works_on:
- on-prem
- konnect

tools:
- deck

prereqs:
entities:
services:
- example-service
routes:
- example-route

min_version:
gateway: 3.4

plugins:
- rate-limiting-advanced
- key-auth

entities:
- consumer
- consumer_group

tier: enterprise

tags:
- rate-limiting

tldr:
q: How do I rate limit different tiers of users, such as free vs. premium subscribers, in my API using {{site.base_gateway}}?
a: To effectively manage API traffic for various user tiers (such as free, basic, and premium subscribers) you can create consumer groups for each tier and assign individual consumers to these groups. Then, configure the Rate Limiting Advanced plugin to apply specific rate limits based on these groups. This setup allows you to enforce customized request limits for each tier, ensuring fair usage and optimizing performance for high-value users.

faqs:
- q: Why can't I use the regular Rate Limiting plugin to rate limit tiers of consumers?
a: We use the Rate Limiting Advanced plugin because it supports sliding windows, which we use to apply the rate limiting logic while taking into account previous hit rates (from the window that immediately precedes the current) using a dynamic weight.

cleanup:
inline:
- title: Clean up Konnect environment
include_content: cleanup/platform/konnect
icon_url: /assets/icons/gateway.svg
- title: Destroy the {{site.base_gateway}} container
include_content: cleanup/products/gateway
icon_url: /assets/icons/gateway.svg
---

## 1. things
<!--outlines:
How to:
- how do I configure it alongside the other entities it relies on?
- since regex is a common use case, I'd like to see that.
-->
107 changes: 107 additions & 0 deletions app/_how-tos/dynamically-rewrite-simple-request-urls-with-routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: Dynamically rewrite simple request URLs with {{site.base_gateway}} Routes
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
content_type: how_to
related_resources:
- text: Routes
url: /gateway/entities/route/
- text: Services
url: /gateway/entities/service/
- text: Routing in {{site.base_gateway}}
url: /gateway/routing/
- text: Expressions router
url: /gateway/routing/expressions/

products:
- gateway

works_on:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it works on both can the platform be agnostic?

- on-prem
- konnect

tools:
- deck

prereqs:
entities:
services:
- example-service
routes:
- example-route

entities:
- service
- route

tags:
- routing
- traffic-control

tldr:
q: How can I divert traffic from an old URL to a new one with {{site.base_gateway}}?
a: Set up a Gateway Service with the old URL path and create a new a Route with new path.For example, your legacy upstream endpoint may have a base URI like `/api/old/`. However, you want your publicly accessible API endpoint to now be named `/new/api`. To route the Service’s upstream endpoint to the new URL, you can set up a Service with the path `/api/old/` and a Route with the path `/new/api`.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thinjk the /api/new and /api/old are good examples of what you are trying to do but because the deck file and steps dont reflect that I got thrown off. I think that the api/old and api/new can be illustrated through the steps better than as the answer int he tld;r


faqs:
- q: My URLs are more complex, such as replacing `/api/<function>/old` with `/new/api/<function>`, what should I use instead to rewrite them?
a: You can use the [Request Transformer plugin](/hub/request-transformer/) for a complex URL rewrite or the [expressions router](/gateway/routing/expressions/) ({{site.base_gateway}} 3.0.x or later) to describe Routes or paths as patterns using regular expressions.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved

cleanup:
inline:
- title: Clean up Konnect environment
include_content: cleanup/platform/konnect
icon_url: /assets/icons/gateway.svg
- title: Destroy the {{site.base_gateway}} container
include_content: cleanup/products/gateway
icon_url: /assets/icons/gateway.svg
---

## 1. Set up a Service with the path to the old Upstream
Guaris marked this conversation as resolved.
Show resolved Hide resolved

In the prerequisites, you created the `example-service` and `example-route` with the `/anything` path. This path, `/anything`, is your old upstream path. You must modify your existing Service to contain the old `/anything` path. By doing it this way, traffic can continue to be routed to the old path while you enable the new path.

{% entity_examples %}
entities:
services:
- name: example-service
url: http://httpbin.konghq.com/anything
path: /anything
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
append_to_existing_section: true
{% endentity_examples %}

<!--figure out apphending-->

## 2. Set up a Route with the path to the new Upstream

Now you can create a Route with your new path, `/new-path`, that points to the new Upstream.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a second route and associates it to the service. So by this point you have:
1 service pointing to the upstream url http://httpbin.konghq.com/anything
2. routes proxying to it, one at /anything, and one at /new-path.
3. And an optional stray route from the prereq

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, i left this undone, you should remove the original /anything route

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the original route.

{% entity_examples %}
entities:
routes:
- name: new-route
paths:
- "/new-path"
service:
name: example-service
append_to_existing_section: true
{% endentity_examples %}

## 3. Apply configuration

{% include how-tos/steps/apply_config.md %}

## 4. Validate

To validate that the URL was successfully rewritten and the request is now being matched to the new Upstream instead of the old one, run the following:

```bash
curl -i http://localhost:8000/new-path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better test would be seeing what URL you are getting from the old path, and from the new one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Guaris I like this idea. I think the idea is that traffic is routed away from the old path to the new one, like a redirect (let me know if this is wrong), so if you go to the old path, should it redirect you to the new path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Guaris I think this is working correctly with http://localhost:8000/new-path as this is the response I get:


HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 486
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Wed, 18 Dec 2024 21:14:18 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 352
X-Kong-Proxy-Latency: 488
Via: 1.1 kong/3.9.0.0-enterprise-edition
X-Kong-Request-Id: 0bfd8c4c54274e4ffbbfcd2c5c939c65

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Connection": "keep-alive", 
    "Host": "httpbin.konghq.com", 
    "User-Agent": "curl/8.4.0", 
    "X-Forwarded-Host": "localhost", 
    "X-Forwarded-Path": "/new-path", 
    "X-Forwarded-Prefix": "/new-path", 
    "X-Kong-Request-Id": "0bfd8c4c54274e4ffbbfcd2c5c939c65"
  }, 
  "json": null, 
  "method": "GET", 
  "origin": "172.27.0.1", 
  "url": "http://localhost/anything"
}

```
{: data-deployment-topology="on-prem" }

```bash
curl -i http://{host}/new-path
```
{: data-deployment-topology="konnect" }
Replace `{host}` with the proxy URL for this data plane node.
{: data-deployment-topology="konnect" }

This command should display a 200 status as you're redirected to the new URL.
cloudjumpercat marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 9 additions & 0 deletions app/_includes/content/how-routing-works.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
For each incoming request, {{site.base_gateway}} must determine which Service gets to handle it based on the Routes that are defined. {{site.base_gateway}} handles routing in the following order:

1. {{site.base_gateway}} finds Routes that match the request by comparing the defined routing attributes with the attributes in the request.
1. If multiple Routes match, the {{site.base_gateway}} router then orders all defined Routes by their priority and uses the highest priority matching Route to handle a request.

If there are multiple matching Routes with the same priority, it is not defined
which of the matching Routes will be used and {{site.base_gateway}}
will use either of them according to how its internal data structures
are organized. If two or more Routes are configured with fields containing the same values, {{site.base_gateway}} applies a priority rule. {{site.base_gateway}} first tries to match the Routes with the most rules.
Loading
Loading