ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于MetalLB的Kubeedge CloudCore负载均衡部署实践

基于MetalLB的Kubeedge CloudCore负载均衡部署实践 简介面向Kubeedge初学者与边缘计算实践者的部署资源包基于CentOS 7.9、K8s v1.22.17kubeadm与Kubeedge v1.13.1搭建链路整合MetalLB负载均衡器解决边缘节点接入、Service LoadBalancer暴露及集群验证等常见问题。包内共15个文件YAML部署清单覆盖Calico网络、MetalLB配置与测试应用Docker镜像tar包提供Kubeedge相关组件及测试所需镜像另有Markdown部署说明与keadm离线安装工具整体约474.64MB便于离线环境使用压缩包内目录划分清晰可快速定位所需配置或镜像。已有242人学习适合想按完整部署链路复现环境、减少版本匹配踩坑的入门用户。随包文档从系统准备、K8s集群部署、Kubeedge安装、MetalLB配置到测试实例与结果验证依次展开并备齐所需镜像和配置清单能够降低自行搜集组件与排查兼容问题的时间成本按步骤操作即可搭建一套可用的Kubeedge边缘计算环境。1. 这套组合的定位给边缘节点一个真正可用的云端入口做云边协同的人大多被同一个问题卡过云端 K8s 集群搭好了Kubeedge 的 CloudCore 也装上去了但边缘节点拿着 IP 和 token 怎么都连不上。你绕开 LoadBalancer改用 NodePort 或者直接把进程跑在宿主机上能连上是能连上可生产环境一次重启、一次迁移就把你打回原形。CentOS 7.9 加 K8s v1.22.17 加 Kubeedge v1.13.1 这条组合线看起来版本老实际是边缘现场最能落地的搭配系统资源占用低内核习惯接近传统运维而 v1.13.1 的 Kubeedge 正好还支持用 LoadBalancer 把 CloudCore 的 WebSocket 通道做成稳定入口。适合正在搭边缘网关、想把设备数据汇聚到云端的集群运维和开发人员。这篇文章会照着这条线把环境、组件、负载均衡器配置和排错讲完。2. CentOS 7.9 上的 K8s v1.22.17先让集群稳定再谈边缘2.1 系统初始化参数内核和网络是 CentOS 7.9 集群的命门CentOS 7.9 用 3.10 内核平时跑传统服务没什么感觉一旦上 K8siptables、cgroup 和网络插件会接连给你颜色看。我一般会在三台机器或单机 All-in-One 上做最小化初始化以下参数是跑 K8s v1.22.17 之前必须处理的。# 关闭 swapK8s 强制要求 swapoff -a sed -i s/.*swap.*/#/ /etc/fstab # 加载内核模块 cat /etc/modules-load.d/k8s.conf EOF overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # 网络转发与 iptables 桥接流量 cat /etc/sysctl.d/k8s.conf EOF net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 EOF sysctl --system这段逻辑不复杂swapoff -a让 kubelet 的资源计算不再被交换分区干扰br_netfilter是保证 K8s 的 Service 和 Pod 网络能把 bridge 上的数据包送到 iptables 规则链里。CentOS 7.9 默认net.bridge.bridge-nf-call-iptables是关闭的如果你不打开后面 LoadBalancer 转发流量时会丢包查找问题能找出一身汗。建议顺手把机器时间同步打开因为 Certificates 的签发和校验对时间敏感边缘节点和云端时间差超过 5 分钟证书大概率直接不可用。2.2 用 kubeadm 锁定版本为什么是 v1.22.17 而不是 v1.23K8s v1.22.17 是 1.22 系列的最后一个补丁版本和 CentOS 7.9 的兼容性是把一些列升级包按保守组合压出来的。更高版本的 kubelet 对 cgroup v2 和 glibc 有更激进的默认值在 CentOS 7 上经常出现 Pod 启动后立刻被 OOMKilled或者 kubelet 报unsupported systemd version。锁版本的正确办法是安装时指定完整版本号。# 配置阿里云镜像源vault 源在 CentOS 7.9 上也存在 cat /etc/yum.repos.d/kubernetes.repo EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled1 gpgcheck0 EOF yum install -y kubeadm-1.22.17-0 kubelet-1.22.17-0 kubectl-1.22.17-0 systemctl enable --now kubelet这里把gpgcheck0是为了避开公网 GPG 密钥在离线环境失效的问题。安装后先不急着 init建议先拉取镜像再初始化避免初始化时因为镜像拉取超时导致集群半成品。kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.22.17 kubeadm init \ --kubernetes-version v1.22.17 \ --apiserver-advertise-address192.168.10.10 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/16常见做法是先用一个内网地址做 apiserver 的 advertise address之后部署 CNI 插件这里我推荐 Flannel v0.19 或 Calico v3.22二者在 1.22 上都有成熟参数。先确认集群 Ready再继续往下走否则 Kubeedge 的故障排查会叠着 K8s 自身的网络故障很难定位。2.3 CentOS 7.9 的存储和镜像仓库几个先决参数CentOS 7.9 默认/分区常常只有 50GBK8s 组件加 Kubeedge 镜像很容易撑满。如果磁盘不够在初始化前把根分区扩容掉避免中途kubeadm init因为磁盘写满失败。另一个容易被忽略的点是容器运行时。Kubeedge v1.13.1 的 EdgeCore 在边缘侧需要访问 containerd 或 Docker建议统一用 containerd并配置SystemdCgroup与 kubelet 的 cgroup driver 保持一致。3. Kubeedge v1.13.1 部署CloudCore 和 EdgeCore 的配对关系3.1 下载 keadm 与 CloudCore 的证书策略Kubeedge v1.13.1 的部署工具叫keadm它负责在云端初始化 CloudCore在边缘侧注册 EdgeCore。下载之后先把keadm放到/usr/local/bin并给执行权限。初始化前要决定两个参数CloudCore 的advertise-address和加密端口。这里的 advertise address 不是随便填EdgeCore 会把--cloudcore-ipport指向这个地址如果填错边缘侧握手阶段直接 fail。# 在云端机器上执行 keadm init \ --advertise-address192.168.10.10 \ --kubeedge-versionv1.13.1 \ --cloudcore-imagekubeedge/cloudcore:v1.13.1 \ --set cloudCore.modules.cloudHub.enabletrue这段命令会生成 CloudCore 的 DaemonSet 或 Deployment 资源并自动签发证书。注意advertise-address这个 IP 的作用是让 CloudCore 把证书里的 IP SAN 和地址一起公布出去。如果你后面要换成 LoadBalancer 的外部 IP这里就存在一个隐患证书里的 SAN 不包含 LB IP。所以更稳的做法是先不填最终 IP等 LoadBalancer 地址确定后再重新生成证书或者直接给 CloudCore 签发带多个 IP 的证书。别嫌麻烦证书问题在边缘侧几乎无法排查日志只显示failed to websocket connection。3.2 CloudCore 负载均衡化的第一步确认端口与模块CloudCore 里承担边缘连接的是 CloudHub 模块默认监听 10000 端口做 WebSocket10002 端口做 QUIC。如果边缘侧网络设备只会放行 TCP那就只暴露 10000。初始化完成后用kubectl get svc -n kubeedge查看 CloudCore 服务是否存在。kubectl get svc -n kubeedge -o wide kubectl logs -n kubeedge -l kubeedgecloudcore --tail50Kubeedge v1.13.1 在初始化时通常不会自动创建 LoadBalancer 类型的 Service默认可能是 ClusterIP。你需要手动把 Service 类型改成 LoadBalancer背后的原理是让 K8s 通过云控制器或 MetalLB 这类组件分配一个额外 IP并把 CloudHub 的 10000 端口映射上去。很多教程在这里直接跳过导致边缘节点只能连到 ClusterIP边缘侧一旦不在集群内网就永远连不上。这一步是整套方案踩坑率最高的地方。3.3 获取 token 与边缘侧加入命令CloudCore 初始化完成后需要在云端生成一个 token边缘节点加入时使用。Kubeedge 的 token 机制是一次性的默认有效期 24 小时生产环境建议配置持久 token或者把 token 放在边缘侧的配置文件中。keadm gettoken返回的 token 是加密字符串。边缘节点执行加入命令这里的关键参数是--cloudcore-ipport它必须是 LoadBalancer 暴露出的 IP 和端口不能填 CloudCore 所在机器的内网 IP。keadm join \ --cloudcore-ipport192.168.20.100:10000 \ --token你的token \ --kubeedge-versionv1.13.1 \ --cgroupdriversystemd \ --remote-runtime-endpointunix:///var/run/containerd/containerd.sock加入完成后在云端执行kubectl get nodes应该能看到边缘节点以edge-worker的角色出现。如果节点状态是 NotReady多半是 CloudCore 侧证书和地址不匹配或边缘侧无法解析 LoadBalancer 的 IP后面避坑章节专门讲。4. 用 LoadBalancer 暴露 CloudCoreMetalLB 服务与参数调整4.1 裸机环境为什么选 MetalLBKubeedge 的 CloudCore 是部署在云端的 Pod边缘节点通过公网或专线访问它。云端集群如果是自建机房的裸机环境没有云厂商的 LB 组件就需要一个能在二层或三层网络上宣告虚拟 IP 的工具。MetalLB 是使用最广的方案它有两种模式BGP 和 L2。CentOS 7.9 K8s v1.22.17 下面我推荐 L2 模式因为 BGP 还需要额外对接交换机L2 模式只要确保 VIP 所在网段与边缘节点可达即可。安装 MetalLB 的常见做法是kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml注意K8s v1.22.17 的 API 版本和 MetalLB v0.13.x 的 CRD 是匹配的。更高版本的 MetalLB 可能需要 K8s v1.23 以上的 feature gate反而翻车。安装完成后要创建配置清单。4.2 MetalLB 的 L2 配置与 strictARPapiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: cloudcore-pool namespace: metallb-system spec: addresses: - 192.168.20.200-192.168.20.220apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: cloudcore-l2 namespace: metallb-system spec: ipAddressPools: - cloudcore-poolIPAddressPool 定义了 LoadBalancer 可分配的 IP 范围。这里有一个关键前提这个网段必须和边缘节点路由可达而且不能让 DHCP 分配池和 MetalLB 的池重叠否则两个设备抢同一个 IP负载均衡器就成了玄学。L2Advertisement 告诉 MetalLB 以 ARP 应答的方式宣告 VIP。还要修改 kube-proxy 的 strictARP 参数因为 MetalLB L2 模式依赖 kube-proxy 不去竞争 VIP 的 ARP 响应。kubectl get configmap -n kube-system kube-proxy -o yaml kube-proxy-cm.yaml sed -i s/strictARP: false/strictARP: true/ kube-proxy-cm.yaml kubectl apply -f kube-proxy-cm.yaml kubectl rollout restart daemonset kube-proxy -n kube-system这里把strictARP打开否则 MetalLB 收到 ARP 请求时kube-proxy 也会尝试应答VIP 的流量到不了 CloudCore。4.3 CloudCore Service 改为 LoadBalancer配置 externalTrafficPolicy 与端口CloudCore 默认 Service 大概是 ClusterIP手动改掉它。apiVersion: v1 kind: Service metadata: name: cloudcore namespace: kubeedge annotations: metallb.universe.tf/allow-shared-ip: cloudcore spec: type: LoadBalancer loadBalancerIP: 192.168.20.200 selector: kubeedge: cloudcore ports: - port: 10000 targetPort: 10000 protocol: TCP name: cloudhub - port: 10002 targetPort: 10002 protocol: TCP name: cloudhub-quic externalTrafficPolicy: Local上面把 Service 的loadBalancerIP固定为地址池里的192.168.20.200。固定 IP 的意义是让 CloudCore 重启、重建后地址不变边缘节点的配置也不用跟着改。externalTrafficPolicy: Local则保证了 CloudCore 的 Pod 在哪台机器流量就到哪台机器不经过 SNAT。这样做的好处是边缘节点看到的连接源 IP 就是真实 IP便于后续做设备维度的访问控制。代价是如果 CloudCore 的 Pod 被调度走了VIP 会临时不可用所以实际部署时可以给 CloudCore 加一个 NodeSelector或者多副本跑两个实例。创建后验证kubectl get svc -n kubeedge cloudcore -o wide如果EXTERNAL-IP显示192.168.20.200说明 MetalLB 已经把这个 IP 接管了。接着在边缘节点上 ping 和 telnet 一下确认端口通。ping -c 3 192.168.20.200 nc -vz 192.168.20.200 10000只要网络可达EdgeCore 的加入命令里就可以放心把这个 IP 填进去。5. CentOS 7.9 上的排错与避坑版本、内核和网络模式5.1 EdgeCore 连接 CloudCore 一直 connection refused现象边缘节点执行keadm join后一直提示failed to connectCloudCore 日志里没有任何报错边缘节点日志里只有connection refused。原因最常见的是 CloudCore Service 的端口没有正确暴露。用kubectl get svc -n kubeedge cloudcore看 EXTERNAL-IP如果是none说明 LoadBalancer 分配失败。另外如果用了 NodePort 临时替代边缘侧和云端必须保证端口一致而且不能有中间防火墙拦截。解决先确认 MetalLB 的 IPAddressPool 是否还有空闲地址然后看 CloudCore 的 Pod 日志里cloudhub模块是否真的监听在 10000。执行kubectl logs -n kubeedge -l kubeedgecloudcore如果看到failed to load certificate就要连带检查证书 SAN 中是否包含 VIP 地址。5.2 MetalLB 分配了 IP 但 ARP 不通现象EXTERNAL-IP有值但边缘节点ping不通nc也不通在云端机器上却能通。原因L2 模式要求 MetalLB 的 Pod 和 CloudCore 的 Service 流量都在同一二层网络内。CentOS 7.9 默认防火墙 open 了端口但没有允许 ARP 协议。如果边缘节点和 VIP 在同一网段但 ARP 请求被 firewalld 丢弃也会导致 ping 不通。解决在云端节点打开 ARP 相关规则或者直接关闭 firewalld。systemctl disable --now firewalld systemctl restart network生产环境如果必须保留防火墙就只放行 CloudCore 端口和 ARP 协议。这个坑最隐蔽因为从云端本机连 VIP 时流量走 lo不经过 ARP所以常被误判为 MetalLB 配置正常。5.3 Kubeedge v1.13.1 在 K8s v1.22.17 上缺少 CRD 和 RBAC现象keadm init执行完后CloudCore 的 Pod 一直 CrashLoopBackOff日志报failed to list configmaps或failed to create leader election lock。原因Kubeedge v1.13.1 安装包里的 CRD 和 RBAC 通过keadm init创建时不一定覆盖了 K8s v1.22 的所有资源权限。特别是cloudcore需要访问configmaps、leases、nodes如果 RBAC 没有授权就会一直因为权限失败退出。解决从 Kubeedge 发布包中的build目录里手动应用crds和rbac然后再重启 CloudCore。kubectl apply -f build/crds/ kubectl apply -f build/rbac/ kubectl rollout restart deployment -n kubeedge cloudcore遇到这种情况别急着调网络参数先看日志里有没有Forbidden字样Kubeedge 的权限问题比网络问题好处理但容易误导排查方向。5.4 edgecore 加入后节点一直 NotReady现象边缘节点已经加入kubectl get nodes能看到边缘节点但状态始终NotReady在边缘节点查看 EdgeCore 日志报failed to sync pod status。原因边缘节点与云端之间的 WebSocket 连接虽然通了但 EdgeCore 上报 Pod 状态时依赖 Kubelet 的运行时如果边缘节点的容器运行时 socket 配置不对CloudCore 无法拿到 Pod 状态。CentOS 7.9 上如果把 Docker 和 containerd 混装--remote-runtime-endpoint填错了就会出现这种问题。解决明确边缘节点用 containerd 还是 Docker二者选一。使用 containerd 时必须确保containerd.sock存在且 EdgeCore 的配置里remote-runtime-endpoint与 socket 路径一致。加入命令加上--remote-runtime-endpoint参数后重启 edgecore 服务。5.5 token 过期与证书轮换现象边缘节点第一次加入成功后后来因为网络断开重连发现要重新加入旧的 token 失效。原因Kubeedge 默认生成一次性 token过期后 EdgeCore 的证书无法续期手里没有永久 token 就只能重新生成。解决在 CloudCore 的配置中把 token 的有效期改长或者使用--token参数配合证书轮换。一般在初始化时设置--set cloudCore.modules.cloudHub.authTokenExpirationSeconds31536000让 token 一年有效。这一步是后来才加的我在第一次搭的时候就吃过一次亏边缘设备装好后没法再到现场重新输入 token提前把 token 写死到配置文件里才能安心。6. 验证边缘节点与云端负载从节点 Ready 到 Pod 下发最后把整套链路验证一遍。云端执行kubectl get nodes和常用 K8s 命令确认边缘节点 Readykubectl get nodes -o wide kubectl get pods -n kubeedge -o wide kubectl logs -n kubeedge -l kubeedgecloudcore --tail30在边缘节点上查看 edgecore 服务的活跃状态然后部署一个测试 Pod指定调度到边缘节点kubectl run edge-test --imagebusybox --overrides{spec:{nodeSelector:{node-role.kubernetes.io/edge-worker:}}} -- sleep 3600 kubectl get pods -o wide | grep edge-test如果 Pod 能 Running说明从 CloudCore 到 EdgeCore 的 Pod 下发链路是通的。实际生产里我还会加一条额外验证从边缘节点反方向访问 CloudCore 暴露的 10000 端口确认 WebSocket 连接重启后不会断。这个可以通过反复重启 edgecore 来模拟只要边缘节点能在云端看到正常心跳就可以收工。进阶做法是把 CloudCore 的 LoadBalancer Service 再做一次固定 IP 绑定。如果没有条件部署 MetalLB也可以绕开 LoadBalancer直接在 Service 上写externalIPs把宿主机 IP 暴露出去。这个方案少了一层 LB但少了一堆 ARP 和 strictARP 的坑spec: type: ClusterIP externalIPs: - 192.168.20.100 ports: - port: 10000 targetPort: 10000externalIPs和 LoadBalancer 的区别在于它没有健康检查IP 不可达时也不会自动漂移。如果你只有单台 CloudCore这个简化方案反而更稳定。但要做多副本和故障转移老老实实用 LoadBalancer。我希望你第一次搭就把 LoadBalancer 这一层吃透否则后期边缘节点多了每一次重连问题都会回到这个入口上。这套组合是我踩过很多坑后愿意留下的稳定路线希望帮到你。本文还有配套的精品资源点击获取
返回列表