About service mesh

A service mesh is a dedicated infrastructure layer that you add your apps to, which ensures secure service-to-service communication across cloud networks. With a service mesh, you can solve problems such as service identity, mutual TLS communication, consistent L7 network telemetry gathering, service resilience, secure traffic routing between services across clusters, and policy enforcement, such as to enforce quotas or rate limit requests. To learn more about the benefits of using a service mesh, see What is a service mesh in the Gloo Mesh Enterprise documentation.

About Istio

The open source project Istio is the leading service mesh implementation that offers powerful features to secure, control, connect, and monitor cloud-native, distributed applications. Istio is designed for workloads that run in one or more Kubernetes clusters, but you can also extend your service mesh to include virtual machines and other endpoints that are hosted outside your cluster. The key benefits of Istio include:

  • Automatic load balancing for HTTP, gRPC, WebSocket, MongoDB, and TCP traffic
  • Secure TLS encryption for service-to-service communication with identity-based authentication and authorization
  • Advanced routing and traffic management policies, such as retries, failovers, and fault injection
  • Fine-grained access control and quotas
  • Automatic logs, metrics, and traces for traffic in the service mesh

About the Gloo Gateway Istio integration

Gloo Gateway comes with an Istio integration that allows you to configure your gateway proxy with an Istio sidecar. The Istio sidecar uses mutual TLS (mTLS) to prove its identity and to secure the connection between your gateway and the services in your Istio service mesh. In addition, you can control and secure the traffic that enters the mesh by applying all the advanced routing, traffic management, security, resiliency, and AI capabilities that Gloo Gateway offers. For example, you can set up end-user authentication and authorization, per-user rate limiting quotas, web application filters, and access logging to help prevent malicious attacks and audit service mesh usage.

About this guide

In this guide, you learn how to use Gloo Gateway as an ingress gateway proxy for the workloads in your Istio service mesh. You explore how to enable the Istio sidecar mesh integration in Gloo Gateway, set up your ingress gateway proxy with a sidecar, and send secure mutual TLS traffic to the httpbin app as illustrated in the following image.

Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. Get the external address of the gateway and save it in an environment variable.

Step 1: Set up an Istio service mesh

Use Solo.io's Gloo Mesh Enterprise product to install a managed Istio version by using the built-in Istio lifecycle manager, or manually install and manage your own Istio installation.

Step 2: Enable the Istio integration in Gloo Gateway

Upgrade your Gloo Gateway installation to enable the Istio integration.

  1. Get the name of the istiod service. Depending on how you set up Istio, you might see a revisionless service name (istiod) or a service name with a revision, such as istiod-1-22.

      kubectl get services -n istio-system
      

    Example output:

      NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                 AGE
    istiod-1-22   ClusterIP   10.102.24.31   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   3h49m
      
  2. Derive the Kubernetes service address for your istiod deployment. The service address uses the format <service-name>.<namespace>.svc:15012. For example, if your service name is istiod-1-22, the full service address is istiod-1-22.istio-system.svc:15012.

  3. Get the Helm values for your current Gloo Gateway installation.

      helm get values gloo -n gloo-system -o yaml > gloo-gateway.yaml
    open gloo-gateway.yaml
      
  4. Add the following values to the Helm value file. Make sure that you change the istioProxyContainer values to the service address and cluster name of your Istio installation.

    SettingDescription
    istioDiscoveryAddressThe address of the istiod service. If omitted, istiod.istio-system.svc:15012 is used.
    istioMetaClusterId
    istioMetaMeshId
    The name of the cluster where Gloo Gateway is installed.
  5. Upgrade your Gloo Gateway installation.

  6. Verify that your gloo-proxy-http pod is restarted with 3 containers now: gateway-proxy, istio-proxy, and sds.

      kubectl get pods -n gloo-system | grep gloo-proxy-http
      

    Example output:

      gloo-proxy-http-f7cd596b7-tv5z7    3/3     Running            0              3h31m
      
  7. Optional: Review the GatewayParameters resource and verify that the istioDiscoveryAddress, istioMetaClusterId, and istioMetaMeshId are set to the values from your Helm chart.

      kubectl get gatewayparameters gloo-gateway -n gloo-system -o yaml
      

    Example output:

       apiVersion: gateway.gloo.solo.io/v1alpha1
       kind: GatewayParameters
       metadata:
         annotations:
           meta.helm.sh/release-name: gloo-gateway
           meta.helm.sh/release-namespace: gloo-system
       ...
       spec:
         kube:
           deployment:
             replicas: 1
           ...
           istio:
             istioProxyContainer:
               image:
                 pullPolicy: IfNotPresent
                 registry: docker.io/istio
                 repository: proxyv2
                 tag: 1.22.0
               istioDiscoveryAddress: istiod-1-22.istio-system.svc:15012
               istioMetaClusterId: mycluster
               istioMetaMeshId: mycluster
               logLevel: warning
            podTemplate:
             extraLabels:
               gloo: kube-gateway
       ...
       

  8. Optional: Review the Settings resource and verify that appendXForwardedHost, enableAutoMtls, and enableIntegration are all set to true.

      kubectl get settings default -n gloo-system -o yaml
      

    Example output:

       apiVersion: gloo.solo.io/v1
       kind: Settings
       metadata:
         annotations:
           meta.helm.sh/release-name: gloo-gateway
           meta.helm.sh/release-namespace: gloo-system
       spec:
         consoleOptions:
           apiExplorerEnabled: true
           readOnly: false
         discovery:
           fdsMode: WHITELIST
         discoveryNamespace: gloo-system
         gloo:
           ...
           istioOptions:
             appendXForwardedHost: true
             enableAutoMtls: true
             enableIntegration: true
       ...
       

