Skip to main content
logoTetrate Service BridgeVersion: 1.4.x

Controlling Access to External Services

Egress Gateways act as a gateway for traffic exiting the mesh. Users are able to define services that are allowed to send traffic to external services through the gateway

Currently only HTTPS can be sent externally. However, the original outbound requests should use HTTP. These outbound HTTP requests are converted to HTTPS requests and sent to the external services. For example, a request to http://tetrate.io from the service that goes through an Egress Gateway is converted to a request to https://tetrate.io, and is proxied on behalf of the originating service. Currently requests that are ultimately need to be HTTP are not supported. For example, you will not be able to use Egress Gateways if your final destination is http://tetrate.io

This document will describe how to configure Egress Gateways to allow services to only send outbound requests to specific services. The following diagram shows the request and response flow when using an Egress Gateway:

Egress Gateway Flow

Before you get started, make sure you:
✓ Familiarize yourself with TSB concepts
✓ Install the TSB environment. You can use TSB demo for quick install
✓ Completed TSB usage quickstart. This document assumes you already created Tenant and are familiar with Workspace and Config Groups. Also you need to configure tctl to your TSB environment.

Please note that in the following example you will deploy Egress Gateway in the demo cluster that you have created using the TSB demo install. If you are using another cluster, change the cluster name in the example accordingly.

Deploy Sleep Services

In this example you will use two sleep services, each living in separate namespaces.

Create the namespaces sleep-one and sleep-two:

kubectl create namespace sleep-one
kubectl create namespace sleep-two

Then follow the instructions in the "Installing sleep Workload in TSB" document to install sleep service two sleep services in the demo cluster. Install the service sleep-one in namespace sleep-one, and the service sleep-two in namespace sleep-two, respectively

You do NOT need to create a Workspace, as you will do this later in this example.

Create Workspace and Traffic Group for Sleep Services

You will need a Traffic Group to associate with the Egress Gateway that you will be creating later. Since a Traffic Group belongs to a Workspace, you will need to create a Workspace as well.

Create a file name sleep-workspace.yaml with the following contents. Replace the values for cluster, organization, and tenant accordingly. For demo installations, you can use the value demo for the cluster, and tetrate for both organization and tenant.

apiversion: api.tsb.tetrate.io/v2
kind: Workspace
metadata:
organization: <organization>
tenant: <tenant>
name: sleep
spec:
displayName: Sleep Workspace
namespaceSelector:
names:
- "<cluster>/sleep-one"
- "<clluser>/sleep-two"
---
apiVersion: traffic.tsb.tetrate.io/v2
kind: Group
metadata:
organization: <organization>
tenant: <tenant>
workspace: sleep
name: sleep-tg
spec:
displayName: Sleep Traffic
namespaceSelector:
names:
- "<cluster>/sleep-one"
- "<cluster>/sleep-two"
configMode: BRIDGED

Apply with tctl:

tctl -f sleep-workspace.yaml

Deploy Egress Gateway

Create the Egress Gateway Namespace

Egress gateways are typically managed by a separate team than the one developing the app (in this case, the sleep services) to avoid the ownerships being mixed up.

In this example we create a separate namespace egress to manage the Egress Gateway. Execute the following command to create a new namespace:

kubectl create namespace egress

Deploy the Egress Gateway

Create a file called egress-deploy.yaml with the following contents:

apiVersion: install.tetrate.io/v1alpha1
kind: EgressGateway
metadata:
name: cluster-egress
namespace: egress
spec:
kubeSpec:
service:
type: NodePort

Apply with kubectl:

kubectl apply -f egress-deploy.yaml

Create a Workspace and a Gateway Group for Egress Gateway

You will also need to create a Workspace and a Gateway Group for the Egress Gateway that you just created.

Create a file named egress-workspace.yaml with the following contents. Replace the values for cluster, organization, and tenant accordingly. For demo installations, you can use the value demo for the cluster, and tetrate for both organization and tenant.

