Connecting to DWH using an Stunnel (deprecated)
This method is deprecated. Refer to the connecting to DWH through a gateway guide for the currently supported method.
Connecting to the DWH Azure DB from GAP is not straightforward, due to the firewall rules enabled on the host of the DB. These rules only allow connections from a whitelisted range of IP addresses. GAP has a pool of nodes that have whitelisted static IP addresses, thus enabling connections to the DB. The solution described here will show you how to set up an stunnel, which will run on one of the whitelisted nodes and will forward and encrypt the traffic from your Service Mesh enabled GAP application to the DWH DB host.
We are going to set up:
- A patch file containing:
- A Deployment containing stunnel
- A Service for stunnel
- A ConfigMap for stunnel
- An Istio ServiceEntry
Create the following patch file, and make sure to replace <application-name> and <namespace-name> with your application and namespace names respectively.
This patch file defines three Kubernetes resources.
- A Deployment: Manages the Pod running an Stunnel container. The Pod is scheduled on a whitelist node. Whitelist nodes have static IP addresses that are allowed through the DWH’s firewall.
- A Service: Makes the Stunnel discoverable from within the Cluster.
- A ConfigMap: Contains Stunnel’s configuration to be mounted into the container.
gap/production/gap_stunnel.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: <application-name>-dwh-stunnel
namespace: <namespace-name>
annotations:
gap/daily-restart: enabled
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: <application-name>
app.kubernetes.io/instance: dwh
template:
metadata:
labels:
app.kubernetes.io/name: <application-name>
app.kubernetes.io/instance: dwh
spec:
containers:
- name: "stunnel"
image: eu.gcr.io/ems-gap-images/stunnel:v2
command:
- dumb-init
args:
- stunnel
- /etc/stunnel/config
ports:
- containerPort: 8443
name: stunnel
securityContext:
runAsUser: 100
resources:
requests:
memory: 8Mi
cpu: 100m
volumeMounts:
- name: config
mountPath: "/etc/stunnel"
readOnly: true
restartPolicy: Always
tolerations:
- key: "role"
operator: "Equal"
value: "whitelist-internal"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: role
operator: In
values:
- whitelist-internal
volumes:
- name: config
configMap:
name: <application-name>-dwh-stunnel
items:
- key: config
path: config
---
apiVersion: v1
kind: Service
metadata:
name: <application-name>-dwh-stunnel
namespace: <namespace-name>
labels:
app.kubernetes.io/name: <application-name>
app.kubernetes.io/instance: dwh
spec:
ports:
- name: stunnel
port: 8443
protocol: TCP
targetPort: stunnel
selector:
app.kubernetes.io/name: <application-name>
app.kubernetes.io/instance: dwh
---
apiVersion: v1
kind: ConfigMap
metadata:
name: <application-name>-dwh-stunnel
namespace: <namespace-name>
labels:
app.kubernetes.io/name: <application-name>
app.kubernetes.io/instance: dwh
data:
config: |
foreground = yes
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
[remote]
client = yes
accept = 0.0.0.0:8443
connect = emarsyscdi.database.windows.net:1433
This Istio service entry will tell the Istio proxy in your meshed Pod to resolve emarsyscdi.database.windows.net to the Stunnel service.
Replace <stunnel-service-cluster-IP> with the Cluster IP of your Stunnel service (found by listing the services in your namespace using k9s or kubectl).
gap/production/gap_dwh_service_entry.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: stunnel
spec:
exportTo:
- "."
hosts:
- emarsyscdi.database.windows.net
ports:
- number: 8443
name: tcp-stunnel
protocol: TCP
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: <stunnel-service-cluster-IP>
Thespec.exportTofield is critical to have its value set to an array containing only one element,".". This ensures that the ServiceEntry is only exported to your namespace, and not globally on GAP, which would make it clash with other ServiceEntries that affect the same hosts.