Gateways
Gateways and OpenShift Service Mesh
Abstract
Chapter 1. About gateways Copy linkLink copied to clipboard!
A gateway is a standalone Envoy proxy deployment and an associated Kubernetes service operating at the edge of a service mesh. You can configure a gateway to provide fine-grained control over the traffic that enters or leaves the mesh. In Red Hat OpenShift Service Mesh, you install gateways using gateway injection.
1.1. About gateway injection Copy linkLink copied to clipboard!
Gateway injection relies upon the same mechanism as sidecar injection to inject the Envoy proxy into gateway pods. To install a gateway using gateway injection, you create a Kubernetes Deployment object and an associated Kubernetes Service object in a namespace that is visible to the Istio control plane. When creating the Deployment object you label and annotate it so that the Istio control plane injects a proxy, and the proxy is configured as a gateway. After installing the gateway, you configure it to control ingress and egress traffic using the Istio Gateway and VirtualService resources.
1.1.1. Installing a gateway by using gateway injection Copy linkLink copied to clipboard!
This procedure explains how to install a gateway by using gateway injection.
You can use this procedure to create ingress or egress gateways.
Prerequisites
- You have installed the OpenShift Service Mesh Operator version 3.0 or later.
- You have created an Istio control plane.
-
You have created an
IstioCNIresource.
Procedure
Create a namespace that you will use to install the gateway.
oc create namespace <gateway_namespace>
$ oc create namespace <gateway_namespace>Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteInstall the gateway and the Istio control plane in different namespaces.
You can install the gateway in a dedicated gateway namespace. This approach allows the gateway to be shared by many applications operating in different namespaces. Alternatively, you can install the gateway in an application namespace. In this approach, the gateway acts as a dedicated gateway for the application in that namespace.
Create a YAML file named
secret-reader.ymlthat defines the service account, role, and role binding for the gateway deployment. These settings enable the gateway to read the secrets, which is required for obtaining TLS credentials.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f secret-reader.yml
$ oc apply -f secret-reader.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
gateway-deployment.ymlthat defines the KubernetesDeploymentobject for the gateway.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Indicates that the Istio control plane uses the gateway injection template instead of the default sidecar template.
- 2
- Ensure that a unique label is set for the gateway deployment. A unique label is required so that Istio
Gatewayresources can select gateway workloads. - 3
- Enables gateway injection by setting the
sidecar.istio.io/injectlabel totrue. If the name of the Istio resource is notdefaultyou must use theistio.io/rev: <istio_revision>label instead, where the revision represents the active revision of the Istio resource. - 4
- Sets the image field to
autoso that the image automatically updates each time the pod starts. - 5
- Sets the
serviceAccountNameto the name of theServiceAccountcreated previously.
Apply the YAML file by running the following command:
oc apply -f gateway-deployment.yml
$ oc apply -f gateway-deployment.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the gateway
Deploymentrollout was successful by running the following command:oc rollout status deployment/<gateway_name> -n <gateway_namespace>
$ oc rollout status deployment/<gateway_name> -n <gateway_namespace>Copy to Clipboard Copied! Toggle word wrap Toggle overflow You should see output similar to the following:
Example output
Waiting for deployment "<gateway_name>" rollout to finish: 0 of 1 updated replicas are available... deployment "<gateway_name>" successfully rolled out
Waiting for deployment "<gateway_name>" rollout to finish: 0 of 1 updated replicas are available... deployment "<gateway_name>" successfully rolled outCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
gateway-service.ymlthat contains the KubernetesServiceobject for the gateway.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- When you set
spec.typetoClusterIPthe gatewayServiceobject can be accessed only from within the cluster. If the gateway has to handle ingress traffic from outside the cluster, setspec.typetoLoadBalancer. Alternatively, you can use OpenShift Routes. - 2
- Set the
selectorto the unique label or set of labels specified in the pod template of the gateway deployment that you previously created.
Apply the YAML file by running the following command:
oc apply -f gateway-service.yml
$ oc apply -f gateway-service.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the gateway service is targeting the endpoint of the gateway pods by running the following command:
oc get endpoints <gateway_name> -n <gateway_namespace>
$ oc get endpoints <gateway_name> -n <gateway_namespace>Copy to Clipboard Copied! Toggle word wrap Toggle overflow You should see output similar to the following example:
Example output
NAME ENDPOINTS AGE <gateway_name> 10.131.0.181:8080,10.131.0.181:8443 1m
NAME ENDPOINTS AGE <gateway_name> 10.131.0.181:8080,10.131.0.181:8443 1mCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Create a YAML file named
gateway-hpa.ymlthat defines a horizontal pod autoscaler for the gateway. The following example sets the minimum replicas to2and the maximum replicas to5and scales the replicas up when average CPU utilization exceeds 80% of the CPU resource limit. This limit is specified in the pod template of the deployment for the gateway.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Set
spec.scaleTargetRef.nameto the name of the gateway deployment previously created.
Optional: Apply the YAML file by running the following command:
oc apply -f gateway-hpa.yml
$ oc apply -f gateway-hpa.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Create a YAML file named
gateway-pdb.ymlthat defines a pod disruption budget for the gateway. The following example allows gateway pods to be evicted only when at least 1 healthy gateway pod will remain on the cluster after the eviction.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Set the
spec.selector.matchLabelsto the unique label or set of labels specified in the pod template of the gateway deployment previously created.
Optional: Apply the YAML file by running the following command:
oc apply -f gateway-pdb.yml
$ oc apply -f gateway-pdb.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 2. Getting traffic into a mesh Copy linkLink copied to clipboard!
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
httpbinby running the following command:oc create namespace httpbin
$ oc create namespace httpbinCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable sidecar injection in the namespace. If you are using the
InPlaceupgrade strategy, run the following command:oc label namespace httpbin istio-injection=enabled
$ oc label namespace httpbin istio-injection=enabledCopy to Clipboard Copied! Toggle word wrap Toggle overflow NoteIf you are using the
RevisionBasedupgrade strategy, run the following commands:To find your
<revision-name>, run the following command:oc get istiorevisions.sailoperator.io
$ oc get istiorevisions.sailoperator.ioCopy 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 3m33sCopy 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=defaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Deploy a sample service named
httpbinby 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-gw.yamlthat defines an IstioGatewayresource. 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
selectorto the unique label or set of labels specified in the pod template of the gateway proxyDeployment. By default, the IstioGatewayresource configuration will apply to matching gateway pods in all namespaces. - 2
- Using the
hostsfield, 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-vs.yamlfor aVirtualService. TheVirtualServicedefines the rules that route traffic from the gateway proxy to thehttpbinservice.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specify the
hoststhat the routing rules of theVirtualServicewill be applied to. Thehostsspecified must be exposed by the IstioGatewayresource the VirtualService is bound to. - 2
- Bind the
VirtualServiceto the IstioGatewayresource created in the previous step by adding theGatewayname to the list of gateways. - 3
- Route matching traffic to the
httpbinservice deployed earlier by defining adestinationthat includes thehostandportof thehttpbinService.
Apply the YAML file by running the following command:
oc apply -f httpbin-vs.yaml
$ oc apply -f httpbin-vs.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow For verification purposes, create a namespace for a
curlclient by running the following command:oc create namespace curl
$ oc create namespace curlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy the
curlclient 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set a
CURL_PODvariable with the name of thecurlpod 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
curlclient, send a request to the/headersendpoint of thehttpbinapplication through the ingress gatewayServiceresource. Set theHostheader of the request tohttpbin.example.comto match the host that the IstioGatewayandVirtualServiceresources specify. Run the followingcurlcommand 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/headersCopy to Clipboard Copied! Toggle word wrap Toggle overflow The response should have a
200 OK HTTPstatus 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
httpbinVirtualServiceby 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/getCopy to Clipboard Copied! Toggle word wrap Toggle overflow The response should return a
404 Not Foundstatus. This is expected because the/getendpoint does not have a matching URI prefix in thehttpbinVirtualServiceresource.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
Servicetype 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
httpbinservice can be accessed from outside the cluster when using the external hostname or IP address of the gatewayServiceresource. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOSTvariable 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_HOSTvariable 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
curlrequest to thehttpbinservice 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/headersCopy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OKstatus, 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
Servicetype is set toClusterIPby 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.yamlthat defines aRoutefor thehttpbinservice.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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that
httpbinservice can be accessed from outside the cluster through the ingress router. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOSTvariable 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_HOSTvariable 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
curlrequest to thehttpbinservice 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/headersCopy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OKstatus, 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-adminrole. - You installed the Red Hat OpenShift Service Mesh Operator.
- You deployed the Istio resource.
Procedure
Create a namespace called
httpbinby running the following command:oc create namespace httpbin
$ oc create namespace httpbinCopy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy a sample service named
httpbinby 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-gw.yamlthat 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
httpbin-hr.yamlthat defines anHTTPRouteresource. TheHTTPRouteresource specifies the rules that route traffic from the gateway proxy to thehttpbinservice.Example HTTPRoute file
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Binds the
HTTPROUTEresource 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
httpbinservice by defining abackendRefsthat includes the name and port of thehttpbinService.
Apply the YAML file by running the following command:
oc apply -f httpbin-hr.yaml
$ oc apply -f httpbin-hr.yamlCopy 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 httpbinCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Create a namespace for a
curlclient by running the following command:oc create namespace curl
$ oc create namespace curlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Deploy a
curlclient 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set a
CURL_PODvariable with the name of thecurlpod 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
curlclient, send a request to the/headersendpoint of thehttpbinapplication through the ingress gatewayServiceresource. Set the Host header of the request tohttpbin.example.comto match the host that the Kubernetes Gateway andHTTPROUTEresources specify. Send thecurlrequest 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/headersCopy to Clipboard Copied! Toggle word wrap Toggle overflow The response should return a
200 OKHTTP 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
curlrequest to an endpoint that does not have a corresponding Uniform Resource Identifier (URI) prefix match defined in thehttpbinHTTPROUTEby 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/getCopy to Clipboard Copied! Toggle word wrap Toggle overflow The response returns a
404 Not Foundstatus. This is expected because the/getendpoint does not have a matching URI prefix in thehttpbinHTTPROUTEresource.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
Servicetype 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
httpbinservice 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_HOSTvariable appropriately for the environment in which your cluster is running.Set the
INGRESS_HOSTvariable 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_PORTvariable 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
curlrequest to thehttpbinservice 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/headersCopy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Verify that the response has the
HTTP/1.1 200 OKstatus, which indicates that the request was successful.
Chapter 3. Directing outbound traffic through a gateway Copy linkLink copied to clipboard!
Using Istio APIs, you can configure gateway proxies that were installed using gateway injection to direct traffic that is bound for an external service.
3.1. About directing egress traffic through a gateway Copy linkLink copied to clipboard!
You can configure a gateway installed using gateway injection as an exit point for the traffic leaving a service mesh. In this configuration, the gateway acts as a forward proxy for requests sent to the services that are external to the mesh.
Configuring a gateway for egress traffic can help fulfill security requirements. For example, an egress gateway can be used in environments where traffic restrictions require that all traffic exiting a mesh flows through a dedicated set of nodes. Similarly, a gateway can be used when network policies prevent application nodes from directly accessing external services. In such scenarios, gateway proxies are deployed on dedicated egress nodes capable of accessing external services. These nodes can then be subjected to strict network policy enforcement or additional monitoring to enhance security.
To configure a gateway installed using gateway injection to direct the egress traffic, use a combination of the Istio ServiceEntry, Gateway, VirtualService, and DestinationRule resources. Use the ServiceEntry resource to define the properties of an external service. The external service is added to the Istio service registry for the mesh. This enables you to apply Istio features, such as monitoring and routing rules, to the traffic exiting the mesh that is destined for an external service. Use the Gateway, VirtualService, and DestinationRule resources to set up rules that route traffic from the mesh to the external service using the gateway proxy.
3.2. Directing egress traffic through a gateway using Istio APIs Copy linkLink copied to clipboard!
Use Istio APIs to direct outbound HTTP traffic through a gateway that was installed using gateway injection.
Prerequisites
- You have installed a gateway using gateway injection.
Procedure
Create a namespace called
curlby running the following command:oc create namespace curl
$ oc create namespace curlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Depending on the update strategy you are using, enable sidecar injection in the namespace by running the appropriate commands:
If you are using the
InPlaceupdate strategy, run the following command:oc label namespace curl istio-injection=enabled
$ oc label namespace curl istio-injection=enabledCopy to Clipboard Copied! Toggle word wrap Toggle overflow If you are using the
RevisionBasedupdate strategy, run the following commands:Display the revision name by running the following command:
oc get istiorevisions.sailoperator.io
$ oc get istiorevisions.sailoperator.ioCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example 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 3m33sCopy to Clipboard Copied! Toggle word wrap Toggle overflow Label the namespace with the revision name to enable sidecar injection by running the following command:
oc label namespace curl istio.io/rev=default
$ oc label namespace curl istio.io/rev=defaultCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Deploy a
curlapplication 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.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Export a
CURL_PODenvironment variable that has been initialized with the name of the curl pod:export CURL_POD=$(oc get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')$ export CURL_POD=$(oc get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
http-se.yamlthat directs traffic from the mesh to an external service. The following example defines aServiceEntryfor a URL.Example configuration
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f http-se.yaml
$ oc apply -f http-se.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Ensure the
ServiceEntryconfiguration was applied correctly. Send an HTTP request to the host that you specified in the previous step by running the following command:oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.com
$ oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.comCopy to Clipboard Copied! Toggle word wrap Toggle overflow This command should return HTTP status codes, such as
301(redirect) or200(success), indicating that the connection works.Create a YAML file named
http-gtw.yamlthat creates an egressGatewayand routes traffic from the mesh to the host specified for the external service.Example configuration
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f http-gtw.yaml
$ oc apply -f http-gtw.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
http-vs.yamlthat sets up aVirtualServiceto manage the flow of traffic from the application sidecars through the egress gateway to the external host.Example configuration
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f http-vs.yaml
$ oc apply -f http-vs.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Resend the HTTP request to the URL:
oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.com
$ oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.comCopy to Clipboard Copied! Toggle word wrap Toggle overflow The terminal should display information similar to the following output:
Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Ensure that the request was routed through the gateway by running the following command:
oc logs deployment/<gateway_name> -n <gateway_namespace> | tail -1
$ oc logs deployment/<gateway_name> -n <gateway_namespace> | tail -1Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteAccess logging must be enabled for this verification step to work. You can enable access logging to the standard output by setting the
spec.values.meshConfig.accessLogFilefield to/dev/stdoutin the Istio resource.The terminal should display information similar to the following output:
Example output
[2024-11-07T14:35:52.428Z] "GET / HTTP/2" 301 - via_upstream - "-" 0 0 24 24 "10.128.2.30" "curl/8.11.0" "79551af2-341b-456d-b414-9220b487a03b" "docs.redhat.com" "23.55.176.201:80" outbound|80||docs.redhat.com 10.128.2.29:49766 10.128.2.29:80 10.128.2.30:38296 -
[2024-11-07T14:35:52.428Z] "GET / HTTP/2" 301 - via_upstream - "-" 0 0 24 24 "10.128.2.30" "curl/8.11.0" "79551af2-341b-456d-b414-9220b487a03b" "docs.redhat.com" "23.55.176.201:80" outbound|80||docs.redhat.com 10.128.2.29:49766 10.128.2.29:80 10.128.2.30:38296 -Copy to Clipboard Copied! Toggle word wrap Toggle overflow
3.3. Directing egress traffic through a gateway by using the Kubernetes Gateway API Copy linkLink copied to clipboard!
Use the Kubernetes Gateway API to direct outbound HTTP traffic through an egress gateway.
Prerequisites
- You installed an Istio control plane.
-
You configured the
IstioandIstioCNIresources.
Procedure
Optional: Enable the {k8} Gateway API custom resource definitions (CRDs).
NoteAs of Kubernetes 1.28 and OpenShift Container Platform 4.18 or earlier version of Red Hat OpenShift Service Mesh, the Kubernetes Gateway API CRDs are not available by default and you must enabled the CRDs before you can use them. OpenShift Container Platform 4.19 and later versions enable the CRDs by default.
Create a YAML file named
gateway-cr.yamlthat enables the Kubernetes Gateway API CRDs.Example Kubernetes Gateway Custom Resource (CR) file
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f gateway-cr.yaml
$ oc apply -f gateway-cr.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Create a namespace called
egress-gatewayby running the following command:oc create namespace egress-gateway
$ oc create namespace egress-gatewayCopy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the
istio-injectionlabel to the namespace by running the following command:oc label namespace egress-gateway istio-injection=enabled
$ oc label namespace egress-gateway istio-injection=enabledCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a YAML file named
egress-gateway-cr.yamlthat defines the egress gateway.Example egress gateway CR file
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the YAML file by running the following command:
oc apply -f egress-gateway-cr.yaml
$ oc apply -f egress-gateway-cr.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify the status of the gateway configuration by running the following command:
oc describe gateway -n egress-gateway
$ oc describe gateway -n egress-gatewayCopy to Clipboard Copied! Toggle word wrap Toggle overflow Desired output is indicated by
Programmedshowing in theStatuscolumn.Create a
curlpod in theegress-gatewaynamespace by running the following command:oc run test-pod --image=curlimages/curl:latest -n egress-gateway --rm -it --restart=Never -- sh
$ oc run test-pod --image=curlimages/curl:latest -n egress-gateway --rm -it --restart=Never -- shCopy to Clipboard Copied! Toggle word wrap Toggle overflow By using the
curlclient, verify that you can accesshttpbin.orgthrough the egress gateway by entering following command:curl -v http://httpbin.org/get
$ curl -v http://httpbin.org/getCopy to Clipboard Copied! Toggle word wrap Toggle overflow Desired output shows a response from
httpbin.orgthat indicates egress traffic routes through the configured gateway.