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 application. 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'
  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
  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
    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
    3. Install an Istio ingress gateway:

      helm upgrade -i --wait --create-namespace -n istio-system istio-ingress istio/gateway --version 1.21.2
  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
    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
    3. List all services and API instances previously created:

      kubectl -n flex get svc
  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
    2. Check the pod status:

      kubectl -n bookinfo get pods
  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
    2. Check the status of the pods:

      kubectl -n test get pods

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
    • 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:9080

  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:

      cat <<EOF | kubectl apply -f -
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: flex
        namespace: flex
      spec:
        selector:
          app: istio-ingress
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: flex
        namespace: flex
      spec:
        hosts:
        - "*"
        gateways:
        - flex
        http:
        - route:
          - destination:
              host: flex
              port:
                number: 8081
          rewrite:
            uri: /ingress/
      EOF
    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
    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"}
  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
    2. Wait a few seconds (approximately 10) and send a test request:

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

  4. Add the Message Logging policy to log traffic:

    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
      - 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
        order: 0
    EOF

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
    • 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:9080

  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
    2. Send a test request with the user1 username and password1 password to the /productpage:

      curl -v -u user1:password1 http://localhost/productpage
    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
      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:

      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
          order: 0
        - policyRef:
            name: rate-limiting-flex
          config:
            rateLimits:
            - timePeriodInMilliseconds: 60000
              maximumRequests: 2
            exposeHeaders: true
      EOF
  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
    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
    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
    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
    5. Make sure you receive this response:

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