Step 3: Set up mTLS routing to httpbin

  1. Label the httpbin namespace for Istio sidecar injection.

      export REVISION=$(kubectl get pod -L app=istiod -n istio-system -o jsonpath='{.items[0].metadata.labels.istio\.io/rev}')      
    echo $REVISION
    kubectl label ns httpbin istio.io/rev=$REVISION --overwrite=true
      
  2. Perform a rollout restart for the httpbin deployment so that an Istio sidecar is automatically added to the httpbin app.

      kubectl rollout restart deployment httpbin -n httpbin
      
  3. Verify that the httpbin app comes up with a fourth container.

      kubectl get pods -n httpbin
      

    Example output:

      NAME                      READY   STATUS    RESTARTS   AGE
    httpbin-f46cc8b9b-f4wbm   4/4     Running   0          10s
      
  4. Send a request to the httpbin app. Verify that you get back a 200 HTTP response and that an x-forwarded-client-cert header is returned. The presence of this header indicates that the connection from the gateway to the httpbin app is now encrypted with mutual TLS.

    Example output:

       {
        "headers": {
          "Accept": [
            "*/*"
          ],
          "Host": [
            "www.example.com:8080"
          ],
          "User-Agent": [
            "curl/7.77.0"
          ],
          "X-B3-Sampled": [
            "0"
          ],
          "X-B3-Spanid": [
            "92744e97e79d8f22"
          ],
          "X-B3-Traceid": [
            "8189f0a6c4e3582792744e97e79d8f22"
          ],
          "X-Forwarded-Client-Cert": [
            "By=spiffe://gloo-edge-docs-mgt/ns/httpbin/sa/httpbin;Hash=3a57f9d8fddea59614b4ade84fcc186edeffb47794c06608068a3553e811bdfe;Subject=\"\";URI=spiffe://gloo-edge-docs-mgt/ns/gloo-system/sa/gloo-proxy-http"
          ],
          "X-Forwarded-Proto": [
            "http"
          ],
          "X-Request-Id": [
            "7f1d6e38-3bf7-44fd-8298-a77c34e5b865"
          ]
        }
       }
       

Step 4: Set up mTLS routing for Bookinfo

Deploy the Bookinfo sample app to your service mesh, and verify that Gloo Gateway correctly routes requests to its services.

Add Bookinfo to the service mesh

