From ebec7afa70dbd5c93af0e0ffd266e200eafe2396 Mon Sep 17 00:00:00 2001 From: Tim O'Keefe Date: Mon, 21 Oct 2024 14:54:09 -0400 Subject: [PATCH] OSSM-8268: Getting traffic into the mesh --- _topic_maps/_topic_map.yml | 2 + .../ossm-getting-traffic-into-a-mesh.adoc | 16 ++ ...g-a-gateway-to-accept-ingress-traffic.adoc | 63 +++++++ ...services-to-traffic-outside-a-cluster.adoc | 18 ++ ...de-the-cluster-using-openshift-routes.adoc | 58 ++++++ ...sing-istio-gateway-and-virtualservice.adoc | 175 ++++++++++++++++++ 6 files changed, 332 insertions(+) create mode 100644 gateways/ossm-getting-traffic-into-a-mesh.adoc create mode 100644 modules/ossm-about-configuring-a-gateway-to-accept-ingress-traffic.adoc create mode 100644 modules/ossm-about-exposing-services-to-traffic-outside-a-cluster.adoc create mode 100644 modules/ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes.adoc create mode 100644 modules/ossm-exposing-service-using-istio-gateway-and-virtualservice.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 0b7df8a40f83..810f60e3e5bd 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -33,6 +33,8 @@ Distros: openshift-service-mesh Topics: - Name: About gateways File: ossm-about-gateways +- Name: Getting traffic into a mesh + File: ossm-getting-traffic-into-a-mesh --- Name: Observability Dir: observability diff --git a/gateways/ossm-getting-traffic-into-a-mesh.adoc b/gateways/ossm-getting-traffic-into-a-mesh.adoc new file mode 100644 index 000000000000..41191531c1f5 --- /dev/null +++ b/gateways/ossm-getting-traffic-into-a-mesh.adoc @@ -0,0 +1,16 @@ +:_content-type: ASSEMBLY +[id="ossm-getting-traffic-into-a-mesh"] += Getting traffic into a mesh +include::_attributes/common-attributes.adoc[] +:context: ossm-getting-traffic-into-a-mesh + +toc::[] + +Using {istio} APIs, you can configure gateway proxies that were installed using gateway injection to accept traffic originating from outside the mesh, and route that traffic to the services within the mesh. + +You can expose gateway proxies to traffic outside a cluster by using either a `LoadBalancer` type `Service` or {ocp-short-name} `Routes`. + +include::modules/ossm-about-configuring-a-gateway-to-accept-ingress-traffic.adoc[leveloffset=+1] +include::modules/ossm-exposing-service-using-istio-gateway-and-virtualservice.adoc[leveloffset=+2] +include::modules/ossm-about-exposing-services-to-traffic-outside-a-cluster.adoc[leveloffset=+1] +include::modules/ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes.adoc[leveloffset=+2] \ No newline at end of file diff --git a/modules/ossm-about-configuring-a-gateway-to-accept-ingress-traffic.adoc b/modules/ossm-about-configuring-a-gateway-to-accept-ingress-traffic.adoc new file mode 100644 index 000000000000..32a21595be1e --- /dev/null +++ b/modules/ossm-about-configuring-a-gateway-to-accept-ingress-traffic.adoc @@ -0,0 +1,63 @@ +// Module included in the following assemblies: + +// gateways/ossm-about-gateways.adoc + +:_mod-docs-content-type: Concept +[id="ossm-about-configuring-a-gateway-to-accept-ingress-traffic_{context}"] += About configuring a gateway installed using gateway injection to accept ingress traffic +:context: ossm-about-configuring-a-gateway-to-accept-ingress-traffic + +When you install a gateway using gateway injection you can configure it to receive ingress traffic using the {istio} `Gateway` and `VirtualService` resources in combination. The {istio} `Gateway` resource describes a load balancer operating at the edge of the mesh that receives incoming or outgoing HTTP/TCP connections. The `Gateway` specification describes a set of ports that should be exposed, the type of protocol to use, and the Server Name Indication (SNI) configuration for the load balancer. `VirtualServices` define routing rules to apply to an {istio} `Gateway`, similar to how you can use `VirtualServices` to define routing rules for internal mesh traffic. + +In the following example an {istio} `Gateway` resource configures a gateway proxy to act as an entry point for external traffic. This configuration exposes port 443 (HTTPS) for the host, `bookinfo.com`. The example configuration applies to pods with the `istio: ingressgateway` label. These pods typically correspond to ingress gateway pods. The `tls` mode is configured as `SIMPLE`, which terminates the incoming HTTPS traffic using the certificate and private key the example provides. + +.Sample configuration +[source,yaml,subs="attributes,verbatim"] +---- +apiVersion: networking.istio.io/v1 +kind: Gateway +metadata: + name: bookinfo-gateway + namespace: bookinfo +spec: + selector: + istio: ingressgateway + servers: + - port: + number: 443 + name: https-443 + protocol: HTTPS + hosts: + - bookinfo.com + tls: + mode: SIMPLE + serverCertificate: /etc/certs/servercert.pem + privateKey: /etc/certs/privatekey.pem +# ... +---- + +The following `VirtualService` is bound to the {istio} `Gateway` resource previously shown in the previous example configuration. The specification defines rules to route traffic with the `/reviews/` path prefix to the reviews service in the `bookinfo` namespace. The `VirtualService` explicitly references the gateway to ensure that the rules are only applied to the traffic that enters through the specified gateway. + +.Sample configuration +[source,yaml,subs="attributes,verbatim"] +---- +kind: VirtualService +metadata: + name: bookinfo-rule + namespace: bookinfo +spec: + hosts: + - bookinfo.com + gateways: + - bookinfo/bookinfo-gateway + http: + - match: + - uri: + prefix: /reviews/ + route: + - destination: + port: + number: 9080 + host: reviews.bookinfo.svc.cluster.local +# ... +---- \ No newline at end of file diff --git a/modules/ossm-about-exposing-services-to-traffic-outside-a-cluster.adoc b/modules/ossm-about-exposing-services-to-traffic-outside-a-cluster.adoc new file mode 100644 index 000000000000..1a93f74f89fb --- /dev/null +++ b/modules/ossm-about-exposing-services-to-traffic-outside-a-cluster.adoc @@ -0,0 +1,18 @@ +// Module included in the following assemblies: + +// gateways/ossm-about-gateways.adoc + +:_mod-docs-content-type: Concept +[id="ossm-about-exposing-services-to-traffic-outside-a-cluster_{context}"] += About exposing services to traffic outside a cluster +:context: ossm-about-exposing-services-to-traffic-outside-a-cluster + +To enable traffic from outside an {ocp-short-name} cluster to access services in a mesh, you must expose a gateway proxy by either setting its `Service` type to `LoadBalancer` or by using the {ocp-short-name} Router. + +Using Kubernetes load balancing to handle incoming traffic directly through the inbound gateway can reduce latency associated with data encryption. By managing encryption at the inbound gateway, you avoid the intermediate decryption and re-encryption steps within the mesh that often add latency. This approach allows mesh traffic to be encrypted and decrypted only once, which is generally more efficient. + +The {ocp-short-name} Router provides a standard approach for managing ingress traffic, and you can use the router to manage certificates for all cluster ingress traffic using the same methods. However, the {ocp-short-name} Router introduces an additional hop between the inbound traffic and the mesh applications. Typically, you route the traffic by decrypting it at the router and then re-encrypting it at the service mesh ingress gateway, which introduces latency. + +// If you are using the Gateway API with automatic deployment, this is the default setting. If you are using Gateway Injection, you have to set the field manually. + +// If you are using Gateway API, you must use the networking.istio.io/service-type annotation on the Kubernetes Gateway resource to set the spec.type parameter of the gateway Service. If you are using gateway injection, you have to set the field manually. diff --git a/modules/ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes.adoc b/modules/ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes.adoc new file mode 100644 index 000000000000..32b343cd5e5a --- /dev/null +++ b/modules/ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes.adoc @@ -0,0 +1,58 @@ +// This procedure is used in the following assembly: +// * gateways/ossm-getting-traffic-into-a-mesh.adoc + +:_mod-docs-content-type: PROCEDURE +[id="ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes_{context}"] += Exposing a gateway to traffic outside the cluster by using OpenShift Routes +:context: ossm-exposing-a-gateway-to-traffic-outside-the-cluster-using-openshift-routes + +You can expose a gateway to traffic outside the cluster by using {ocp-short-name} Routes. This approach provides an alternative to using Kubernetes load balancer service when you have to expose gateways to traffic outside the cluster. + +.Prerequisites + +* You have installed a gateway using gateway injection. + +.Procedure + +. Ensure that the `Service`` type is set to `ClusterIP`. ++ +[source,terminal] +---- +oc patch service -n -p '{"spec": {"type": "ClusterIP"}}' +---- + +. Create a `Route`. ++ +[source,yaml,subs="attributes,verbatim"] +---- +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: httpbin + namespace: +spec: + host: httpbin.example.com + port: + targetPort: http2 + to: + kind: Service + name: + weight: 100 + wildcardPolicy: None + # ... +---- + +. Verify that httpbin service can be accessed from outside the cluster through the ingress router. Ensure that you set the `INGRESS_HOST` variable appropriately for the environment that your cluster is running in. ++ +[source,terminal] +---- +# If the cluster is running on AWS: +INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') + +# If the cluster is running on GCP or Azure: +INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + +curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers +---- + +. Verify that the terminal returns `HTTP/1.1 200 OK` which indicates that the request was successful. diff --git a/modules/ossm-exposing-service-using-istio-gateway-and-virtualservice.adoc b/modules/ossm-exposing-service-using-istio-gateway-and-virtualservice.adoc new file mode 100644 index 000000000000..308446d0b8be --- /dev/null +++ b/modules/ossm-exposing-service-using-istio-gateway-and-virtualservice.adoc @@ -0,0 +1,175 @@ +// This procedure is used in the following assembly: +// * gateways/ossm-getting-traffic-into-a-mesh.adoc + +:_mod-docs-content-type: PROCEDURE +[id="ossm-exposing-service-using-istio-gateway-and-virtualservice_{context}"] += Exposing a service by using the {istio} gateway and VirtualService resources +:context: ossm-exposing-service-using-istio-gateway-and-virtualservice + +This procedure uses the {istio} `Gateway` and `VirtualService` resources to configure a gateway that was deployed by using gateway injection. The resources configure the gateway to expose a service in the mesh to traffic outside the mesh. You can expose the gateway to traffic outside the cluster by setting the `Service` for the gateway to type `LoadBalancer`. + +.Prerequisites + +* You have installed an {istio} gateway using gateway injection. + +.Procedure + +. Create namespace called `httpbin`: ++ +[source,terminal] +---- +$ oc create namespace httpbin +---- + +. Label the namespace to enable {istio} sidecar injection: ++ +[source,terminal] +---- +$ oc label namespace httpbin istio-injection=enabled +---- + +. Deploy a sample service by applying the `http.yaml` file: ++ +[source,terminal] +---- +$ oc apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/refs/heads/release-1.24/samples/httpbin/httpbin.yaml +---- + +. Create a YAML file named `httpbin-gw.yaml` that defines an Istio `Gateway` resource. This resource configures gateway proxies to expose port 80 (HTTP) for the host, `httpbin.example.com`. ++ +[source,yaml,subs="attributes,verbatim"] +---- +apiVersion: networking.istio.io/v1 +kind: Gateway +metadata: + name: httpbin-gateway + namespace: httpbin +spec: + selector: + istio: <1> + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - httpbin.example.com <2> +# ... +---- +<1> Set the `selector` to the unique label or set of labels specified in the pod template of the gateway proxy `Deployment`. By default, the {istio} `Gateway` resource configuration will apply to matching gateway pods in all namespaces. +<2> Using the `hosts` field, specify a list of addresses that can be used by clients when attempting to access a mesh service at the associated port. + +. Apply the YAML file by running the following command: ++ +[source,terminal] +---- +$ oc apply -f httpbin-gw.yaml +---- + +. Create a YAML file named `httpbin-vs.yaml` for a `VirtualService` The `VirtualService` defines the rules that route traffic from the gateway proxy to the `httpbin` service. ++ +[source,yaml,subs="attributes,verbatim"] +---- +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: httpbin + namespace: httpbin +spec: + hosts: + - httpbin.example.com <1> + gateways: + - httpbin-gateway <2> + http: + - match: + - uri: + prefix: /status + - uri: + prefix: /headers + route: + - destination: <3> + port: + number: 8000 + host: httpbin +# ... +---- +<1> Specify the `hosts` that the routing rules of the `VirtualService` will be applied to. The `hosts` specified must be exposed by the {istio} `Gateway` resource the VirtualService is bound to. +<2> Bind the `VirtualService` to the {istio} `Gateway` resource created in the previous step by adding the `Gateway` name to the list of gateways. +<3> Route matching traffic to the `httpbin` service deployed earlier by defining a `destination` that includes the `host` and `port` of the httpbin `Service`. + +. Apply the YAML file by running the following command: ++ +[source,terminal] +---- +$ oc apply -f httpbin-vs.yaml +---- + +. For verification purposes, create a namespace for a `curl` client: ++ +[source,terminal] +---- +$ oc create namespace curl +---- + +. Deploy the `curl` client by applying the curl.yaml file: ++ +[source,terminal] +---- +$ oc apply -n curl -f https://raw.githubusercontent.com/istio/istio/refs/heads/release-1.24/samples/curl/curl.yaml +---- + +. Using the `curl` client, send a request to the `/headers` endpoint of the `httpbin` application through the ingress gateway `Service`. Set the `Host` header of the request to `httpbin.example.com` to match the host that the {istio} `Gateway` and `VirtualService` resources specify. ++ +[source,terminal] +---- +CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}') + +oc exec $CURL_POD -n curl -- \ + curl -s -I \ + -H Host:httpbin.example.com \ + ..svc.cluster.local/headers +---- + +. The response should have a `200 OK HTTP` status indicating that the request was successful. ++ +.Example output +[source,terminal] +---- +HTTP/1.1 200 OK +server: istio-envoy +... +---- + +. Send a curl request to an endpoint that does not have a corresponding URI prefix match defined in the httpbin `VirtualService`: ++ +[source,terminal] +---- +oc exec $CURL_POD -n curl -- \ + curl -s -I \ + -H Host:httpbin.example.com \ + ..svc.cluster.local/get +---- ++ +The response should return a `404 Not Found` status. This is expected because the `/get` endpoint does not have a matching URI prefix in the httpbin `VirtualService`. ++ +.Example output +[source,terminal] +---- +HTTP/1.1 404 Not Found +server: istio-envoy +... +---- + +. Expose the gateway proxy to traffic outside the cluster by setting the `Service` type to `LoadBalancer`. ++ +[source,terminal] +---- +oc patch service -n -p '{"spec": {"type": "LoadBalancer"}}' +---- ++ +[NOTE] +==== +A gateway can also be exposed to traffic outside the cluster by using {ocp-short-name} Routes. For more information, see "Exposing a gateway to traffic outside the cluster using {ocp-short-name} Routes". +==== + +. Verify that the httpbin service can now be accessed from outside the cluster. Ensure that you set the `INGRESS_HOST` variable appropriately for the environment your cluster is running in. \ No newline at end of file