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

1、kube-proxy ipvs模式开启ARP

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

或者手动设置

1
2
3
4
5
6
7
8
9
# 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

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

3、创建ip地址池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 模式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

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 即可。