K8s部署Flask应用无法从控制平面、本地笔记本访问问题咨询
问题背景
- 本地笔记本:IP 192.168.12.85,网关192.168.1.254
- K8s控制平面节点:主机名bino-k8-master,IP 192.168.1.66,网关192.168.1.247
- K8s工作节点:主机名bino-k8-wnode1,IP 192.168.1.67,网关192.168.1.247
- 集群基于Ubuntu 20、containerd搭建,已部署简易Flask应用
现有运行状态
Pod运行状态
ubuntu@bino-k8-master:~$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES flask-k8s-deployment-59bd54648c-jdgxv 1/1 Running 0 16h 10.244.1.8 bino-k8-wnode1 <none> <none>
Service运行状态
ubuntu@bino-k8-master:~$ kubectl get services -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR flask-k8s-service LoadBalancer 10.96.179.198 <pending> 6000:30787/TCP 17h app=flask-k8s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h <none>
故障表现
- 工作节点内执行curl访问Pod地址
http://10.244.1.8:5000、Service地址http://10.96.179.198:6000可正常返回响应 - 控制平面节点执行上述curl请求直接卡住无响应
- 本地笔记本无法访问集群内部署的Flask应用
- LoadBalancer类型Service的EXTERNAL-IP持续处于
<pending>状态
根因说明
- 控制平面节点无法访问跨节点Pod、ClusterIP Service,核心原因是集群内核转发参数未正确配置、CNI网络插件组件在控制平面节点运行异常,或者kube-proxy未正确下发跨节点路由与iptables规则。
- 裸金属自建K8s集群没有云厂商提供的LoadBalancer控制器,因此LoadBalancer类型Service不会自动分配外部访问IP,无法直接对外暴露服务。
- 本地笔记本与K8s节点分属不同网段(192.168.12.0/24、192.168.1.0/24),需先保证两个网段三层路由可达才能正常访问。
解决方案
步骤1:修复控制平面节点跨节点网络访问
- 在所有集群节点(控制平面+工作节点)执行以下命令,开启K8s要求的内核转发参数:
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sudo sysctl --system
- 检查CNI网络插件的运行状态,所有节点上的CNI组件Pod必须处于Running状态,若控制平面节点对应的CNI Pod异常,直接删除异常Pod等待自动重建即可。
- 重启kube-proxy组件,强制重新下发路由与iptables规则:
kubectl rollout restart daemonset kube-proxy -n kube-system
- 验证修复结果:在控制平面节点执行
ip route,确认存在指向工作节点Pod网段(10.244.1.0/24)的路由,下一跳为工作节点IP 192.168.1.67;重新curl Pod与Service地址,确认可正常返回响应。
步骤2:配置外部访问,实现本地笔记本访问Flask应用
先做基础连通性校验:在本地笔记本ping两个K8s节点IP 192.168.1.66、192.168.1.67,如果ping不通先排查两个网段网关的路由配置,保证三层可达。
两种暴露方案选其一即可:
方案A:使用NodePort类型Service(部署最快,无额外组件依赖)
- 修改现有Service类型:
kubectl patch service flask-k8s-service -p '{"spec":{"type":"NodePort"}}'
- 查看Service返回结果,记录端口映射中暴露的NodePort端口(当前配置中为30787)。
- 在所有集群节点执行命令,放开NodePort端口段的防火墙规则:
sudo ufw allow 30000:32767/tcp
- 本地笔记本直接访问
http://192.168.1.66:30787或http://192.168.1.67:30787即可打开Flask应用。
方案B:部署MetalLB实现裸金属LoadBalancer(与云环境使用体验一致)
如果需要保留LoadBalancer类型Service的使用逻辑,部署开源裸金属LoadBalancer实现MetalLB即可:
- 安装MetalLB核心组件
- 配置与K8s节点同网段的闲置IP段作为LoadBalancer地址池(例如192.168.1.200~192.168.1.210)
- 配置完成后flask-k8s-service会自动分配到同网段的EXTERNAL-IP,本地笔记本直接访问该IP的6000端口即可。
内容的提问来源于stack exchange,提问作者Bino Oetomo
相关产品推荐
相关产品推荐

