Discovery - Directing TCP traffic through a static Egress Gateway (DWH connection)
For admin use only!
- Deploy and configure a static Egress Gateway.
- Create the necessary routing and service entry resources to forward TCP connections from the workload pods through the gateway to the final destination of the request.
- Have minimal setup overhead for teams.
Using the Helm Charts for the Egress Gateway, we can set up the ClusterIP Service for the Gateway to listen on a TCP port, 1433.
# gap-gitops/cluster-components/stage/istio-egress-gateway/static-whitelist-internal/static-whitelist-internal-egress-gateway-values.yaml
service:
# ...
- name: dwh
port: 1433
protocol: TCP
targetPort: 1433
# ...
To be able to create the routing rules, we’ll need to create a ServiceEntry first.
In the working example below, there are a couple of things important to note:
- The
ServiceEntryneeds to be exported both to the namespace of the workload, and the namespace of the gateway. - We need to specify a TCP port so we can catch TCP requests originating from the workloads
- The location is set to
MESH_EXTERNALwhich disables mTLS. The requests are encrypted at the workloads.
# gap-gitops/cluster-components/stage/istio-egress-gateway/static-whitelist-internal/resources/gap_dwh_serviceentry.yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: static-gap-dwh-connection
namespace: istio-egress-gateway
labels:
doNotRequireExportTo: enabled
spec:
exportTo:
- .
- cloud-platform
hosts:
- emarsyscdi.database.windows.net
ports:
- name: tcp
number: 1433
protocol: TCP
location: MESH_EXTERNAL
resolution: DNS
The routing rules for the Istio API solution (which we are using) are configured via VirtualService resources.
There will be two TCP routes defined within a single resource:
- From the workload to the Gateway
- From the Gateway to the final destination
Since both routing rules are TCP routing rules, they will be defined under spec.tcp as array elements.
As there is a single resource for both routing rules, they need to be exported to both the Gateway’s and the workload’s namespace.
It would also be possible to separate the two rules into two VirtualService resources.
The first routing rule matches on requests that:
- are going through the mesh
- are targeting the specified port (1433)
- the originating workload has a matching label (
egress-gateway-dwh: enabled) - note that there’s no SNI host matching due to handling TCP requests in this case
The first routing rule directs matching requests to the egress gateway. The gateway needs to be targeted via its full service name. The requests are routed to the port specified, which needs to be the same that is configured in the Gateway’s setup as a TCP port.
The second routing rule matches on requests that:
- are routed through the egress gateway
- are targeting the specified port (1433)
The second routing rule directs matching requests to the DWH, to the port on which the DB is listening (1433).
For configuring further routing rules from other workloads, only the exportTo array needs to be extended with the namespace of the other workload,
and the necessary label should be added to the workload too (egress-gateway-dwh: enabled).
# gap-gitops/cluster-components/stage/istio-egress-gateway/static-whitelist-internal/resources/gap_dwh_virtualservice.yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: direct-static-dwh-connection-through-egress-gateway
namespace: istio-egress-gateway
spec:
exportTo:
- .
- cloud-platform
gateways:
- mesh
- static-whitelist-internal-egress-gateway
hosts:
- emarsyscdi.database.windows.net
tcp:
- match:
- gateways:
- mesh
port: 1433
sourceLabels:
egress-gateway-dwh: enabled
route:
- destination:
host: static-whitelist-internal-egress-gateway.istio-egress-gateway.svc.cluster.local
port:
number: 1433
- match:
- gateways:
- static-whitelist-internal-egress-gateway
port: 1433
route:
- destination:
host: emarsyscdi.database.windows.net
port:
number: 1433
Based on the setup above, the workload needs to send requests to the DWH domain to port 1433, and opt for encrypting the request. Also, the following label needs to be added to the pods:
egress-gateway-dwh: enabled
For an example on how to assemble a DWH connection string using Python, you can take a look at the following test repository: https://github.com/emartech/gap-dwh-connection-test