准备部署一个 cilium load-balancer service 作为 control-plane 的负载均衡,k8s 集群是用阿里云 ecs 自己搭建的
cilium 安装命令
cilium install --version 1.18.1 \
--namespace kube-system \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true \
--set l2announcements.enabled=true \
--set l2NeighDiscovery.enabled=true \
--set externalIPs.enabled=true
部署清单文件如下:
LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
annotations:
io.cilium/lb-ipam-ips: 172.21.48.240
labels:
component: kube-apiserver
tier: control-plane
name: kube-api
namespace: kube-system
spec:
selector:
component: kube-apiserver
tier: control-plane
ports:
- name: https
port: 6443
protocol: TCP
targetPort: 6443
type: LoadBalancer
CiliumLoadBalancerIPPool
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
name: api-server
annotations:
spec:
blocks:
- cidr: "172.21.48.240/28"
CiliumL2AnnouncementPolicy
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
name: control-plane
spec:
serviceSelector:
matchLabels:
component: apiserver
provider: kubernetes
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
loadBalancerIPs: true
externalIPs: true
部署后,加入集群的节点服务器都能访问负载均衡 172.21.48.240 的 6443 端口,但没有加入集群的服务器都不能访问,请问如何解决这个问题?
从您描述的情况来看,问题可能出在 L2 公告策略的配置上,导致未加入集群的服务器无法学习到负载均衡 IP 的 MAC 地址映射。以下是具体解决方法:
修正 CiliumL2AnnouncementPolicy 的标签选择器
您当前的服务标签是component: kube-apiserver,但公告策略中匹配的是component: apiserver,存在标签不匹配的问题。
修改后的 CiliumL2AnnouncementPolicy:
yaml
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
name: control-plane
spec:
serviceSelector:
matchLabels:
component: kube-apiserver # 修正为与Service匹配的标签
tier: control-plane # 增加tier标签匹配
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
loadBalancerIPs: true
externalIPs: true
确保 IP 地址在正确的网络范围内
检查 172.21.48.240 是否与未加入集群的服务器在同一个二层广播域(同一子网)。如果不在同一子网,需要:
将负载均衡 IP 更改为与目标服务器相同子网的 IP
或者在网络设备上配置路由,将该 IP 段路由到集群节点
验证网络策略和安全组
确保阿里云 ECS 的安全组规则允许 6443 端口的访问,并且没有网络 ACL 阻止流量。
应用修改后,执行以下命令使其生效:
bash
kubectl apply -f your-updated-l2-policy.yaml
kubectl rollout restart daemonset/cilium -n kube-system
这些修改应该能让 L2 公告正确工作,使同一广播域内的非集群服务器也能访问负载均衡 IP。
感谢提醒,的确没注意到 serviceSelector 存在的问题,我找时间用下面的 matchLabels 验证一下。这是 AI 回答的吧
spec:
serviceSelector:
matchLabels:
component: kube-apiserver
tier: control-plane
@dudu: 嗯,豆包回答的。但我看了下,两者的标签选择器的确不一致。您可以试试看修改一致后能否解决这个问题。
@华哥来也: 实验成功,就是这个原因引起,AI 可以帮助发现低级错误
@华哥来也: 当时验证时弄错了,后来发现阿里云 ECS 云服务器不支持 L2 Announcements,详见 https://q.cnblogs.com/q/155433