Route to services external to the mesh
After you configure your route table, you can use it to forward requests to services or resources that are external to 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. To route requests to services that are external to your service mesh, you assign a unique internal hostname to your external endpoint that your in-mesh services use to send requests to.
In this guide, you create Gloo Mesh ExternalEndpoint
and ExternalService
resources. Gloo Mesh translates these resources into an Istio ServiceEntry.
- Because external endpoints cannot be automatically discovered by Gloo Mesh, you create a Gloo Mesh
ExternalEndpoint
resource to specify the hostname or IP address, the port, and the protocol of the external endpoint that you want to reach. - Then, you create a Gloo Mesh
ExternalService
resource to expose all of the external endpoints under a unique internal hostname.
For more information, see the following resources:
- Routing to external services concept doc
- Gloo Mesh API docs for ExternalEndpoint
- Gloo Mesh API docs for ExternalService
Before you begin
- Install Gloo Mesh, register workload clusters, and install Istio into each workload cluster. For example, you might follow the demo setup to get a testing environment up and running, or the docs in the installation guide to set up your production-level environment. To enable multicluster routing, ensure that you deploy an east-west gateway.
- Follow the other guides in this routing section to plan your routing table setup. For example, you might 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.
Route to external services
-
Create a virtual gateway that selects the default Istio ingress gateway, which routes incoming traffic (north-south) to your service mesh.
kubectl apply --context $REMOTE_CONTEXT1 -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: VirtualGateway metadata: name: ingress-gateway namespace: gloo-mesh spec: workloads: # Selects the istio ingress gateway in workload cluster 1 - selector: labels: istio: ingressgateway cluster: ${REMOTE_CLUSTER1} listeners: # The port the ingress gateway listens on for incoming requests to route - port: number: 80 http: {} EOF
-
Save the public address of the Istio ingress gateway.
export CLUSTER_1_INGRESS_ADDRESS=$(kubectl --context $REMOTE_CONTEXT1 get svc -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $CLUSTER_1_INGRESS_ADDRESS
export CLUSTER_1_INGRESS_ADDRESS=$(kubectl --context $REMOTE_CONTEXT1 get svc -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') echo $CLUSTER_1_INGRESS_ADDRESS
-
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 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 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: 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. A route table allows you to define how requests to endpoints should be routed, and is translated to the Istio
VirtualService
resource. 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: db-routes namespace: global spec: # Applies to any host; can indicate a specific host hosts: - '*' # Selects the virtual gateway you previously created virtualGateways: - name: ingress-gateway namespace: gloo-mesh cluster: ${REMOTE_CLUSTER1} 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 EOF
kubectl apply --context $REMOTE_CONTEXT1 -n global -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: httpbin-routes namespace: global spec: hosts: - '*' # Selects the virtual gateway you previously created virtualGateways: - name: ingress-gateway namespace: gloo-mesh cluster: ${REMOTE_CLUSTER1} 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 EOF
-
Test the route to your external resource by curling the ingress gateway address and path. For example, the following command appends
/httpbin
for the external httpbin app.curl http://$CLUSTER_1_INGRESS_ADDRESS/httpbin
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.