Hear from Salesforce leaders on how to create and deploy Agentforce agents.
Contact Us 1-800-596-4880

Integrating Flex Gateway with Istio Service Mesh

To leverage Flex Gateway policies, logging, and metrics from the Anypoint Platform control plane, integrate Flex Gateway into your Istio Service Mesh. Deploy Flex Gateway as an ingress gateway to manage ingress north-south cluster traffic and internal east-west traffic inside the cluster.

To integrate Flex Gateway, use the following architecture diagram and tutorial. Flex Gateway is integrated by using a modified version of the Istio Bookinfo sample applicationLeaving the Site. In the Flex Gateway integration:

  • An Istio virtual service forwards all ingress north-south traffic to Flex Gateway.

  • Direct access to the bookinfo name space is restricted. All external traffic into the bookinfo namespace must come from the flex namespace. Istio automatically configures mTLS configuration between the bookinfo and flex.

  • Flex Gateway protects and monitors the exposed product page service from ingress traffic with an API instance.

  • The Istio sidecar intercepts east-west traffic between the product page service and the reviews service. Flex Gateway acts as an ingress gateway managing incoming traffic to the reviews service.

A diagram demonstrating the architecture to integrate Flex Gateway with Istio

In the diagram, Flex Gateway is running in Connected Mode. If Flex Gateway runs in Local Mode, the Anypoint Platform control plane is absent.

To configure the architecture:

Before You Begin

Before you begin, install the following prerequisites:

Set up Environment

  1. Create a Kubernetes cluster for this demo or skip this step if you already have a cluster you want to use:

    k3d cluster create demo-istio --k3s-arg "--disable=traefik@server:0" --port '80:80@server:0' --port '443:443@server:0'
    ssh
  2. Add the Flex Gateway and Istio Helm repositories:

    helm repo add istio https://istio-release.storage.googleapis.com/charts \
    && helm repo add flex-gateway https://flex-packages.anypoint.mulesoft.com/helm \
    && helm repo up
    ssh
  3. Install Istio:

    1. Install the Istio base chart that contains the cluster-wide Custom Resource Definitions (CRDs) that must be installed before deploying the Istio control plane:

      helm upgrade -i --wait --create-namespace -n istio-system istio-base istio/base --version 1.21.2 --set defaultRevision=default
      ssh
    2. Install the Istio discovery chart that deploys the istiod service:

      helm upgrade -i --wait --create-namespace -n istio-system istiod istio/istiod --version 1.21.2
      ssh
    3. Install an Istio ingress gateway:

      helm upgrade -i --wait --create-namespace -n istio-system istio-ingress istio/gateway --version 1.21.2
      ssh
  4. Install Flex Gateway:

    1. Create the namespace and set up the label to enable the sidecar injection:

      kubectl create ns flex && kubectl label ns flex istio-injection=enabled --overwrite
      ssh
    2. Install Flex Gateway:

      helm upgrade -i --wait -n flex --version 1.7.0 flex flex-gateway/flex-gateway \
      --set gateway.scope=Namespace \
      --set gateway.mode=connected \
      --set service.type=ClusterIP \
      --set service.http.port=8081 \
      --set service.https.enabled=false \
      --set-file registration.content=registration.yaml
      ssh
    3. List all services and API instances previously created:

      kubectl -n flex get svc
      ssh
  5. Install the bookinfo application:

    1. Enable Istio label injection in the default namespace and install the bookinfo application:

      kubectl create ns bookinfo \
      && kubectl label ns bookinfo istio-injection=enabled --overwrite \
      && kubectl -n bookinfo apply -l version!=v2,version!=v3 -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml
      ssh
    2. Check the pod status:

      kubectl -n bookinfo get pods
      ssh
  6. Install the sleep application to test traffic:

    1. Create the test namespace and install the sleep application:

      kubectl create ns test \
      && kubectl label ns test istio-injection=enabled --overwrite \
      && kubectl -n test apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/sleep/sleep.yaml
      ssh
    2. Check the status of the pods:

      kubectl -n test get pods
      ssh

Intercept Ingress North-South Traffic

Intercept ingress north-south traffic to protect services from external traffic.

