You can allow routing to an external static IP address, CIDR range, or hostname from services in your mesh by using an ExternalService Gloo custom resource.

Before you begin

  1. Complete the multicluster getting started guide to set up the following testing environment.

    • Three clusters along with environment variables for the clusters and their Kubernetes contexts.
    • The Gloo meshctl CLI, along with other CLI tools such as kubectl and istioctl.
    • The Gloo management server in the management cluster, and the Gloo agents in the workload clusters.
    • Istio installed in the workload clusters.
    • A simple Gloo workspace setup.
  2. Install Bookinfo and other sample apps.
  3. Decide on the outbound traffic policy for your service mesh. If you followed the steps to install Istio with the Istio lifecycle manager, the outbound traffic policy for your service mesh is set to ALLOW_ANY by default and allows your services in the mesh to reach any external endpoint. You can change this setting and instead block all egress traffic to hosts that are not part of your service mesh by changing the outbound traffic policy to REGISTRY_ONLY as shown in the following steps. Note that if you manually installed Istio, follow the steps in Upgrade Istio to update that setting. The steps in this guide assume that youo set the outbound traffic policy for your service mesh to REGISTRY_ONLY.

    1. Open the gm-istiod-values.yaml file that you used to create the istiod control plane.
    2. Change the outboundTrafficPolicy field to REGISTRY_ONLY.
    3. Apply your changes by using the following command.
        kubectl apply -f gm-istiod-values.yaml --context $MGMT_CONTEXT
        

Route to an external service directly

Create an external service to represent the service outside the mesh that you want to route to.

  1. Log in to the reviews app and verify that you cannot reach www.google.com.

      kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=reviews -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -vik www.google.com
      

    Example output:

      * Mark bundle as not supporting multiuse
    < HTTP/1.1 502 Bad Gateway
    HTTP/1.1 502 Bad Gateway
    < date: Thu, 11 May 2023 17:07:43 GMT
    date: Thu, 11 May 2023 17:07:43 GMT
    < server: envoy
    server: envoy
    < content-length: 0
    content-length: 0
      
  2. Create the global namespace in the management cluster.

      kubectl create ns global --context $MGMT_CONTEXT
      
  3. Create an external service resource for www.google.com. If you want to specify an IP address or CIDR instead, replace spec.hosts with spec.addresses. Note that you cannot specify a hostname and an IP address or CIDR in the same external service resource. For more information, see the API reference for ExternalService.

      kubectl apply --context $MGMT_CONTEXT -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: ExternalService
    metadata:
      name: google
      namespace: global
    spec:
      hosts:
      - "www.google.com"
      ports:
      - name: http
        number: 80
        protocol: HTTP
      selector: {}
    EOF
      
  4. Log in to the reviews app again and verify that you are now able to reach www.google.com.

      kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=reviews -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -vik www.google.com
      

    Example output:

      ...
    * Connected to www.google.com (240.240.121.170) port 80 (#0)
    > GET / HTTP/1.1
    > Host: www.google.com
    > User-Agent: curl/8.0.1-DEV
    > Accept: */*
    > 
    HTTP/1.1 200 OK
    date: Thu, 11 May 2023 20:20:30 GMT
    expires: -1
    cache-control: private, max-age=0
    content-type: text/html; charset=ISO-8859-1
    content-security-policy-report-only: object-src 'none';base-uri 'self';script-src 'nonce-EB6v-9MT_uuKEuJkStGmsw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
    p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
    server: envoy
    x-xss-protection: 0
    x-frame-options: SAMEORIGIN
    ...
      

Create multiple external services

You can create multiple external services that share the same host but have different ports or wildcard subdomains. For example, you might have different teams own different subdomains of an external service. Or, several third-party services might be exposed on different ports of the same host.

Before you begin, create an external service that routes traffic to www.google.com.

  1. Create another external service resource for *.google.com. This way, you can reach another service exposed on the google.com host, such as images.google.com. If you want to specify an IP address or CIDR instead, replace spec.hosts with spec.addresses. Note that you cannot specify a hostname and an IP address or CIDR in the same external service resource.

      kubectl apply --context $MGMT_CONTEXT -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: ExternalService
    metadata:
      name: google-wildcard
      namespace: bookinfo
    spec:
      hosts:
      - "*.google.com"
      ports:
      - name: http
        number: 80
        protocol: HTTP
      selector: {}
    EOF
      
  2. Log in to the reviews app again and verify that you are now able to reach images.google.com.

      kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=reviews -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -vik images.google.com
      

    Example output:

      ...
    * Connected to images.google.com (172.253.124.113) port 80
    > GET / HTTP/1.1
    > Host: images.google.com
    > User-Agent: curl/8.8.0
    > Accept: */*
    > 
    * Request completely sent off
    < HTTP/1.1 200 OK
    ...
      

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl delete externalservice google -n global --context $MGMT_CONTEXT
kubectl delete externalservice google-wildcard -n global --context $MGMT_CONTEXT
kubectl delete ns global --context $MGMT_CONTEXT