gateway-api: add gateway api instruction to request routing task (#12204)

* gateway-api: add gateway api instruction to request routing task

* lint

* regen

* improve gamma tip/warning

* lint

* add port

* fix samples.sh

* fixes
This commit is contained in:
Frank Budinsky 2022-11-10 14:32:57 -05:00 committed by GitHub
parent ef5010daaf
commit 69981b01b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 492 additions and 141 deletions

View File

@ -0,0 +1,5 @@
---
---
The following instructions allow you to choose to use either the Gateway API or the Istio configuration API when configuring
traffic management in the mesh. Follow instructions under either the `Gateway API` or `Istio classic` tab,
according to your preference.

View File

@ -0,0 +1,18 @@
---
---
{{< tip >}}
{{< boilerplate gateway-api-future >}}
{{< boilerplate gateway-api-choose >}}
Note that this document uses the Gateway API to configure internal mesh (east-west) traffic,
i.e., not just ingress (north-south) traffic.
Configuring internal mesh traffic using the Gateway API is an
[experimental feature](https://gateway-api.sigs.k8s.io/concepts/versioning/#release-channels-eg-experimental-standard)
currently under development and pending [upstream agreement](https://gateway-api.sigs.k8s.io/contributing/gamma/).
Make sure to install the experimental CRDs before using the Gateway API:
{{< text syntax=bash snip_id=install_experimental_crds >}}
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref={{< k8s_gateway_api_version >}}" | kubectl apply -f -
{{< /text >}}
{{< /tip >}}

View File

@ -2,9 +2,7 @@
---
{{< tip >}}
{{< boilerplate gateway-api-future >}}
The following instructions allow you to choose to use either the Gateway API or the Istio configuration API when configuring
traffic management in the mesh. Follow instructions under either the `Gateway API` or `Istio classic` tab,
according to your preference.
{{< boilerplate gateway-api-choose >}}
Note that the Kubernetes Gateway API CRDs do not come installed by default on most Kubernetes clusters, so make sure they are
installed before using the Gateway API:

View File

@ -0,0 +1,25 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2153,SC2155,SC2164
# Copyright Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
####################################################################################################
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
# boilerplates/gateway-api-gamma-support.md
####################################################################################################
bpsnip_gateway_api_gamma_support_install_experimental_crds() {
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.5.1" | kubectl apply -f -
}

View File

@ -252,7 +252,7 @@ currently under development and pending [upstream agreement](https://gateway-api
{{< /warning >}}
The Gateway API can also be used to configure mesh traffic.
This is done by configuring the `parentRef` to point to a service, instead of a gateway.
This is done by configuring the `parentRef` to point to a service, instead of a gateway.
For example, to add a header on all calls to an in-cluster `Service` named `example`:
@ -277,6 +277,8 @@ spec:
port: 80
{{< /text >}}
More details and examples can be found in other [traffic management tasks](/docs/tasks/traffic-management/).
## Cleanup
1. Uninstall Istio and the `httpbin` sample:

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# shellcheck disable=SC1090,SC2154
# Copyright Istio Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source "tests/util/gateway-api.sh"
install_gateway_api_crds
# @setup profile=default
source "content/en/docs/tasks/traffic-management/request-routing/test.sh"
# @cleanup
source "tests/util/samples.sh"
snip_cleanup_2
cleanup_bookinfo_sample
cleanup_sleep_sample
remove_gateway_api_crds

View File

@ -12,6 +12,8 @@ test: yes
This task shows you how to route requests dynamically to multiple versions of a
microservice.
{{< boilerplate gateway-api-gamma-support >}}
## Before you begin
* Setup Istio by following the instructions in the
@ -19,13 +21,16 @@ microservice.
* Deploy the [Bookinfo](/docs/examples/bookinfo/) sample application.
* Review the [Traffic Management](/docs/concepts/traffic-management) concepts doc. Before attempting this task, you should be familiar with important terms such as *destination rule*, *virtual service*, and *subset*.
* Review the [Traffic Management](/docs/concepts/traffic-management) concepts doc.
## About this task
The Istio [Bookinfo](/docs/examples/bookinfo/) sample consists of four separate microservices, each with multiple versions.
Three different versions of one of the microservices, `reviews`, have been deployed and are running concurrently.
To illustrate the problem this causes, access the Bookinfo app's `/productpage` in a browser and refresh several times.
The URL is `http://$GATEWAY_URL/productpage`, where `$GATEWAY_URL` is the External IP address of the ingress, as explained in
the [Bookinfo](/docs/examples/bookinfo/#determine-the-ingress-ip-and-port) doc.
Youll notice that sometimes the book review output contains star ratings and other times it does not.
This is because without an explicit default service version to route to, Istio routes requests to all available versions
in a round robin fashion.
@ -33,79 +38,168 @@ in a round robin fashion.
The initial goal of this task is to apply rules that route all traffic to `v1` (version 1) of the microservices. Later, you
will apply a rule to route traffic based on the value of an HTTP request header.
## Apply a virtual service
## Route to version 1
To route to one version only, you apply virtual services that set the default version for the microservices.
In this case, the virtual services will route all traffic to `v1` of each microservice.
To route to one version only, you configure route rules that send traffic to default versions for the microservices.
{{< warning >}}
If you haven't already applied destination rules, follow the instructions in [Apply Default Destination Rules](/docs/examples/bookinfo/#apply-default-destination-rules).
If you haven't already, follow the instructions in [define the service versions](/docs/examples/bookinfo/#define-the-service-versions).
{{< /warning >}}
1. Run the following command to apply the virtual services:
1. Run the following command to create the route rules:
{{< text bash >}}
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
{{< /text >}}
{{< tabset category-name="config-api" >}}
Because configuration propagation is eventually consistent, wait a few seconds
for the virtual services to take effect.
{{< tab name="Istio classic" category-value="istio-classic" >}}
1. Display the defined routes with the following command:
Istio uses virtual services to define route rules.
Run the following command to apply virtual services that will route all traffic to `v1` of each microservice:
{{< text bash yaml >}}
$ kubectl get virtualservices -o yaml
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
{{< /text >}}
{{< text bash >}}
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
{{< /text >}}
1. You can also display the corresponding `subset` definitions with the following command:
Because configuration propagation is eventually consistent, wait a few seconds
for the virtual services to take effect.
{{< text bash >}}
$ kubectl get destinationrules -o yaml
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
2) Display the defined routes with the following command:
{{< tabset category-name="config-api" >}}
{{< tab name="Istio classic" category-value="istio-classic" >}}
{{< text bash yaml >}}
$ kubectl get virtualservices -o yaml
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
{{< /text >}}
You can also display the corresponding `subset` definitions with the following command:
{{< text bash >}}
$ kubectl get destinationrules -o yaml
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl get httproute reviews -o yaml
...
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- group: ""
kind: Service
name: reviews-v1
port: 9080
weight: 1
matches:
- path:
type: PathPrefix
value: /
status:
parents:
- conditions:
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: Route was valid
observedGeneration: 8
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: All references resolved
observedGeneration: 8
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
group: gateway.networking.k8s.io
kind: Service
name: reviews
port: 9080
{{< /text >}}
In the resource status, make sure that the `Accepted` condition is `True` for the `reviews` parent.
{{< /tab >}}
{{< /tabset >}}
You have configured Istio to route to the `v1` version of the Bookinfo microservices,
most importantly the `reviews` service version 1.
@ -113,15 +207,11 @@ most importantly the `reviews` service version 1.
## Test the new routing configuration
You can easily test the new configuration by once again refreshing the `/productpage`
of the Bookinfo app.
1. Open the Bookinfo site in your browser. The URL is `http://$GATEWAY_URL/productpage`, where `$GATEWAY_URL` is the External IP address of the ingress, as explained in
the [Bookinfo](/docs/examples/bookinfo/#determine-the-ingress-ip-and-port) doc.
Notice that the reviews part of the page displays with no rating stars, no
matter how many times you refresh. This is because you configured Istio to route
all traffic for the reviews service to the version `reviews:v1` and this
version of the service does not access the star ratings service.
of the Bookinfo app in your browser.
Notice that the reviews part of the page displays with no rating stars, no
matter how many times you refresh. This is because you configured Istio to route
all traffic for the reviews service to the version `reviews:v1` and this
version of the service does not access the star ratings service.
You have successfully accomplished the first part of this task: route traffic to one
version of a service.
@ -143,41 +233,78 @@ Remember, `reviews:v2` is the version that includes the star ratings feature.
1. Run the following command to enable user-based routing:
{{< text bash >}}
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@
{{< /text >}}
{{< tabset category-name="config-api" >}}
1. Confirm the rule is created:
{{< tab name="Istio classic" category-value="istio-classic" >}}
{{< text bash yaml >}}
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
{{< /text >}}
{{< text bash >}}
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@
{{< /text >}}
1. On the `/productpage` of the Bookinfo app, log in as user `jason`.
You can confirm the rule is created using the following command:
{{< text bash yaml >}}
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- kind: Service
name: reviews
port: 9080
rules:
- matches:
- headers:
- name: end-user
value: jason
backendRefs:
- name: reviews-v2
port: 9080
- backendRefs:
- name: reviews-v1
port: 9080
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
2) On the `/productpage` of the Bookinfo app, log in as user `jason`.
Refresh the browser. What do you see? The star ratings appear next to each
review.
1. Log in as another user (pick any name you wish).
3) Log in as another user (pick any name you wish).
Refresh the browser. Now the stars are gone. This is because traffic is routed
to `reviews:v1` for all users except Jason.
@ -201,12 +328,28 @@ gradually send traffic from one version of a service to another.
## Cleanup
1. Remove the application virtual services:
1. Remove the application route rules:
{{< text bash >}}
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
{{< /text >}}
{{< tabset category-name="config-api" >}}
1. If you are not planning to explore any follow-on tasks, refer to the
{{< tab name="Istio classic" category-value="istio-classic" >}}
{{< text bash >}}
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl delete httproute reviews
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
2) If you are not planning to explore any follow-on tasks, refer to the
[Bookinfo cleanup](/docs/examples/bookinfo/#cleanup) instructions
to shutdown the application.

View File

@ -19,16 +19,35 @@
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
# docs/tasks/traffic-management/request-routing/index.md
####################################################################################################
source "content/en/boilerplates/snips/gateway-api-gamma-support.sh"
snip_apply_a_virtual_service_1() {
snip_route_to_version_1_1() {
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
}
snip_apply_a_virtual_service_2() {
snip_route_to_version_1_2() {
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
EOF
}
snip_route_to_version_1_3() {
kubectl get virtualservices -o yaml
}
! read -r -d '' snip_apply_a_virtual_service_2_out <<\ENDSNIP
! read -r -d '' snip_route_to_version_1_3_out <<\ENDSNIP
- apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
@ -75,10 +94,56 @@ kubectl get virtualservices -o yaml
subset: v1
ENDSNIP
snip_apply_a_virtual_service_3() {
snip_route_to_version_1_4() {
kubectl get destinationrules -o yaml
}
snip_route_to_version_1_5() {
kubectl get httproute reviews -o yaml
}
! read -r -d '' snip_route_to_version_1_5_out <<\ENDSNIP
...
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- group: ""
kind: Service
name: reviews-v1
port: 9080
weight: 1
matches:
- path:
type: PathPrefix
value: /
status:
parents:
- conditions:
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: Route was valid
observedGeneration: 8
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: All references resolved
observedGeneration: 8
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
group: gateway.networking.k8s.io
kind: Service
name: reviews
port: 9080
ENDSNIP
snip_route_based_on_user_identity_1() {
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
}
@ -109,6 +174,35 @@ spec:
subset: v1
ENDSNIP
snip_route_based_on_user_identity_3() {
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- kind: Service
name: reviews
port: 9080
rules:
- matches:
- headers:
- name: end-user
value: jason
backendRefs:
- name: reviews-v2
port: 9080
- backendRefs:
- name: reviews-v1
port: 9080
EOF
}
snip_cleanup_1() {
kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
}
snip_cleanup_2() {
kubectl delete httproute reviews
}

View File

@ -19,6 +19,8 @@ set -e
set -u
set -o pipefail
GATEWAY_API="${GATEWAY_API:-false}"
source "tests/util/samples.sh"
# @setup profile=default
@ -38,42 +40,56 @@ startup_sleep_sample # needed for sending test requests with curl
startup_bookinfo_sample
# set default route rules
snip_apply_a_virtual_service_1
if [ "$GATEWAY_API" == "true" ]; then
snip_route_to_version_1_2
_verify_lines snip_route_to_version_1_5 "
+ message: Route was valid
+ reason: Accepted
"
else
snip_route_to_version_1_1
# wait for rules to propagate
_wait_for_istio virtualservice default productpage
_wait_for_istio virtualservice default reviews
_wait_for_istio virtualservice default ratings
_wait_for_istio virtualservice default details
# wait for rules to propagate
_wait_for_istio virtualservice default productpage
_wait_for_istio virtualservice default reviews
_wait_for_istio virtualservice default ratings
_wait_for_istio virtualservice default details
# confirm route rules are set
_verify_elided snip_apply_a_virtual_service_2 "$snip_apply_a_virtual_service_2_out"
# confirm route rules are set
_verify_elided snip_route_to_version_1_3 "$snip_route_to_version_1_3_out"
# check destination rules
_verify_lines snip_apply_a_virtual_service_3 "
+ productpage
+ reviews
+ ratings
+ details
"
# check destination rules
_verify_lines snip_route_to_version_1_4 "
+ productpage
+ reviews
+ ratings
+ details
"
fi
# check that requests do not return ratings
_verify_not_contains get_bookinfo_productpage "glyphicon glyphicon-star"
# route traffic for user jason to reviews:v2
snip_route_based_on_user_identity_1
if [ "$GATEWAY_API" == "true" ]; then
snip_route_based_on_user_identity_3
else
snip_route_based_on_user_identity_1
# wait for rules to propagate
_wait_for_istio virtualservice default reviews
# wait for rules to propagate
_wait_for_istio virtualservice default reviews
# confirm route rules are set
_verify_elided snip_route_based_on_user_identity_2 "$snip_route_based_on_user_identity_2_out"
# confirm route rules are set
_verify_elided snip_route_based_on_user_identity_2 "$snip_route_based_on_user_identity_2_out"
fi
# check that requests from user jason return ratings and other requests do not
_verify_contains get_bookinfo_productpage_jason "glyphicon glyphicon-star"
_verify_not_contains get_bookinfo_productpage "glyphicon glyphicon-star"
# @cleanup
snip_cleanup_1
cleanup_bookinfo_sample
cleanup_sleep_sample
if [ "$GATEWAY_API" != "true" ]; then
snip_cleanup_1
cleanup_bookinfo_sample
cleanup_sleep_sample
fi

View File

@ -15,10 +15,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
GATEWAY_API="${GATEWAY_API:-false}"
startup_bookinfo_sample() {
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
if [ "$GATEWAY_API" == "true" ]; then
kubectl apply -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml
kubectl wait --for=condition=ready gtw bookinfo-gateway --timeout=2m
kubectl apply -f samples/bookinfo/platform/kube/bookinfo-versions.yaml
else
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
fi
for deploy in "productpage-v1" "details-v1" "ratings-v1" "reviews-v1" "reviews-v2" "reviews-v3"; do
_wait_for_deployment default "$deploy"
@ -27,8 +36,14 @@ startup_bookinfo_sample() {
cleanup_bookinfo_sample() {
kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml || true
kubectl delete -f samples/bookinfo/networking/destination-rule-all.yaml || true
kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml || true
if [ "$GATEWAY_API" == "true" ]; then
kubectl delete -f samples/bookinfo/platform/kube/bookinfo-versions.yaml || true
kubectl delete -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml || true
else
kubectl delete -f samples/bookinfo/networking/destination-rule-all.yaml || true
kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml || true
fi
}
startup_sleep_sample() {
@ -76,10 +91,16 @@ sample_http_request() {
user="$2"
fi
local ingress_url="http://istio-ingressgateway.istio-system"
local ingress_url
local sleep_pod
local response
if [ "$GATEWAY_API" == "true" ]; then
ingress_url="http://bookinfo-gateway.default"
else
ingress_url="http://istio-ingressgateway.istio-system"
fi
sleep_pod=$(kubectl get pod -l app=sleep -n default -o 'jsonpath={.items..metadata.name}')
local args=""