Expose TCP and UDP on a k8s cluster with one LoadBalancer - kubernetes

I've got a single-node k8s cluster running on a VPS with Traefik configured as it's Ingress controller and MetalLB as the LoadBalancer.
This is working great for all my TCP servers, however, I would like to host a dedicated game server in the cluster, which needs to be exposed over UDP.
Now, I know Traefik supports UDP as well as TCP, but the problem is getting it to Traefik.
I cannot expose multiple protocols over one Service of type LoadBalancer, meaning that that option will not work.
I could try exposing the service through NodePorts, but that will change the mapping of the ports which I want to prevent. Also, using port-forward is not possible, as this does not support UDP.
What other options do I have?

I just found out that MetalLB supports IP sharing under some conditions!.
I'll try this out.

Related

Kubernetes service proxy

Kuberenetes newbie here, we have a jms server outside the cluster thats only accessible through our cluster, how can I create a port forward proxy on the cluster so I can connect to it via my local pc?
Proxy is an application layer function or feature, whereas port forwarding is really just a manual entry in one of the NAPT tables. A proxy understands the application protocol and can be used as a single entry point for multiple exposed servers.
The NGINX Ingress Controller for Kubernetes (as a proxy) is compatible with the NGINX web server. If you want to access workloads that are already running on your cluster from outside of it. Creating an Ingress resource is the standard procedure. In your workload cluster, add an ingress controller. For installation instructions, see this page.
Kubernetes port forwarding:
This is especially useful when you want to directly communicate with a specific port on a Pod from your local machine, according to the official kubernetes Connect with Port Forwarding documentation. Additionally, you don't have to manually expose services to accomplish this. Kubectl port-forward, on the other hand, moves connections from a local port to a pod port. Kubectl port-forward is more general than kubectl proxy because it can forward TCP traffic while kubectl proxy can only forward HTTP traffic. Although Kubectl simplifies port forwarding, it should only be utilized for debugging.
You can learn more about how to use port-forward to access applications in a cluster and another similar info link & SO aids in better comprehension.
Finally, for more information, see Port-Forwarding and Proxy Server and Client Deployment.

What is a Kubernetes LoadBalancer On-Prem

I understand that, in Cloud scenarios, a LoadBalancer resource refers to and provisions an external layer 4 load balancer. There is some proprietary integration by which the cluster configures this load balancing. OK.
On-prem we have no such integration so we create our own load balancer outside of the cluster which distributes traffic to all nodes - effectively, in our case to the ingress.
I see no need for the cluster to know anything about this external load balancer.
What is a LoadBalancer* then in an on-prem scenario? Why do I have them? Why do I need one? What does it do? What happens when I create one? What role does the LoadBalancer resource play in ingress traffic. What effect does the LoadBalancer have outside the cluster? Is a LoadBalancer just a way to get a new IP address? How/why/ where does the IP point to and where does the IP come from?
All questions refer to the Service of type “LoadBalancer” inside cluster and not my load balancer outside the cluster of which the cluster has no knowledge.
As pointed out in the comments a kubernetes service of type LoadBalancer can not be used by default with on-prem setups. You can use metallb to setup a service of that type in an on prem environment.
Kubernetes does not offer an implementation of network load balancers (Services of type LoadBalancer) for bare-metal clusters. [...] If you’re not running on a supported IaaS platform (GCP, AWS, Azure…), LoadBalancers will remain in the “pending” state indefinitely when created. [...] MetalLB aims to redress this imbalance by offering a network load balancer implementation that integrates with standard network equipment, so that external services on bare-metal clusters also “just work” as much as possible.
You can for example use the BGP mode to advertise the service's IP to your router, read more on that in the docs.
The project is still in beta but is promoted as production ready and used by several bigger companies.
Edit
Regarding your question in the comments:
Can I just broadcast the MAC address of my node and manually add the IP I am broadcasting to the LoadBalancer service via kubectl edit?
Yes that would work too. That's basically what metallb does, announcing the IP and updating the service.
Why need a software then? Imaging having 500 hosts that come and go with thousends of services of type LoadBalancer that come and go. You need an automation here.
Why does Kubernetes need to know this IP?
It doesn't. If you don't use an external ip, the service is still usable via it's NodePort, see for example the istio docs (with a little more details added by me):
$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
istio-ingressgateway LoadBalancer 192.12.129.119 <Pending> [...],80:32123/TCP,443:30994/TCP,[...]
Here the external IP is not set and stays in <Pending>. You can still use the service by pointing your traffic to <Node-IP>:32123 for plain http and to <Node-IP>:30994 for https. As you can see above those ports are mapped to 80 and 443.
If the external ip is set you can direct traffic directly to port 80 and 443 on the external load balancer. Kube-Proxy will create an iptables chain with the destination of you external ip, that basically leads from the external IP over the service ip with a load balancer configuration to a pod ip.
To investigate that set up a service of type LoadBalancer, make sure it has an external ip, connect to the host and run the iptables-save command (e.g. iptables-save | less). Search for the external ip and follow the chain until you end up at the pod.

