MetalLB二层模式使用指南
2022-8-8
测试组件的版本情况 #
- kubernetes: v1.22.8
- metellb: v0.10.3
- nginx: latest
创建测试应用 #
创建一个nginx服务和service资源:
kubectl -n without-istio create deploy nginx --image=nginx
测试分配IP #
创建loadbalancer类型的service:
kubectl -n without-istio create service loadbalancer nginx --tcp=80:80
查看该service详细配置:
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
namespace: without-istio
name: nginx
...
spec:
allocateLoadBalancerNodePorts: true
clusterIP: 10.233.15.89
clusterIPs:
- 10.233.15.89
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: 80-80
nodePort: 30662
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 10.206.65.234
可以发现external-ip已经完成分配.
在同一个局域网内, 使用curl命令测试联通情况:
可以看到, 是可以正常访问的.
手动指定地址池 #
默认, metallb会从所有的可用地址池中分配IP, 除非我们关闭某一个地址池的自动分配auto-assign: false
.
metallb v0.12之前都是用configmap进行配置, 而不是用CRD. 这里是 配置相关文档.
下面我们让集群中有两个地址池, 其中一个关闭自动分配. 修改metallb的配置文件, 增加一个address-pools(expensive), 地址范围10.206.65.224-10.206.65.233, 如下:
kubectl -n metallb-system edit cm config
可以看到目前有两个地址池, 同时配置auto-assign: false
来关闭对expensive地址池的自动分配. 配置完毕之后, metallb会重新加载配置文件, 不需要重启它.
下面创建一个指定地址池(loadbalanced-manual)的service, 我们看能否正确分配地址:
kubectl create -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-manual
namespace: without-istio
annotations:
metallb.universe.tf/address-pool: expensive
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
EOF
继续查看刚创建的service, 发现IP地址已经成功分配, 而且地址范围也符合预期:
经测试访问正常:
手动指定IP #
现在我们看nginx-manual的external-ip是:
下面我手动将其ip指定为10.206.65.225
, 使用如下命令:
kubectl -n without-istio patch service nginx-manual -p '
{
"spec": {
"loadBalancerIP": "10.206.65.225"
}
}'
请看发生的变化:
可见external-ip地址按照我们的要求发生了变化. 下面测试下请求连通性:
访问正常.
当地址池IP不够用时 #
当前expensive
地址池只有两个IP地址:
这两个地址已经被service占用:
下面指定该地址池, 创建第三个service, 我们看看会发生什么
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
annotations:
metallb.universe.tf/address-pool: expensive
name: nginx-manual-2
namespace: without-istio
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
EOF
我们发现, 该service的EXTERNAL-IP处于pending
状态, 并且会看到一条Warning级别的事件, 提示地址池中没有可分配的IP了.
因此, 当地址池中IP数量不够用的时候, Service的EXTERNAL-IP会处于挂起状态, 并发送事件提示地址池中无可分配IP地址.