<p>I have 2 pods in a Kubernetes namespace. One uses <code>TCP</code> and the other uses <code>UDP</code> and both are exposed using <code>ClusterIP</code> services via external IP.  Both services use the same external IP.</p>
<p>This way I let my users access both the services using the same IP.
I want to remove the use of <code>spec.externalIPs</code> but be able to allow my user to still use a single domain name/IP to access both the <code>TCP</code> and <code>UDP</code> services.</p>
<p>I do not want to use <code>spec.externalIPs</code>, so I believe clusterIP and NodePort services cannot be used. ​Load balancer service does not allow me to specify both <code>TCP</code> and <code>UDP</code> in the same service.</p>
<p>I have experimented with NGINX Ingress Controller. But even there the Load Balancer service needs to be created which cannot support both <code>TCP</code> and <code>UDP</code> in the same service.</p>
<p>Below is the cluster IP service exposing the apps currently using external IP:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: tcp-udp-svc
  name: tcp-udp-service
spec:
  externalIPs:
  - &lt;public IP- IP2&gt;
  ports:
  - name: tcp-exp
    port: 33001
    protocol: TCP
    targetPort: 33001
  - name: udp-exp
    port: 33001
    protocol: UDP
    targetPort: 33001
  selector:
    app: tcp-udp-app
  sessionAffinity: None
  type: ClusterIP
</code></pre>
<p>The service shows up like below</p>
<pre><code>NAME                  TYPE           CLUSTER-IP            EXTERNAL-IP        PORT(S)
tcp-udp-service       ClusterIP      &lt;internal IP IP1&gt;     &lt;public IP- IP2&gt;   33001/TCP,33001/UDP
</code></pre>
<p>Using the above set up, both the <code>TCP</code> and <code>UDP</code> apps on port 33001 is accessible externally just fine using IP2.</p>
<p>As you can see I've used:</p>
<pre><code>spec:
  externalIPs:
  - &lt;public IP- IP2&gt;
</code></pre>
<p>In the service to make it accessible externally.</p>
<p>However I do not want to use this set up, ie. I am looking for a set up without using the <code>spec.externalIPs</code>.</p>
<p>When using a load balancer service to expose the apps, I see that both <code>TCP</code> and <code>UDP</code> cannot be added in the same load balancer service. So I have to create one load balancer service for <code>TCP</code> and add another load balancer service for <code>UDP</code> like below</p>
<pre><code>NAME                TYPE           CLUSTER-IP            EXTERNAL-IP        PORT(S)
tcp-service         LoadBalancer   &lt;internal IP IP1&gt;     &lt;public IP- IP2&gt;   33001/TCP

udp-service         LoadBalancer   &lt;internal IP IP3&gt;     &lt;public IP- IP4&gt;   33001/UDP


---
apiVersion: v1
kind: Service
metadata:
  name: tcp-service 
 spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: tcp-svc
    port: 33001
    protocol: TCP
    targetPort: 33001
  selector:
     app: tcp-udp-app
  sessionAffinity: None
  type: LoadBalancer

---
apiVersion: v1
kind: Service
metadata:
  name: udp-service
 spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: udp-svc
    port: 33001
    protocol: UDP
    targetPort: 33001
  selector:
     app: tcp-udp-app
  sessionAffinity: None
  type: LoadBalancer 
</code></pre>
<p>But the problem is that each of these services get individual IPs assigned (IP2 &amp; IP4).
But I want to be able to access both the TCP &amp; UDP apps using the same IP. When testing out with nginx ingress controller too, I am faced the same issue as above.</p>
<p>Is there any other possible way to achieve what I am looking for, ie. to expose both TCP and UDP services on the same IP, but without using the <code>spec.externalIPs</code>?</p>

<p>Unfortunately, you will not be able to achieve your desired result with Load Balancer. Service type in any way for UDP traffic, because according the <a href="https://cloud.ibm.com/docs/containers?topic=containers-vpc-lbaas#lbaas_limitations" rel="nofollow noreferrer">following documentation</a> UDP protocol is not supported by any of VPC load balancer types.</p>
<p>You could theoretically define a portable public IP address for LoadBalancer Service type, by using the <code>loadBalancerIP</code> annotation, but this portable public IP address has to be available in portable public subnet upfront and Cloud Provivers's LB needs to support UDP protocol.  You can see <a href="https://cloud.ibm.com/docs/containers?topic=containers-cs_loadbalancer_fails" rel="nofollow noreferrer">this doc</a></p>
<p>Workaround for non-Prod setup:</p>
<p>You can use <code>hostPort</code> to <a href="https://kubernetes.io/docs/concepts/configuration/overview/" rel="nofollow noreferrer">expose</a> TCP &amp; UDP ports directly on worker nodes. Could be used together with some Ingress controllers that support TCP &amp; UDP Services, like NGINX Ingress. For more see <a href="https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/" rel="nofollow noreferrer">this documentation</a>.</p>
