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 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 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 shown in the 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 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 Additional resources About gateway injection 2.1.1. Exposing a service by using the Istio Gateway and VirtualService resources 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: USD oc create namespace httpbin Enable sidecar injection in the namespace. If you are using the InPlace upgrade strategy, run the following command: USD oc label namespace httpbin istio-injection=enabled Note If you are using the RevisionBased upgrade strategy, run the following commands: To find your <revision-name> , run the following command: USD oc get istiorevisions.sailoperator.io Sample output: NAME TYPE READY STATUS IN USE VERSION AGE default-v1-23-0 Local True Healthy True v1.23.0 3m33s Label the namespace with the revision name to enable sidecar injection: USD oc label namespace httpbin istio.io/rev=default-v1-23-0 Deploy a sample service named httpbin by running the following command: USD oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/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 . apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: httpbin spec: selector: istio: <gateway_name> 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: USD 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. 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 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: USD oc apply -f httpbin-vs.yaml For verification purposes, create a namespace for a curl client by running the following command: USD oc create namespace curl Deploy the curl client by running the following command: USD oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml Set a CURL_POD variable with the name of the curl pod by running the following command: USD CURL_POD=USD(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}') Using the curl client, send a request to the /headers endpoint of the httpbin application through the ingress gateway Service resource. Set the Host header of the request to httpbin.example.com to match the host that the Istio Gateway and VirtualService resources specify. Run the following curl command to send the request: USD oc exec USDCURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/headers 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 ... 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: USD oc exec USDCURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.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 resource. Example output 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 : USD oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}' Note A 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 gateway Service resource. Ensure that you set the INGRESS_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: USD INGRESS_HOST=USD(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') If the cluster runs on GCP or Azure, set the INGRESS_HOST variable by running the following command: USD INGRESS_HOST=USD(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}') Send a curl request to the httpbin service using the host of the gateway by running the following command: USD curl -s -I -H Host:httpbin.example.com http://USDINGRESS_HOST/headers Verify that the response has the HTTP/1.1 200 OK status, which indicates that the request was successful. Additional resources Istio Gateway resource API reference VirtualService API reference 2.2. About exposing services to traffic outside a cluster 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 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 to ClusterIP by running the following command: USD oc patch service -n -p '{"spec": {"type": "ClusterIP"}}' Create a YAML file named httpbin-route.yaml that defines a Route for the httpbin service. apiVersion: route.openshift.io/v1 kind: Route metadata: name: httpbin namespace: <gateway_namespace> spec: host: httpbin.example.com port: targetPort: http2 to: kind: Service name: <gateway_name> weight: 100 wildcardPolicy: None Apply the YAML file by running the following command: USD oc apply -f httpbin-route.yaml 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. If the cluster runs on AWS, set the INGRESS_HOST variable by running the following command: USD INGRESS_HOST=USD(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') If the cluster runs on GCP or Azure, set the INGRESS_HOST variable by running the following command: USD INGRESS_HOST=USD(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') Send a curl request to the httpbin service using the host of the ingress router by running the following command: USD curl -s -I -H Host:httpbin.example.com http://USDINGRESS_HOST/headers Verify that the response has the HTTP/1.1 200 OK status, which indicates that the request was successful. Additional resources Creating an HTTP-based Route

Commands:
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
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
oc create namespace httpbin
oc label namespace httpbin istio-injection=enabled
oc get istiorevisions.sailoperator.io
NAME TYPE READY STATUS IN USE VERSION AGE default-v1-23-0 Local True Healthy True v1.23.0 3m33s
oc label namespace httpbin istio.io/rev=default-v1-23-0
oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: httpbin spec: selector: istio: <gateway_name> 1 servers: - port: number: 80 name: http protocol: HTTP hosts: - httpbin.example.com 2
oc apply -f httpbin-gw.yaml
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
oc apply -f httpbin-vs.yaml
oc create namespace curl
oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
CURL_POD=USD(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')
oc exec USDCURL_POD -n curl -- curl -s -I -H Host:httpbin.example.com <gateway_name>.<gateway_namespace>.svc.cluster.local/headers
HTTP/1.1 200 OK server: istio-envoy
oc exec USDCURL_POD -n curl -- curl -s -I -H Host:httpbin.example.com <gateway_name>.<gateway_namespace>.svc.cluster.local/get
HTTP/1.1 404 Not Found server: istio-envoy
oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'
INGRESS_HOST=USD(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
INGRESS_HOST=USD(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -s -I -H Host:httpbin.example.com http://USDINGRESS_HOST/headers
oc patch service -n -p '{"spec": {"type": "ClusterIP"}}'
apiVersion: route.openshift.io/v1 kind: Route metadata: name: httpbin namespace: <gateway_namespace> spec: host: httpbin.example.com port: targetPort: http2 to: kind: Service name: <gateway_name> weight: 100 wildcardPolicy: None
oc apply -f httpbin-route.yaml
INGRESS_HOST=USD(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
INGRESS_HOST=USD(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -s -I -H Host:httpbin.example.com http://USDINGRESS_HOST/headers