Expose TCP services using ingress-nginx
Stream TCP using ingress-nginx.
A no nonsense guide to exposing TCP services using ingress-nginx.
Install the TCP service
Install the Service that binds the TCP port you need to expose.
For this example we'll install a dind (Docker in Docker) deployment and expose TCP port 2376.
helm repo add lazybit https://chartmuseum.lazybit.ch
helm repo update
helm install dind lazybit/dind --set extraHosts[0]=example.com
Note: Set
extraHoststo the DNS name that will resolve the service.
Note: Check this StackOverflow answer for an example exposing a PostgresQL database.
Install ingress-nginx
Install the ingress-nginx contoller for your cluster.
Create the tcp-services ConfigMap
The tcp-services ConfigMap's data entries are formatted: <external port>: <namespace/service name>:<service port>:[PROXY]:[PROXY]
cat <<EOF |kubectl apply -n ingress-nginx -f -
apiVersion: v1
data:
"2376": default/dind:2376
kind: ConfigMap
metadata:
name: tcp-services
EOF
Patch the ingress-controller Deployment
Patch the ingress-nginx Deployment's spec.template.spec.containers[0].args with the --tcp-services argument using the format --tcp-services=<namespace/configmap name>:
INGRESS_NGINX_ARGS=$(\
kubectl get deployments.apps \
-n ingress-nginx \
nginx-ingress-controller \
-o json | jq '.spec.template.spec.containers[]|select(.name=="nginx-ingress-controller")|.args+=["--tcp-services=ingress-nginx/tcp-services"]|.args|unique'
)
PATCH='{"spec":{"template":{"spec":{"containers":[{"name":"nginx-ingress-controller","args":[{}]}]}}}}'
kubectl patch deployments.apps -n ingress-nginx nginx-ingress-controller -p "$(echo "$PATCH" |jq ".spec.template.spec.containers[0].args=$INGRESS_NGINX_ARGS")"
Patch the ingress-nginx Service
Patch the ingress-nginx Service:
kubectl patch service -n ingress-nginx ingress-nginx -p '{"spec": {"ports": [{"port": 2376,"targetPort": 2376,"name": "dind"}]}}'
Tip: Google Kubernetes Engine and DigitalOcean will automatically update existing firewall rules for allowing traffic on the specified port.
Test the connection
Copy the client TLS certificates for connecting to the docker daemon:
kubectl cp dind-0:/certs/client client
Set the users environment and connect to the remote docker daemon:
export DOCKER_HOST=tcp://example.com:2376
export DOCKER_CERT_PATH=${PWD}/client
export DOCKER_TLS_VERIFY=1
docker ps