For testing purposes, you can deploy Bookinfo, the Istio sample app, and add it to your ambient mesh. Note that if you already followed the example to deploy Bookinfo in the Gloo Mesh docs, you can continue to the next section.

  1. Create the bookinfo namespace, and label it with the istio.io/dataplane-mode=ambient label. This label adds all Bookinfo services that you create in the namespace to the ambient mesh.

      kubectl create ns bookinfo
    kubectl label namespace bookinfo istio.io/dataplane-mode=ambient
      
  2. Deploy the Bookinfo app.

      # deploy bookinfo application components for all versions
    kubectl -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio//samples/bookinfo/platform/kube/bookinfo.yaml -l 'app'
    # deploy an updated product page with extra container utilities such as 'curl' and 'netcat'
    kubectl -n bookinfo apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/productpage-with-curl.yaml
    # deploy all bookinfo service accounts
    kubectl -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio//samples/bookinfo/platform/kube/bookinfo.yaml -l 'account'
      
  3. Verify that the Bookinfo app is deployed successfully.

      kubectl get pods,svc -n bookinfo
      
  4. Verify that you can access the ratings app from the product page app.

      kubectl -n bookinfo debug -i pods/$(kubectl get pod -l app=productpage -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -v http://ratings:9080/ratings/1
      

    Example output:

      ...
    < HTTP/1.1 200 OK
    < Content-type: application/json
    < Date: Tue, 24 Dec 2024 20:58:23 GMT
    < Connection: keep-alive
    < Keep-Alive: timeout=5
    < Transfer-Encoding: chunked
    < 
    { [59 bytes data]
    100    48    0    48    0     0   2549      0 --:--:-- --:--:-- --:--:--  2666
    * Connection #0 to host ratings left intact
    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
      

Route to Bookinfo services

To expose the app to incoming traffic requests, you create an HTTPRoute resource that references the product page microservice.

  1. Create an HTTPRoute resource that defines routing rules for each microservice path.

      kubectl apply -n bookinfo -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: bookinfo
    spec:
      parentRefs:
      - name: http
        namespace: gloo-system
      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
    EOF
      
  2. Verify that Gloo Gateway correctly routes traffic requests to Bookinfo services in your serice mesh by opening the product page in your web browser.

      open http://$INGRESS_GW_ADDRESS:8080/productpage 
      

Step 5: Exclude a service from mTLS

You can exclude a service from requiring to communicate with the gateway proxy via mTLS by adding the disableIstioAutoMtls option to the Upstream that represents your service.

  1. Create an Upstream resource that represents the httpbin app and add the disableIstioAutoMtls: true option to it. This option excludes the httpbin Upstream from communicating with the gateway proxy via mTLS.

      kubectl apply -f- <<EOF
    apiVersion: gloo.solo.io/v1
    kind: Upstream
    metadata:
      name: httpbin
      namespace: gloo-system
    spec:
      disableIstioAutoMtls: true
      kube:
        serviceName: httpbin
        serviceNamespace: httpbin
        servicePort: 8000
    EOF
      
  2. Create an HTTPRoute resource that routes traffic to the httpbin Upstream that you created.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: exclude-automtls
      namespace: gloo-system
    spec:
      parentRefs:
      - name: http
        namespace: gloo-system
      hostnames:
        - disable-automtls.example
      rules:
        - backendRefs:
          - name: httpbin
            kind: Upstream
            group: gloo.solo.io
    EOF
      
  3. Send a request to the httpbin app on the disable-automtls.example domain. Verify that you do not get back the x-forwarded-client-cert header.

    Example output:

      {
      "headers": {
         "Accept": [
          "*/*"
        ],
        "Host": [
          "disable-automtls.example:8080"
        ],
         "User-Agent": [
           "curl/7.77.0"
         ],
         "X-Forwarded-Proto": [
          "http"
         ],
        "X-Request-Id": [
          "47c4dcc8-551b-4c93-8aa3-1cd1e15b137c"
        ]
      }
    }
      
  4. Repeat the request to the httpbin app on the www.example.com domain that is enabled for mTLS. Verify that you continue to see the x-forwarded-client-cert header.

    Example output:

       {
        "headers": {
          "Accept": [
            "*/*"
          ],
          "Host": [
            "www.example.com:8080"
          ],
          "User-Agent": [
            "curl/7.77.0"
          ],
          "X-Forwarded-Client-Cert": [
            "By=spiffe://gloo-edge-docs-mgt/ns/httpbin/sa/httpbin;Hash=3a57f9d8fddea59614b4ade84fcc186edeffb47794c06608068a3553e811bdfe;Subject=\"\";URI=spiffe://gloo-edge-docs-mgt/ns/gloo-system/sa/gloo-proxy-http"
          ],
          "X-Forwarded-Proto": [
            "http"
          ],
          "X-Request-Id": [
            "7f1d6e38-3bf7-44fd-8298-a77c34e5b865"
          ]
        }
       }
       

Cleanup

You can optionally remove the resources that you created.

  1. Follow the Uninstall guide in the Gloo Mesh Enterprise documentation to remove Gloo Mesh Enterprise.

  2. Follow the upgrade guide to upgrade your Gloo Gateway Helm installation values. Remove the Helm values that you added as part of this guide.

  3. Remove the Istio sidecar from the httpbin app.

    1. Remove the Istio label from the httpbin namespace.

        kubectl label ns httpbin istio.io/rev-
        
    2. Perform a rollout restart for the httpbin deployment.

        kubectl rollout restart deployment httpbin -n httpbin
        
    3. Verify that the Istio sidecar container is removed and the httpbin pod has three containers.

        kubectl get pods -n httpbin
        

      Example output:

        NAME                       READY   STATUS        RESTARTS   AGE
      httpbin-7d4965fb6d-mslx2   3/3     Running       0          6s
        
  4. Remove the HTTPRoute for the Bookinfo sample app.

      kubectl delete httproute bookinfo -n bookinfo
      
  5. Remove the Upstream and HTTPRoute that you used to exclude a service from mTLS.

      kubectl delete upstream httpbin -n gloo-system
    kubectl delete httproute exclude-automtls -n gloo-system