Chapter 2. Getting traffic into a mesh
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 OpenShift Routes
.
2.1. About configuring a gateway installed using gateway injection to accept ingress traffic Copy linkLink copied to clipboard!
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. The tls
mode is configured as SIMPLE
, which terminates the incoming HTTPS traffic using the certificate and private key the example provides.
Sample configuration
The following VirtualService
is bound to the Istio Gateway
resource 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
resource shown previously. This ensures that the routing rules are only applied to the traffic that enters through the specified gateway.
Sample configuration
2.1.1. Exposing a service by using the Istio Gateway and VirtualService resources Copy linkLink copied to clipboard!
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. Then, you 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
by running the following command:oc create namespace httpbin
$ oc create namespace httpbin
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable sidecar injection in the namespace. If you are using the
InPlace
upgrade strategy, run the following command:oc label namespace httpbin istio-injection=enabled
$ oc label namespace httpbin istio-injection=enabled
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteIf you are using the
RevisionBased
upgrade strategy, run the following commands:To find your
<revision-name>
, run the following command:oc get istiorevisions.sailoperator.io
$ oc get istiorevisions.sailoperator.io
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample output:
NAME TYPE READY STATUS IN USE VERSION AGE default Local True Healthy True v1.24.3 3m33s
NAME TYPE READY STATUS IN USE VERSION AGE default Local True Healthy True v1.24.3 3m33s
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Label the namespace with the revision name to enable sidecar injection:
oc label namespace httpbin istio.io/rev=default
$ oc label namespace httpbin istio.io/rev=default
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Deploy a sample service named
httpbin
by running the following command:oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-gw.yaml
that defines an IstioGateway
resource. This resource configures gateway proxies to expose port 80 (HTTP) for the host,httpbin.example.com
.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Set the
selector
to the unique label or set of labels specified in the pod template of the gateway proxyDeployment
. By default, the IstioGateway
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:
oc apply -f httpbin-gw.yaml
$ oc apply -f httpbin-gw.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-vs.yaml
for aVirtualService
. TheVirtualService
defines the rules that route traffic from the gateway proxy to thehttpbin
service.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specify the
hosts
that the routing rules of theVirtualService
will be applied to. Thehosts
specified must be exposed by the IstioGateway
resource the VirtualService is bound to. - 2
- Bind the
VirtualService
to the IstioGateway
resource created in the previous step by adding theGateway
name to the list of gateways. - 3
- Route matching traffic to the
httpbin
service deployed earlier by defining adestination
that includes thehost
andport
of thehttpbin
Service
.
Apply the YAML file by running the following command:
oc apply -f httpbin-vs.yaml
$ oc apply -f httpbin-vs.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For verification purposes, create a namespace for a
curl
client by running the following command:oc create namespace curl
$ oc create namespace curl
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy the
curl
client by running the following command:oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set a
CURL_POD
variable with the name of thecurl
pod by running the following command:CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using the
curl
client, send a request to the/headers
endpoint of thehttpbin
application through the ingress gatewayService
resource. Set theHost
header of the request tohttpbin.example.com
to match the host that the IstioGateway
andVirtualService
resources specify. Run the followingcurl
command to send the request:oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/headers
$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/headers
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The response should have a
200 OK HTTP
status indicating that the request was successful.Example output
HTTP/1.1 200 OK server: istio-envoy ...
HTTP/1.1 200 OK server: istio-envoy ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Send a curl request to an endpoint that does not have a corresponding URI prefix match defined in the
httpbin
VirtualService
by running the following command:oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/get
$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/get
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The response should return a
404 Not Found
status. This is expected because the/get
endpoint does not have a matching URI prefix in thehttpbin
VirtualService
resource.Example output
HTTP/1.1 404 Not Found server: istio-envoy ...
HTTP/1.1 404 Not Found server: istio-envoy ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Expose the gateway proxy to traffic outside the cluster by setting the
Service
type toLoadBalancer
:oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
$ oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteA gateway can also be exposed to traffic outside the cluster by using OpenShift Routes. For more information, see "Exposing a gateway to traffic outside the cluster using OpenShift Routes".
Verify that
httpbin
service can be accessed from outside the cluster when using the external hostname or IP address of the gatewayService
resource. Ensure that you set theINGRESS_HOST
variable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOST
variable by running the following command:INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the cluster runs on GCP or Azure, set the
INGRESS_HOST
variable by running the following command:INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Send a
curl
request to thehttpbin
service using the host of the gateway by running the following command:curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OK
status, which indicates that the request was successful.
2.2. About exposing services to traffic outside a cluster Copy linkLink copied to clipboard!
To enable traffic from outside an OpenShift 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 OpenShift 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 OpenShift 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 OpenShift 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.
2.2.1. Exposing a gateway to traffic outside the cluster by using OpenShift Routes Copy linkLink copied to clipboard!
You can expose a gateway to traffic outside the cluster by using OpenShift 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 completed the procedure, Exposing a Service by using the Istio Gateway and VirtualService resources.
Procedure
Ensure that the
Service
type is set toClusterIP
by running the following command:oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "ClusterIP"}}'
$ oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "ClusterIP"}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-route.yaml
that defines aRoute
for thehttpbin
service.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f httpbin-route.yaml
$ oc apply -f httpbin-route.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that
httpbin
service can be accessed from outside the cluster through the ingress router. Ensure that you set theINGRESS_HOST
variable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOST
variable by running the following command:INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
$ INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the cluster runs on GCP or Azure, set the
INGRESS_HOST
variable by running the following command:INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Send a
curl
request to thehttpbin
service using the host of the ingress router by running the following command:curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OK
status, which indicates that the request was successful.
2.3. Exposing a service by using the Kubernetes Gateway API Copy linkLink copied to clipboard!
Use the Kubernetes Gateway API to create Gateway
and HTTPRoute
resources and deploy a gateway. The resources configure the gateway to expose a service in the mesh to traffic outside the mesh. Then, you can set the Service
for the gateway to LoadBalancer
to expose the gateway to traffic outside the cluster.
Prerequisites
-
You are logged in to the OpenShift Container Platform web console as a user with the
cluster-admin
role. - You installed the Red Hat OpenShift Service Mesh Operator.
- You deployed the Istio resource.
Procedure
Create a namespace called
httpbin
by running the following command:oc create namespace httpbin
$ oc create namespace httpbin
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy a sample service named
httpbin
by running the following command:oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-gw.yaml
that defines a Kubernetes Gateway resource. This resource configures gateway proxies to expose port 80 (HTTP) for the host,httpbin.example.com
.Example gateway resource file
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specifies the virtual hostname that clients use when attempting to access a mesh service on the associated port.
Apply the YAML file by running the following command:
oc apply -f httpbin-gw.yaml
$ oc apply -f httpbin-gw.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-hr.yaml
that defines anHTTPRoute
resource. TheHTTPRoute
resource specifies the rules that route traffic from the gateway proxy to thehttpbin
service.Example HTTPRoute file
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Binds the
HTTPROUTE
resource to the Kubernetes Gateway resource that was created in the previous step by adding the name of the gateway resource to the list of gateways. - 2
- Routes the matching traffic to the
httpbin
service by defining abackendRefs
that includes the name and port of thehttpbin
Service.
Apply the YAML file by running the following command:
oc apply -f httpbin-hr.yaml
$ oc apply -f httpbin-hr.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Ensure that the Gateway API service is ready, and that an address is allocated to the service, by running the following command:
oc wait --for=condition=programmed gtw httpbin-gateway -n httpbin
$ oc wait --for=condition=programmed gtw httpbin-gateway -n httpbin
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Create a namespace for a
curl
client by running the following command:oc create namespace curl
$ oc create namespace curl
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy a
curl
client by running the following command:oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set a
CURL_POD
variable with the name of thecurl
pod by running the following command:CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using the
curl
client, send a request to the/headers
endpoint of thehttpbin
application through the ingress gatewayService
resource. Set the Host header of the request tohttpbin.example.com
to match the host that the Kubernetes Gateway andHTTPROUTE
resources specify. Send thecurl
request by running the following command:oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/headers
$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/headers
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The response should return a
200 OK
HTTP status, which indicates that the request was successful.Example output
HTTP/1.1 200 OK server: istio-envoy ...
HTTP/1.1 200 OK server: istio-envoy ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Send a
curl
request to an endpoint that does not have a corresponding Uniform Resource Identifier (URI) prefix match defined in thehttpbin
HTTPROUTE
by running the following command:oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/get
$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/get
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The response returns a
404 Not Found
status. This is expected because the/get
endpoint does not have a matching URI prefix in thehttpbin
HTTPROUTE
resource.Example output
HTTP/1.1 404 Not Found server: istio-envoy ...
HTTP/1.1 404 Not Found server: istio-envoy ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Expose the gateway proxy to traffic outside the cluster by setting the
Service
type toLoadBalancer
. Run the following command:oc patch service <gateway_name>-istio -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
$ oc patch service <gateway_name>-istio -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteA gateway can also be exposed to traffic outside the cluster by using OpenShift Routes. For more information, see "Exposing a gateway to traffic outside the cluster using OpenShift Routes".
Verify that the
httpbin
service can be accessed from outside the cluster when using the external hostname or IP address of the gateway Service resource. Ensure that you set theINGRESS_HOST
variable appropriately for the environment in which your cluster is running.Set the
INGRESS_HOST
variable by running the following command:export INGRESS_HOST=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.addresses[0].value}')
$ export INGRESS_HOST=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.addresses[0].value}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set the
INGRESS_PORT
variable by running the following command:INGRESS_PORT=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
$ INGRESS_PORT=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using the gateway host, send a
curl
request to thehttpbin
service by running the following command:curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OK
status, which indicates that the request was successful.