To intercept ingress north-south traffic:

  1. Create the Flex Gateway ingress API instance to forward all ingress north-south traffic in the bookinfo namespace to the productpage service:

    • Local Mode:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: gateway.mulesoft.com/v1alpha1
      kind: ApiInstance
      metadata:
        name: ingress
        namespace: flex
      spec:
        address: http://0.0.0.0:8081/ingress/
        services:
          productpage:
            address: http://productpage.bookinfo.svc:9080
      EOF
      ssh
    • Connected Mode:

      To add an API instance in Connected Mode, see Adding a Flex Gateway API Instance.

      Configure the API instance with the following downstream parameters:

      • Protocol: HTTP

      • Port: 8081

      • Base Path: /ingress/

        Configure the API instance with the following upstream parameters:

      • Route label: productpage

      • Upstream URL: http://productpage.bookinfo.svc:9080Leaving the Site

  2. Create the flex Istio ingress gateway to forward the ingress traffic to Flex Gateway using a Istio virtual service:

    1. Create the Flex Gateway:

    2. Wait a few seconds (approximately 10) and send a test request to the /api/v1/products/1 page:

      curl -v http://localhost/api/v1/products/1
      ssh
    3. Ensure you receive this output:

      < HTTP/1.1 200 OK
      < server: istio-envoy
      < date: Tue, 27 Feb 2024 22:06:33 GMT
      < content-type: application/json
      < content-length: 195
      < x-envoy-upstream-service-time: 8
      <
      * Connection #0 to host localhost left intact
      {"id": 2, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890"}
      ssh
  3. Protect the Flex Gateway API instance by applying the Basic Authentication policy:

    1. Add the policy:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: gateway.mulesoft.com/v1alpha1
      kind: ApiInstance
      metadata:
        name: ingress
        namespace: flex
      spec:
        address: http://0.0.0.0:8081/ingress/
        services:
          productpage:
            address: http://productpage.bookinfo.svc:9080
        policies:
        - policyRef:
            name: http-basic-authentication-flex
          config:
            username: user1
            password: password1
      EOF
      ssh
    2. Wait a few seconds (approximately 10) and send a test request:

      curl -v http://localhost/
      ssh
    3. Make sure you receive a 401 response.

  4. Add the Message Logging policy to log traffic:

Intercept East-West Traffic Between Services

Use Flex Gateway to intercept east-west traffic between services and protect them with policies.

To intercept east-west traffic:

  1. Create the bookinfo-reviews API instance to forward the east-west traffic to the reviews service:

    • Local Mode:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: gateway.mulesoft.com/v1alpha1
      kind: ApiInstance
      metadata:
        name: bookinfo-reviews
        namespace: flex
      spec:
        address: http://0.0.0.0:8081/bookinfo/reviews/
        services:
          upstream:
            address: http://reviews.bookinfo.svc:9080
        policies:
        - policyRef:
            name: message-logging-flex
          config:
            loggingConfiguration:
            - itemName: "Request"
              itemData:
                message: "#['> ' ++ attributes.version ++ ' ' ++  attributes.method ++ ' ' ++ attributes.headers.host ++ attributes.requestUri]"
                level: "INFO"
                firstSection: true
            - itemName: "Response"
              itemData:
                message: "#['< Status=' ++ attributes.statusCode ++ ' Length=' ++ (attributes.headers['content-length'] default 'none') ++ ' Time=' ++ (attributes.headers['x-envoy-upstream-service-time'] default 'none')]"
                level: "INFO"
                secondSection: true
      EOF
      ssh
    • Connected Mode:

      To add an API instance in Connected Mode, see Adding a Flex Gateway API Instance.

      Configure the API instance with these downstream parameters:

      • Protocol: HTTP

      • Port: 8081

      • Base Path: /bookinfo/reviews/

        Configure the API instance with these upstream parameters:

      • Route label: reviews

      • Upstream URL: http://reviews.bookinfo.svc:9080Leaving the Site

  2. Intercept the traffic between the productpage service and the reviews service and forward it to the flex service:

    1. Create the Istio API instance:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: bookinfo-reviews
        namespace: istio-system
      spec:
        hosts:
        - reviews.bookinfo.svc.cluster.local
        http:
        - match:
          - sourceLabels:
              app: flex
          route:
          - destination:
              host: reviews.bookinfo.svc.cluster.local
              port:
                number: 9080
        - route:
          - destination:
              host: flex.flex.svc.cluster.local
              port:
                number: 8081
          rewrite:
            uri: /bookinfo/reviews/
      EOF
      ssh
    2. Send a test request with the user1 username and password1 password to the /productpage:

      curl -v -u user1:password1 http://localhost/productpage
      ssh
    3. Check the Flex Gateway logs to ensure the request sent from the productpage service to the reviews service passed through Flex Gateway. The logs appear similar to:

      [flex-gateway-envoy][info] wasm log productpage-message-logging-flex-2.flex.productpage.flex.svc main: [policy: productpage-message-logging-flex-2.flex][api: productpage.flex.svc][req: 6e1f7c32-918d-4b6a-af3f-36a4430f80ae] [accessLog] > HTTP/1.1 GET localhost/ingress/productpage
      [flex-gateway-envoy][info] wasm log bookinfo-reviews-message-logging-flex-1.flex.bookinfo-reviews.flex.svc main: [policy: bookinfo-reviews-message-logging-flex-1.flex][api: bookinfo-reviews.flex.svc][req: b23e9c64-a2aa-4464-8984-d1dd6c18f7ea] [accessLog] > HTTP/1.1 GET reviews:9080/bookinfo/reviews/reviews/0
      ssh
      Use the standard output logs for a quick log check. To learn how to view standard output logs, see Viewing Standard Output Logs.
    4. Apply the Rate Limiting policy to the bookinfo-reviews API instance to protect the reviews service:

  3. Restrict direct access to the bookinfo service:

    1. Restrict access:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: security.istio.io/v1
      kind: AuthorizationPolicy
      metadata:
        name: flex-allow
        namespace: bookinfo
      spec:
        action: ALLOW
        rules:
        - from:
          - source:
              namespaces:
              - flex
              - bookinfo
      EOF
      ssh
    2. Send a test request from the test namespace to the details service:

      kubectl -n test exec -ti -c sleep $(kubectl -n test get pod --no-headers -o=name) -- curl -v details.bookinfo:9080/details/0
      ssh
    3. Make sure you receive this 403 forbidden response:

      < HTTP/1.1 403 Forbidden
      < content-length: 19
      < content-type: text/plain
      < date: Thu, 09 May 2024 15:51:11 GMT
      < server: envoy
      < x-envoy-upstream-service-time: 0
      <
      * Connection #0 to host details.bookinfo left intact
      RBAC: access denied
      ssh
    4. Send this request to the details service to find out how to access the bookinfo service from the flex namespace:

      kubectl -n flex exec -ti -c app  $(kubectl -n flex get pod --no-headers -o=name) -- flexctl check http http://details.bookinfo:9080/details/0
      ssh
    5. Make sure you receive this response:

      [flexctl][info] Access to http address 'http://details.bookinfo:9080/details/0': ok
      ssh