Expose TCP services 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
extraHosts
to 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