Route to external services
Enable services in your service mesh to route to endpoints that are located outside the service mesh.
In some cases, one of your Istio-managed apps might need to communicate with services that are external to the service mesh. For example, your app might need to contact a public API or an on-prem database. If you installed Istio with the REGISTRY_ONLY
option, communication is allowed only between services in the mesh. Communication to services outside the mesh is prohibited. To allow services in the mesh to talk to services outside the mesh, you can leverage Gloo ExternalService
and ExternalEndpoint
custom resources. Gloo Mesh translates these resources into an Istio ServiceEntry.
In this guide, you can choose between two solutions to allow routing to an external service, allow routing to an IP address, CIDR, or hostname directly and configure an internal DNS entry to group multiple external endpoints behind one common IP address or hostname. The solution that is right for you depends on your use case. Make sure to review the Routing to external services concept doc for more information.
For additional information about the Gloo custom resources, see the following resources:
- Gloo Mesh API docs for ExternalEndpoint
- Gloo Mesh API docs for ExternalService
Before you begin
- 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 Platform CLI,
meshctl
, along with other CLI tools such askubectl
andistioctl
. - 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.
- Install Bookinfo and other sample apps.
- Decide on the approach to allow routing to an external service. You can choose between the following options:
The guides on this page use a simple route table to allow routing to an external service. For additional route table options, check out the path matching guide to decide how to match the incoming requests to your service paths, the redirect guide to set up any path or host rewrites, or the sub-table delegation guide to nest and sort multiple route tables. Note: Be sure that each route for one host is unique, such as by using prefix matching to determine which requests to the host should be forwarded to which destinations.
Allow routing to an IP address, CIDR, or hostname directly
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.
-
Get the addresses and ports that your external resources listen on. For example, the address might be a static IP address, a CIDR range, or a registered hostname.
-
Create an external service resource with either the
addresses
orhostname
option. Note that you cannot specify a hostname and an IP address or CIDR in the same external service resource.kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalService metadata: name: db-external-service namespace: global spec: addresses: # Static IP address or CIDR - 123.221.3.0 - 144.222.1.6/16 ports: - name: http number: 80 protocol: HTTP selector: {} EOF
kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalService metadata: name: db-external-service namespace: global spec: hosts: - "my-remote-db.com" ports: - name: http number: 80 protocol: HTTP selector: {} EOF
-
Create a route table to allow routing to the external service.
kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: db-routes namespace: global spec: hosts: - '*' http: # Route for the db-external-service - name: db-app # Prefix matching matchers: - uri: prefix: /db/ # Forwarding directive forwardTo: destinations: # Reference to the external service exposing your external endpoints - ref: name: db-external-service kind: EXTERNAL_SERVICE pathRewrite: / EOF
-
Test the route to your external resource from one of the apps in your service mesh. For example, log in to an initiator app in your mesh and run
nslookup my-remote-db.com/db
orcurl 123.221.3.0:80/db
to verify that the external resource is reachable.
Create internal DNS entries for multiple external endpoints
Instead of allowing specific IP addresses, CIDR ranges, or hostnames directly, you can set up an internal hostname or IP address that serves multiple external endpoints and therefore works similarly to setting up a CNAME or A record in your DNS provider. To do that, you use ExternalEndpoint
custom resources to define the external endpoints. Then, you define the internal hostname or IP address that services in the mesh use to route traffic to any of these endpoints in the ExternalService
resource.
-
Get the address and ports that your external resource listens on. For example, the address might be a static IP address or a registered URL.
-
Create an external endpoint for each address and an external service. The external endpoint represents the server or service outside of your service mesh that you want to reach. By using a Gloo Mesh external service, you can then assign a unique hostname to this external endpoint that services in your mesh can use to send requests. You can also use this service to route incoming requests from your ingress gateway directly to your external endpoint.
- Use the address and ports to create an external endpoint resource. In these examples, two external endpoints are created for two static IP addresses that an on-prem database is exposed by.
kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalEndpoint metadata: name: db1-external-endpoint namespace: global labels: # Label that the external service will select external-endpoint: db spec: # Static IP address for on-prem service 1 address: 123.45.67.8 ports: - name: myport number: 9080 EOF kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalEndpoint metadata: name: db2-external-endpoint namespace: global labels: # Label that the external service will select external-endpoint: db spec: # Static IP address for on-prem service 2 address: 123.45.67.9 ports: - name: myport number: 9080 EOF
- Create an external service resource to expose the external endpoint inside your mesh. In this example, you select all endpoints with the
external-endpoint: db
label. Note that thehosts
field is not required to match the address that you specified in the external endpoint, because this host is an internal address that is used only by the gateways and services within your service mesh.kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalService metadata: name: db-external-service namespace: global spec: hosts: # Arbitrary, internal-only hostname assigned to the endpoint - "my-remote-db.com" ports: - name: http number: 80 protocol: HTTP targetPort: number: 9080 selector: # Selects the endpoint label external-endpoint: db EOF
-
Use the address and ports to create an external endpoint resource. In this example, the external endpoint can be reached by using the
httpbin.org
address, and the ports 80 and 443.kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalEndpoint metadata: name: httpbin-external-endpoint namespace: global labels: # Label that the external service will select external-endpoint: httpbin spec: # Registered URL for external service address: httpbin.org ports: - name: http number: 80 - name: https number: 443 EOF
-
Create an external service resource to expose the external endpoint inside your mesh. In this example, you select all external endpoints with the
external-endpoint: httpbin
label. Note that thehosts
field is not required to match the address that you specified in the external endpoint, because this host is an internal address that is used only by the gateways and services within your service mesh.kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: ExternalService metadata: name: httpbin-external-service namespace: global spec: hosts: # Arbitrary, internal-only hostname assigned to the endpoint - "my-remote-svc.com" ports: - name: http number: 80 protocol: HTTP selector: # Selects the endpoint label external-endpoint: httpbin EOF
- Use the address and ports to create an external endpoint resource. In these examples, two external endpoints are created for two static IP addresses that an on-prem database is exposed by.
-
Create a route table to route requests to the external service.
In this example route table, all requests to the
/db/
path are routed to the endpoints that back thedb-external-service
.kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: db-routes namespace: global spec: # Applies to the external service hostname hosts: - my-remote-db.com http: # Route for the db-external-service - name: db-app # Prefix matching matchers: - uri: prefix: /db/ # Forwarding directive forwardTo: destinations: # Reference to the external service exposing your external endpoints - ref: name: db-external-service kind: EXTERNAL_SERVICE pathRewrite: / EOF
In this example route table, all requests to the
/httpbin/
path are routed to the endpoints that back thehttpbin-external-service
.kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: httpbin-routes namespace: global spec: # Applies to the external service hostname hosts: - my-remote-svc.com http: # Route for the httpbin-external-service - name: httpbin-app # Prefix matching matchers: - uri: prefix: /httpbin/ # Forwarding directive forwardTo: destinations: # Reference to the external service exposing your external endpoints - ref: name: httpbin-external-service kind: EXTERNAL_SERVICE pathRewrite: / EOF
-
Test the route to your external resource from one of the apps in your service mesh. For example, log in to an initiator app in your mesh and run
nslookup my-remote-db.com/db
ornslookup my-remote-svc.com/httpbin
to verify that the external resource is reachable through the external service hostname. Or, if you can access an app in your service mesh externally, you can curl the ingress gateway address and the path for your initiator app, and verify that information from the external resource is being successfully returned.
Next steps
- If you haven't already, follow the other guides in the routing section to plan your routing table setup. For example, you might check out the prefix matching guide to decide how to match the incoming requests to your service paths, the redirect guide to set up any path or prefix rewrites, or the sub-table delegation guide to nest and sort multiple route tables.
- Configure additional route settings, such as weighted routing to version subsets or adding and removing headers.
- Apply a policy to your service or route. For example, you might set a connection policy to keep alive connections that the load balancer in your infrastructure provider might otherwise periodically close.