0

I have multiple deployments running of RDP application and they all are exposed with ClusterIP service. I have nginx-ingress controller in my k8s cluster and to allow tcp I have added --tcp-services-configmap flag in nginx-ingress controller deployment and also created a configmap for the same that is shown below

apiVersion: v1 
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
  3389: “demo/rdp-service1:3389”

This will expose “rdp-service1” service. And I have 10 more such services which needed to be exposed on the same port number but if I add more service in the same configmap like this

...
data
  3389: “demo/rdp-service1:3389”
  3389: “demo/rdp-service2:3389”

Then it will remove the previous service data and since here I have also deployed external-dns in k8s, so all the records created by ingress using host: ... will starts pointing to the deployment attached with the newly added service in configmap.

Now my final requirement is as soon as I append the rule for a newly created deployment(RDP application) in the ingress then it starts allowing the TCP connection for that, so is there any way to achieve this. Or is there any other Ingress controller available that can solve such type of use case and can also easily be integrated with external-dns ?

Note:- I am using AWS EKS Cluster and Route53 with external-dns.

Ajay Pathak
  • 1
  • 1
  • 2
  • If I understand you correctly, you would like to expose multiple `Deployments` of `RDP` app that is using `TCP` traffic with `nginx-ingress` on a **single port**. Have you thought about creating a `Service` that would include them all? You could do that by adding a label to each `Deployment` for example `connect: true` and use it as a selector for the `Service` that is in the `Configmap` (`big-rdp-service:3389`). – Dawid Kruk Apr 29 '21 at 11:03
  • @DawidKruk here I want to do virtual name host based routing too and for this I have to create a rule in ingress to specify the backend service and the host name, so here I could not create a service that includes all the deployments. – Ajay Pathak Apr 29 '21 at 17:11

2 Answers2

1

Posting this answer as a community wiki to explain some of the topics in the question as well as hopefully point to the solution.

Feel free to expand/edit it.


NGINX Ingress main responsibility is to forward the HTTP/HTTPS traffic. With the addition of the tcp-services/udp-services it can also forward the TCP/UDP traffic to their respective endpoints:

The main issue is that the Host based routing for Ingress resource in Kubernetes is targeting specifically HTTP/HTTPS traffic and not TCP (RDP).

You could achieve a following scenario:

  • Ingress controller:
    • 3389 - RDP Deployment #1
    • 3390 - RDP Deployment #2
    • 3391 - RDP Deployment #3

Where there would be no Host based routing. It would be more like port-forwarding.

A side note! This setup would also depend on the ability of the LoadBalancer to allocate ports (which could be limited due to cloud provider specification)


As for possible solution which could be not so straight-forward I would take a look on following resources:

I'd also check following links:

Dawid Kruk
  • 8,982
  • 2
  • 22
  • 45
  • Thanks for replying. Actually I came to know about other ingress controllers that supports TCP routing based on hostname using SNI SSL/TLS termination. I have tried those ingress controllers(Ambassador, Traefik, Kong) and setup all the things required for my use case but still not able to achieve that as my docker image is RDP server, so when I tried to connect with RDP client with the DNS record(i.e., hostname) then it couldn't connect. So now I am confused whether the RDP client send the SNI(i.e., hostname) in the packet or not to the server. – Ajay Pathak May 13 '21 at 05:50
  • @AjayPathak I cannot answer you this question but I'd reckon this question about RDP could be asked on [Serverfault](https://serverfault.com/). – Dawid Kruk May 21 '21 at 15:24
-2

Actually, I really don't know why you are using that configmap.

In my knowledge, nginx-ingress-controller is routing traffic coming in the same port and routing based on host. So if you want to expose your applications on the same port, try using this:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}-ingress
  namespace: your-namespace
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: your-hostname
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          serviceName: {{ .Chart.Name }}-service
          servicePort: {{ .Values.service.nodeport.port }}

Looking in your requirement, I feel that you need a LoadBalancer rather than Ingress

Chuong Nguyen
  • 1,077
  • 6
  • 15
  • Well thanks for replying but this doesn't solve my use case. Actually I have hundreds of deployments, so I don't want to expose every deployment with LoadBalancer. And also since my docker image is RDP desktop, so with nginx-ingress controller I can't directly access it by creating normal rules in ingress and for this in nginx-ingress controller we have to create one configmap to allow tcp connections. And here the problem is that in one configmap we can write one service for one tcp port. – Ajay Pathak Apr 28 '21 at 17:01
  • Hi @AjayPathak, So you want to expose some of your deployments through 1 port. If I understand correctly, you can create a Nodeport type service, and register which deployments you want to expose by filling the "Selector" and "matchLabels" field – Chuong Nguyen Apr 29 '21 at 03:00
  • Yes @AshBlake I have tried this too but if I expose every deployment on NodePort then I could not able to connect with the RDP application in the pod as RDP client application only connects on 3389 port. – Ajay Pathak Apr 29 '21 at 17:15
  • Yes, I think you should find a way to differ your deployments. Cause you want to expose multiple deployments with 1 ports, 1 DNS, that is not possible. – Chuong Nguyen May 03 '21 at 09:58