k3s + MetalLB: metallb-controller Failed to allocate IP for "default/nginx": no available IPs

5.3k Views Asked by At

I created a k3s cluster and disabled the service loadbalancer & traefik. I installed metallb via a manifest file. Also, I created a ConfigMap for Metallb below named "config" with an address pool so I don't know why the metallb-controller is saying "no available ips".

ubuntu@mark:~$ k describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.43.29.17
IPs:                      10.43.29.17
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30584/TCP
Endpoints:                10.42.4.4:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason            Age   From                Message
  ----     ------            ----  ----                -------
  Warning  AllocationFailed  34s   metallb-controller  Failed to allocate IP for "default/nginx": no available IPs
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
      - name: default
    protocol: layer2
      addresses:
      - 192.168.136.206-192.168.136.209
2

There are 2 best solutions below

2
John On

Install the latest stable version:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml

Define an IPAddressPool

---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: nat
  namespace: metallb-system
spec:
  addresses:
    - 192.168.136.206-192.168.136.209
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: empty
  namespace: metallb-system
2
fflores On

You are using the ConfigMap while in the documentation it says that in newer versions you should not use it:

Previous versions of MetalLB are configurable via a configmap. However, starting from the version v0.13.0, it will be possible to configure it only via CRs. A tool to convert old configmaps to CRs is provided as a container image under quay.io/metallb/configmaptocrs.

I was doing the same thing, I had an old repo, where I used the ConfigMap, so I decided to reuse it, but than I read the documentation and followed the instructions from the MetalLB website.

From installation I executed the following commands:

kubectl edit configmap -n kube-system kube-proxy

# see what changes would be made, returns nonzero returncode if different
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system

# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml

, and then from the configuration I choose the Layer 2 Configuration setup. Add the code bellow in a file.yaml:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.240-192.168.1.250

, and then apply it using kubectl

kubectl apply -f file.yaml

After that every thing works well. I hope this answer would be helpful for those who used the old approach, correct me if I have misunderstood.