2

I am following this guide to expose a service running on my bare metal k8s cluster to the world.

The guide suggests using metallb for giving external access. The problem is, during the setup process of metallb, I am asked to give a range of available IP addresses.

The hosting provider I am using is very basic, and all I have is the IP address of the Linux instance that is running my K8s node. So my question is, how can I provision an IP address for assigning to my application? Is this possible with a single IP?

Alternatively I'd love get this done with a NodePort, but I need to support HTTPS traffic and I am not sure its possible if I go that way.

john
  • 1,561
  • 3
  • 20
  • 44
  • You can support https traffic on any port. You just need to include the port in the URL (`https://example.com:4321`). Additionally, once you have the service operating on a nodeport, you could set up a netfilter rule to map the service to port 443 if you don't already have something else listening on that port. – larsks Dec 20 '22 at 15:27
  • @larsks I just created a nodeport that exposes the service on port `31286` but only on HTTP. When I hit the same URL with HTTPS, I get `curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number` and does not load on the browser as well. Any idea why this is? – john Dec 20 '22 at 16:21
  • It sounds as if you're providing an HTTP service, not an HTTPS service. Assuming that's the case, you would obviously need to put something in front of your service that speaks HTTPS. – larsks Dec 20 '22 at 16:33

2 Answers2

2

Specify a single IP using CIDR notation. your-ip/32 (192.168.10.0/32 for example)

Ola Ekdahl
  • 1,484
  • 1
  • 11
  • 21
  • Is this the public IP of the K8s node? I am confused because one of the guides specifically said you cannot use the k8s node's public IP with metallb. – john Dec 21 '22 at 18:28
  • @john this is from the guide you linked "You can set your public IPs right away or your private network with additional forwarding. This time you can use the same network as the host machine's." – Ola Ekdahl Dec 21 '22 at 19:39
  • Thanks. I used the local IP range as you suggested. Afterwards nginx is accessbile on the [server-ip]:[external-port-of-loadbalancer-service]. Now to figure out how to add SSL to nginx. – john Jan 02 '23 at 15:53
  • Check out this guide for nginx-ssl setup. https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes – Ola Ekdahl Jan 03 '23 at 19:21
0

Single IP Address Load Balancer

Using a single IP address is possible. In this case you don't need the speaker pods that announce the external IP addresses and thus no pod security labels. So, if you install using helm, prepare a metallb-values-helm.yaml file:

speaker:
  enabled: false

Then install metallb:

kubectl create namespace metallb-system
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system -f metallb-values-helm.yaml

Now prepare a configuration of the public IP address in a metallb-config-ipaddress.yaml file:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: metallb-ip
  namespace: metallb-system
spec:
  addresses:
  # The IP address of the kubernetes master node
  - 192.168.178.10/32

And apply:

kubectl apply -f metallb-config-ipaddress.yaml

Multiple Services Sharing the Same IP Address

This should already work for a single service. However, if you want to apply multiple services on different ports of the same IP address, you need to provide an annotation in every service manifest, as described here. A service manifest will look like:

apiVersion: v1
kind: Service
metadata:
  name: cool-service
  namespace: default
  annotations:
    metallb.universe.tf/allow-shared-ip: "key-to-share-192.168.178.10"
...

The string "key-to-share-192.168.178.10" is arbitrary, but must be equal for all services. If there is really just a single IP address in your pool (as specified above), you don't have to specify it as loadBalancerIP: 192.168.178.10. This would be only required if you had multiple IP addresses and wanted to select one. So that's all.

What's next?

You can also use nginx-ingress as ingress controller behind your metallb load balancer, which is still required to expose the nginx-ingress service. Then you can e. g. separate your services via subdomains (pointing to the same IP address) like

  • service1.domain.com
  • service2.domain.com
John
  • 1,472
  • 1
  • 19
  • 22