Chapter 3. Directing outbound traffic through a gateway


Using Istio APIs, you can configure gateway proxies that were installed using gateway injection to direct traffic that is bound for an external service.

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.

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

  1. Create a namespace called curl by running the following command:

    $ oc create namespace curl
    Copy to Clipboard Toggle word wrap
  2. Depending on the update strategy you are using, enable sidecar injection in the namespace by running the appropriate commands:

    1. If you are using the InPlace update strategy, run the following command:

      $ oc label namespace curl istio-injection=enabled
      Copy to Clipboard Toggle word wrap
    2. If you are using the RevisionBased update strategy, run the following commands:

      1. Display the revision name by running the following command:

        $ oc get istiorevisions.sailoperator.io
        Copy to Clipboard Toggle word wrap

        Example output

        NAME     TYPE    READY   STATUS    IN USE   VERSION   AGE
        default  Local   True    Healthy   True     v1.24.3   3m33s
        Copy to Clipboard Toggle word wrap

      2. Label the namespace with the revision name to enable sidecar injection by running the following command:

        $ oc label namespace curl istio.io/rev=default
        Copy to Clipboard Toggle word wrap
  3. Deploy a curl application 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
    Copy to Clipboard Toggle word wrap
  4. Export a CURL_POD environment 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}')
    Copy to Clipboard Toggle word wrap
  5. Create a YAML file named http-se.yaml that directs traffic from the mesh to an external service. The following example defines a ServiceEntry for 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: DNS
    Copy to Clipboard Toggle word wrap

  6. Apply the YAML file by running the following command:

    $ oc apply -f http-se.yaml
    Copy to Clipboard Toggle word wrap
  7. Ensure the ServiceEntry configuration 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
    Copy to Clipboard Toggle word wrap

    This command should return HTTP status codes, such as 301 (redirect) or 200 (success), indicating that the connection works.

  8. Create a YAML file named http-gtw.yaml that creates an egress Gateway and routes traffic from the mesh to the host specified for the external service.

    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-docs
    Copy to Clipboard Toggle word wrap

  9. Apply the YAML file by running the following command:

    $ oc apply -f http-gtw.yaml
    Copy to Clipboard Toggle word wrap
  10. Create a YAML file named http-vs.yaml that sets up a VirtualService to manage the flow of traffic from the application sidecars through the egress gateway to the external host.

    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: 100
    Copy to Clipboard Toggle word wrap

  11. Apply the YAML file by running the following command:

    $ oc apply -f http-vs.yaml
    Copy to Clipboard Toggle word wrap
  12. 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
    Copy to Clipboard Toggle word wrap

    The 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-8
    Copy to Clipboard Toggle word wrap

  13. Ensure that the request was routed through the gateway by running the following command:

    $ oc logs deployment/<gateway_name> -n <gateway_namespace> | tail -1
    Copy to Clipboard Toggle word wrap
    Note

    Access 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.accessLogFile field to /dev/stdout in 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 -
    Copy to Clipboard Toggle word wrap

Use the Kubernetes Gateway API to direct outbound HTTP traffic through an egress gateway.

Prerequisites

  • You installed an Istio control plane.
  • You configured the Istio and IstioCNI resources.

Procedure

  1. Optional: Enable the {k8} Gateway API custom resource definitions (CRDs).

    Note

    As 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.

    1. Create a YAML file named gateway-cr.yaml that enables the Kubernetes Gateway API CRDs.

      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: 9080
      Copy to Clipboard Toggle word wrap

    2. Apply the YAML file by running the following command:

      $ oc apply -f gateway-cr.yaml
      Copy to Clipboard Toggle word wrap
  2. Create a namespace called egress-gateway by running the following command:

    $ oc create namespace egress-gateway
    Copy to Clipboard Toggle word wrap
  3. Apply the istio-injection label to the namespace by running the following command:

    $ oc label namespace egress-gateway istio-injection=enabled
    Copy to Clipboard Toggle word wrap
  4. Create a YAML file named egress-gateway-cr.yaml that defines the egress gateway.

    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: 80
    Copy to Clipboard Toggle word wrap

    1. Apply the YAML file by running the following command:

      $ oc apply -f egress-gateway-cr.yaml
      Copy to Clipboard Toggle word wrap

Verification

  1. Verify the status of the gateway configuration by running the following command:

    $ oc describe gateway -n egress-gateway
    Copy to Clipboard Toggle word wrap

    Desired output is indicated by Programmed showing in the Status column.

  2. Create a curl pod in the egress-gateway namespace by running the following command:

    $ oc run test-pod --image=curlimages/curl:latest -n egress-gateway --rm -it --restart=Never -- sh
    Copy to Clipboard Toggle word wrap
  3. By using the curl client, verify that you can access httpbin.org through the egress gateway by entering following command:

    $ curl -v http://httpbin.org/get
    Copy to Clipboard Toggle word wrap

    Desired output shows a response from httpbin.org that indicates egress traffic routes through the configured gateway.

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat