Kubernetes Host and Service Ingress Mapping using TCP

8/27/2021

While working with Kubernetes for some months now, I found a nice way to use one single existing domain name and expose the cluster-ip through a sub-domain but also most of the microservices through different sub-sub-domains using the ingress controller.

My ingress example code:

kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: cluster-ingress-basic
  namespace: ingress-basic
  selfLink: >-
    /apis/networking.k8s.io/v1beta1/namespaces/ingress-basic/ingresses/cluster-ingress-basic
  uid: 5d14e959-db5f-413f-8263-858bacc62fa6
  resourceVersion: '42220492'
  generation: 29
  creationTimestamp: '2021-06-23T12:00:16Z'
  annotations:
    kubernetes.io/ingress.class: nginx
  managedFields:
    - manager: Mozilla
      operation: Update
      apiVersion: networking.k8s.io/v1beta1
      time: '2021-06-23T12:00:16Z'
      fieldsType: FieldsV1
      fieldsV1:
        'f:metadata':
          'f:annotations':
            .: {}
            'f:kubernetes.io/ingress.class': {}
        'f:spec':
          'f:rules': {}
    - manager: nginx-ingress-controller
      operation: Update
      apiVersion: networking.k8s.io/v1beta1
      time: '2021-06-23T12:00:45Z'
      fieldsType: FieldsV1
      fieldsV1:
        'f:status':
          'f:loadBalancer':
            'f:ingress': {}
spec:
  rules:
    - host: microname1.subdomain.domain.com
      http:
        paths:
          - pathType: ImplementationSpecific
            backend:
              serviceName: kylin-job-svc
              servicePort: 7070
    - host: microname2.subdomain.domain.com
      http:
        paths:
          - pathType: ImplementationSpecific
            backend:
              serviceName: superset
              servicePort: 80
    - {}
status:
  loadBalancer:
    ingress:
      - ip: xx.xx.xx.xx

With this configuration:

  1. microname1.subdomain.domain.com is pointing into Apache Kylin
  2. microname2.subdomain.domain.com is pointing into Apache Superset

This way all microservices can be exposed using the same Cluster-Load-Balancer(IP) but the different sub-sub domains.

I tried to do the same for the SQL Server but this is not working, not sure why but I have the feeling that the reason is that the SQL Server communicates using TCP and not HTTP.

- host: microname3.subdomain.domain.com
  http:
    paths:
      - pathType: ImplementationSpecific
        backend:
          serviceName: mssql-linux
          servicePort: 1433

Any ideas on how I can do the same for TCP services?

-- Stavros Koureas
ingress-controller
kubernetes
service
sql-server

1 Answer

8/27/2021

Your understanding is good, by default NGINX Ingress Controller only supports HTTP and HTTPs traffic configuration (Layer 7) so probably your SQL server is not working because of this.

Your SQL service is operating using TCP connections so it is does not take into consideration custom domains that you are trying to setup as they are using same IP address anyway .

The solution for your issue is not use custom sub-domain(s) for this service but to setup exposing TCP service in NGINX Ingress Controller. For example you can setup this SQL service to be available on ingress IP on port 1433:

Ingress controller uses the flags --tcp-services-configmap and --udp-services-configmap to point to an existing config map where the key is the external port to use and the value indicates the service to expose using the format: <namespace/service name>:<service port>:[PROXY]:[PROXY]

To setup it you can follow steps provided in official NGINX Ingress documentation but there are also some more detailed instructions on StackOverflow, for example this one.

-- Mikolaj S.
Source: StackOverflow