Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MetalLB External IP to Internet

I can't access to public IP assigned by MetalLB load Balancer

I created a Kubernetes cluster in Contabo. Its 1 master and 2 workers. Each one has its own public IP.

I did it with kubeadm + flannel. Later I did install MetalLB to use Load Balancing.

I used this manifest for installing nginx:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1
        ports:
        - name: http
          containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

It works, pods are running. I see the external IP adress after:

kubectl get services

enter image description here From each node/host I can curl to that ip and port and I can get nginx's:

<h1>Welcome to nginx!</h1>

So far, so good. BUT:

What I still miss is to access to that service (nginx) from my computer. I can try to access to each node (master + 2 slaves) by their IP:PORT and nothing happens. The final goal is to have a domain that access to that service but I can't guess witch IP should I use.

What I'm missing?

Should MetalLB just expose my 3 possible IPs? Should I add something else on each server as a reverse proxy?

I'm asking this here because all articles/tutorials on baremetal/VPS (non aws,GKE, etc...) do this on a kube on localhost and miss this basic issue.

Thanks.

like image 415
dasHannon Avatar asked Jul 18 '19 17:07

dasHannon


People also ask

How does metallb assign an IP address to a user?

MetalLB assigns an IP address from these address pools. To accept any IP address from any pool that is configured for automatic assignment, no special annotation or configuration is required. By default, services do not share IP addresses.

How does metallb handle load-balancers?

Like some other load-balancer implementations, MetalLB accepts the spec.loadBalancerIP field in the service specification. If the requested IP address is within a range from any address pool, MetalLB assigns the requested IP address. If the requested IP address is not within any range, MetalLB reports a warning.

What are the prerequisites for metallb?

There are a few prerequisites for MetalLB which you should take a look at before installing. One of them are the Network provider (CNI). Most CNI's should work, but not all are tested. TCE uses Antrea which is not tested by MetalLB, but in my use-cases I have not seen any issues.


2 Answers

I am having the very same hardware layout:

  • a 3-Nodes Kubernetes Cluster - here with the 3 IPs: | 123.223.149.27 | 22.36.211.68 | 192.77.11.164 |
  • running on (different) VPS-Providers (connected to a running cluster(via JOIN), of course)

Target: "expose" the nginx via metalLB, so I can access my web-app from outside the cluster via browser via the IP of one of my VPS'

Problem: I do not have a "range of IPs" I could declare for the metallb

Steps done:

  1. create one .yaml file for the Loadbalancer, the kindservicetypeloadbalancer.yaml
  2. create one .yaml file for the ConfigMap, containing the IPs of the 3 nodes, the kindconfigmap.yaml

``

### start of the kindservicetypeloadbalancer.yaml
### for ensuring a unique name: loadbalancer name nginxloady

apiVersion: v1
kind: Service
metadata:
  name: nginxloady
  annotations:
    metallb.universe.tf/address-pool: production-public-ips
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

``

below, the second .yaml file to be added to the Cluster:

    # start of the kindconfigmap.yaml
    ## info: the "production-public-ips" can be found 
    ## within the annotations-sector of the kind: Service type: loadbalancer / the kindservicetypeloadbalancer.yaml 
    ## as well... ...namespace: metallb-system & protocol: layer2 
    ## note: as you can see, I added a /32 after every of my node-IPs

 
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: production-public-ips
      protocol: layer2
      addresses:
      - 123.223.149.27/32
      - 22.36.211.68/32
      - 192.77.11.164/32 

``

  • add the LoadBalancer:

    kubectl apply -f kindservicetypeloadbalancer.yaml

  • add the ConfigMap:

    kubectl apply -f kindconfigmap.yaml

  • Check the status of the namespace ( "n" ) metallb-system:

    kubectl describe pods -n metallb-system

PS: actually it is all there: https://metallb.universe.tf/installation/

and here: https://metallb.universe.tf/usage/#requesting-specific-ips

like image 84
flowfab Avatar answered Oct 20 '22 23:10

flowfab


What you are missing is a routing policy

Your external IP addresses must belong to the same network as your nodes or instead of that you can add a route to your external address at your default gateway level and use a static NAT for each address

like image 43
Amine Bouzid Avatar answered Oct 20 '22 21:10

Amine Bouzid