Chapter 3. Directing outbound traffic through a gateway
Using Istio APIs, you configure gateway proxies, installed through gateway injection, to direct traffic 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 through gateway injection as an exit point for traffic leaving the service mesh. It acts as a forward proxy for requests sent to services external to the mesh.
- Egress gateway
An egress gateway acts as a forward proxy and serves as the exit point for traffic exiting the service mesh toward external services. You can configure an egress gateway to fulfill security requirements:
- Traffic Restrictions: In environments with strict traffic restrictions, an egress gateway ensures all outbound traffic flows through a dedicated set of nodes.
- Network Policy Enforcement: When network policies prevent application nodes from directly accessing external services, the egress gateway handles the external access.
In these scenarios, you deploy gateway proxies on dedicated egress nodes that can access external services. You can then enforce strict network policies or add monitoring to these nodes to enhance security.
- Configure egress traffic
You can configure a gateway installed through gateway injection to direct the egress traffic by combining the following Istio resources:
-
The
ServiceEntryadds the external service to the Istio service registry. You can then apply Istio features, such as monitoring and routing rules, to traffic heading toward that external service. -
Use the
Gateway,VirtualService, andDestinationRuleresources to set up rules that route traffic from the mesh to the external service using the gateway proxy.
-
The
- Egress routing in ambient mode
If your deployment uses ambient mode, you must configure egress routing using the Kubernetes Gateway API instead of Istio
GatewayandVirtualServiceresources. The Kubernetes Gateway API provides a standardized, Kubernetes-native method for defining how traffic exits the mesh and reaches external services.You can use
GatewayandHTTPRoute(orGRPCRoute) resources to route mesh traffic to destinations outside the cluster. Service Mesh fully supports the Gateway API in ambient mode, and you can also use it with sidecar-based deployments, providing a consistent configuration model for both ingress and egress routing.
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 you 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 curlDepending 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=enabledIf you are using the
RevisionBasedupdate strategy, run the following commands:Display the revision name by running the following command:
$ oc get istiorevisions.sailoperator.ioYou should see output similar to the following example:
NAME TYPE READY STATUS IN USE VERSION AGE default Local True Healthy True v1.24.3 3m33sLabel the namespace with the revision name to enable sidecar injection by running the following command:
$ oc label namespace curl istio.io/rev=default
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.yamlExport a
CURL_PODenvironment variable and initialize it with the name of the curl pod by running the following command:$ export CURL_POD=$(oc get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')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
apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: egress-se namespace: curl spec: hosts: - docs.redhat.com ports: - number: 80 name: http-port protocol: HTTP location: MESH_EXTERNAL resolution: DNSApply the YAML file by running the following command:
$ oc apply -f http-se.yamlEnsure that you applied the
ServiceEntryconfiguration 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.comThis 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, similar to the following example:Example configuration
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: egress-gw namespace: <gateway_namespace> # Namespace where the egress gateway is deployed spec: selector: istio: <gateway_name> # Selects the egress-gateway instance to handle this traffic servers: - port: number: 80 name: http protocol: HTTP hosts: - docs.redhat.com # External service host, not a full URL. --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egress-dr namespace: <gateway_namespace> # Namespace where the egress gateway is deployed spec: host: <gateway_name>.<gateway_namespace>.svc.cluster.local subsets: - name: rh-docsApply the YAML file by running the following command:
$ oc apply -f http-gtw.yamlCreate 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, similar to the following example:Example configuration
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: egress-vs namespace: curl # Namespace where the curl pod is running spec: hosts: - docs.redhat.com # External service host, not a full URL. gateways: - mesh - <gateway_namespace>/egress-gw # Egress gateway name defined in the file that you used in the previous step. http: - match: - gateways: - mesh port: 80 route: - destination: host: <gateway_name>.<gateway_namespace>.svc.cluster.local subset: rh-docs port: number: 80 weight: 100 - match: - gateways: - <gateway_namespace>/egress-gw # Egress gateway name defined in the file that you used in the previous step. port: 80 route: - destination: host: docs.redhat.com port: number: 80 weight: 100Apply the YAML file by running the following command:
$ oc apply -f http-vs.yamlResend the HTTP request to the URL:
$ oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.comThe terminal should display information similar to the following output:
Example output
... HTTP/1.1 301 Moved Permanently ... location: <example_url> ... HTTP/2 200 Content-Type: text/html; charset=utf-8Ensure that the gateway routed the request by running the following command:
$ oc logs deployment/<gateway_name> -n <gateway_namespace> | tail -1NoteYou must enable access logging 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 -
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, similar to the following example:Example Kubernetes Gateway Custom Resource (CR) file
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: bookinfo-gateway spec: gatewayClassName: istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: bookinfo spec: parentRefs: - name: bookinfo-gateway rules: - matches: - path: type: Exact value: /productpage - path: type: PathPrefix value: /static - path: type: Exact value: /login - path: type: Exact value: /logout - path: type: PathPrefix value: /api/v1/products backendRefs: - name: productpage port: 9080Apply the YAML file by running the following command:
$ oc apply -f gateway-cr.yaml
Create a namespace called
egress-gatewayby running the following command:$ oc create namespace egress-gatewayApply the
istio-injectionlabel to the namespace by running the following command:$ oc label namespace egress-gateway istio-injection=enabledCreate a YAML file named
egress-gateway-cr.yamlthat defines the egress gateway, similar to the following example:Example egress gateway CR file
# ServiceEntry to allow traffic to httpbin.org apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP location: MESH_EXTERNAL resolution: DNS --- # Gateway API Gateway for egress apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-egress-gateway annotations: networking.istio.io/service-type: ClusterIP spec: gatewayClassName: istio listeners: - name: http hostname: httpbin.org port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- # HTTPRoute to direct traffic from sidecars to the egress gateway apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: direct-httpbin-to-egress-gateway spec: parentRefs: - kind: ServiceEntry group: networking.istio.io name: httpbin-ext rules: - backendRefs: - name: httpbin-egress-gateway-istio port: 80 --- # HTTPRoute to forward traffic from the egress gateway to httpbin.org apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: forward-httpbin-from-egress-gateway spec: parentRefs: - name: httpbin-egress-gateway hostnames: - httpbin.org rules: - backendRefs: - kind: Hostname group: networking.istio.io name: httpbin.org port: 80Apply the YAML file by running the following command:
$ oc apply -f egress-gateway-cr.yaml
Verification
Verify the status of the gateway configuration by running the following command:
$ oc describe gateway -n egress-gatewayThe
Statuscolumn displaysProgrammedto indicate the required output.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 -- shBy using the
curlclient, verify that you can accesshttpbin.orgthrough the egress gateway by entering following command:$ curl -v http://httpbin.org/getThe required output shows a response from
httpbin.orgthat indicates egress traffic routes through the configured gateway.