官方文档:MetalLB, bare metal load-balancer for Kubernetes (universe.tf)

1、kube-proxy ipvs模式开启ARP

kubectl edit configmap -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

或者手动设置

# 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

2、安装MetalLB

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

3、创建ip地址池

cat > metallb-ip-pool.yaml << EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
  # 网段跟节点保持一致
  - 10.20.12.190-10.20.12.200
  # 自动分配可用地址,默认false
  autoAssign: true
  # 高级使用,指定命名空间或服务使用ip地址池
  # serviceAllocation:
  #   priority: 50
  #   # 指定default、portal命名空间下所有service可用
  #   namespaces:
  #   - default
  #   - portal
  #   # 指定在任意命名空间下有foo: bar标签的所有service可用
  #   namespaceSelectors:
  #   - matchLabels:
  #     foo: bar
  #   # 指定在任意命名空间下service中包含app: bar标签可用
  #   serviceSelectors:
  #   - matchExpressions:
  #     - {key: app, operator: In, values: [bar]}
EOF
​
kubectl apply -f metallb-ip-pool.yaml

此时以及ip地址已经可用,但为了标准化和未来更多的功能,需要创建L2Advertisement

4、通告服务IPs(Layer 2 模式)


cat > layer2.yaml << EOF
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metallb-system
spec:
  ipAddressPools:
  # 指定ip地址池
  - default
  # 高级使用:指定网络接口,默认情况下,metallb 会从节点的所有网络接口播报 LoadBalancer IP
  interfaces:
  - ens192
  # 高级使用:将地址池在指定节点中通告,注释掉默认在所有节点中通告,注意L2模式最终都是在可用节点中选择一个节点通告IP地址池
  # nodeSelectors:
  # - matchLabels:
  #     kubernetes.io/hostname: k8s-node01
  # - matchLabels:
  #     kubernetes.io/hostname: k8s-node02
EOF
​
kubectl apply -f layer2.yaml

验证

外部访问 EXTERNAL-IP 即可。