Traffic from two ports to one entrypoint?

In Kubernetes I use the Traefik ingress controller. My Kubernetes cluster is Bare Metal.
I have two services listening on ports 8080 and 8082. These two services are tied to one deployment. The deployment has an application that listens on these two ports for different tasks.
Can traffic be routed to these two ports through the same entrypoint, or is this not recommended?
I'm not familiar with kubernetes, so excuse me if I misunderstood the question.
I'm running traefik with a single entry point on port 443 in front of multiple docker-compose services. That's no problem whatsoever. However, traefik needs to know which service the client wants to reach. This is done by specifying different host rules for these services. see

Accessing a webpage hosting on a pod

I have deployment that hosts a website on port 9001 and a service attached to it. I want to allow anyone (from outside cluster) to be able to connect to that site.
Any help would be appreciated.
I want to allow anyone (from outside cluster) to be able to connect to that site
There are many ways to do this using kubernetes services to expose port 9001 of the website to the outside world:
Service type LoadBalancer if you have an external, cloud-provider's load-balancer.
ExternalIPs. The website can be hit at ExternalIP:Port.
Service type NodePort if the cluster's nodes are reachable from the users. The website can be hit at NodeIP:NodePort.
Ingress controller and ingress resource.
As you wrote that this is not a cloud deployment, you need to consider how to correctly expose this to the world in a decent fashion. First and formost, create a NodePort type service for your deployment. With this, your nodes will expose that service on a high port.
Depending on your network, at this point you either need to configure a loadbalancer in your network to forward traffic for some IP:80 to your node(s) high NodePort, or for example deploy HAProxy in a DeamonSet with hostNetwork: true that will proxy 80 to your NodePort.
A bit more complexity can be added by deployment of Nginx IngressController (exposed as above) and use of Ingress to make the Ingress Controller expose all your services without the need to fiddle with NodePort/LB/HAProxy for each of them individualy any more.

Kubernetes LoadBalancer with both HTTPS and TCP traffic

I have an HTTP LoadBalancer on Google Kubernetes Engine that is configured with nginx-ingress to serve website traffic. I would now also like to expose a database (PostgreSQL) on port 5432. How do I do that without the cost of a separate LoadBalancer? nginx-ingress seems to only support HTTP traffic.
EDIT:
Actually, never mind; see https://github.com/nginxinc/kubernetes-ingress/blob/c525f568e5b2c5fb234706c67c9a453d4248ee9f/examples/customization/nginx-config.yaml#L35 for how to add a main snippet via NGINX ingress configmap. Lookup how to use NGINX as a TCP proxy and put that snippet there
Configuration snippets available via annotations don't allow you to add a whole server. Meaning the standard ingress controller deployment can't do what you are asking. You'll have to put together a custom deployment yourself to add another server snippet.