apiversion: api.tsb.tetrate.io/v2
kind: Workspace
metadata:
organization: <organization>
tenant: <tenant>
name: egress
spec:
displayName: Egress Workspace
namespaceSelector:
names:
- "<cluster>/egress"
---
apiVersion: gateway.tsb.tetrate.io/v2
kind: Group
metadata:
organization: <organization>
tenant: <tenant>
workspace: egress
name: egress-gw
spec:
displayName: Egress Gateway
namespaceSelector:
names:
- "<cluster>/egress"
configMode: BRIDGED

Apply with tctl

tctl apply -f egress-workspace.yaml

Configure Egress Gateway

In this example, you will be applying different configurations to the two sleep services.

sleep-one will be configured so that it can access all external URLs, but sleep-two will only be allowed to access a single destination (in this sample, "edition.cnn.com").

Create a file named egress-config.yaml with the following contents. Replace the values for organization and tenant accordingly. For demo installations, you can use the value tetrate for both organization and tenant.

apiVersion: gateway.tsb.tetrate.io/v2
kind: EgressGateway
metadata:
organization: <organization>
tenant: <tenant>
workspace: egress
group: egress-gw
name: cluster-egress
spec:
workloadSelector:
namespace: egress
labels:
app: cluster-egress
authorization:
- from:
mode: CUSTOM
serviceAccounts: ["sleep-one/sleep"]
to: ["*"]
- from:
mode: CUSTOM
serviceAccounts: ["sleep-two/sleep"]
to: ["edition.cnn.com"]

Apply with tctl

tctl apply -f egress-config.yaml

Create TrafficSettings to use Egress Gateway

Finally, create traffic settings to tie the Traffic Group that the services are associated to with the Egress Gateway.

Create a file named sleep-traffic-setting-egress.yaml with the following contents. Replace the values for organization and tenant accordingly. For demo installations, you can use the value tetrate for both organization and tenant.

The host value is in <namespace>/<fqdn> format. The fqdn value is derived from the namespace and metadata.name values specified in the previous step:

apiVersion: traffic.tsb.tetrate.io/v2
kind: TrafficSetting
metadata:
organization: <organization>
tenant: <tenant>
workspace: sleep
group: sleep-tg
name: sleep-traffic-settings
spec:
egress:
host: egress/cluster-egress.egress.svc.cluster.local

Apply this with tctl:

tctl apply -f sleep-traffic-setting-egress.yaml

Testing

To test whether Egress Gateway is working correctly, you will be sending requests from the sleep services to external services.

For this you will need to figure out the Pod names for sleep-one and sleep-two. Execute the following commands to lookup the Pod names:

export SLEEP_ONE_POD=$(kubectl get pod -n sleep-one -l app=sleep -o jsonpath={.items.metadata.name})
export SLEEP_TWO_POD=$(kubectl get pod -n sleep-two -l app=sleep -o jsonpath={.items.metadata.name})

Execute the following commands against sleep-one. Since you have configured the Egress Gateway such that sleep-one is allowed to access all external services, the following commands should all display "200":

kubectl exec ${SLEEP_ONE_POD} -n sleep-one -c sleep -- \
curl http://twitter.com \
-s \
-o /dev/null \
-L \
-w "%{http_code}\n" \
-H "X-B3-Sampled: 1"

kubectl exec ${SLEEP_ONE_POD} -n sleep-one -c sleep -- \
curl http://github.com \
-s \
-o /dev/null \
-L \
-w "%{http_code}\n" \
-H "X-B3-Sampled: 1"

kubectl exec ${SLEEP_ONE_POD} -n sleep-one -c sleep -- \
curl http://edition.cnn.com \
-s \
-o /dev/null \
-L \
-w "%{http_code}\n" \
-H "X-B3-Sampled: 1"

kubectl exec ${SLEEP_ONE_POD} -n sleep-one -c sleep -- \
curl http://httpbin.org \
-s \
-o /dev/null \
-L \
-w "%{http_code}\n" \
-H "X-B3-Sampled: 1"

Do the same for service sleep-two by replacing SLEEP_ONE_POD to SLEEP_TWO_POD, and sleep-one to sleep-two, respectively.

This time, only requests to edition.cnn.com should display "200". All other requests should display "403".