K8s实战: 用OpenELB破解Service外部访问难题

关于openelbl作为调度器实现k8s的Service的loadbalancer模式:

Kubernetes 原生不提供 LoadBalancer 类型 Service 的具体实现(尤其在裸机或私有云环境)。需要借助外部组件(如 OpenELB)来充当 4/7 层调度器,提供负载均衡能力,并能自动判断后端 Pod 的健康状态。

本文档记录了在 K8s 集群中部署 OpenELB 并测试 LoadBalancer Service 的完整过程及问题解决方法。

1.安装OpenELB

1.1下载资源清单

bash 复制代码
wget https://raw.githubusercontent.com/openelb/openelb/release-0.6/deploy/openelb.yaml

1.2应用

bash 复制代码
[root@k8s-master01 ~]# kubectl apply -f openelb.yaml

1.3 检验

bash 复制代码
[root@k8s-master01 ~]# kubectl get pod -n openelb-system 
NAME                                  READY   STATUS              RESTARTS   AGE
openelb-admission-create-8ndq2        0/1     ContainerCreating   0          12s
openelb-admission-patch-pn9n6         0/1     ContainerCreating   0          12s
openelb-controller-5cdcf556d4-rtvtg   0/1     ContainerCreating   0          12s
openelb-speaker-4plq6                 0/1     ContainerCreating   0          12s
openelb-speaker-b4qjf                 0/1     ContainerCreating   0          12s
openelb-speaker-c5hwc                 0/1     ContainerCreating   0          12s

2.配置 EIP(弹性 IP 地址池)

2.1 EIP 资源配置文件

yml 复制代码
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
    name: eip-sample-pool
    annotations:
      eip.openelb.kubesphere.io/is-default-eip: "true"
spec:
    address: 192.168.64.100-192.168.64.150	 # 可用的 IP 范围
    priority: 100
    namespaces:
      - test
      - default
    namespaceSelector:
      kubesphere.io/workspace: workspace
    disable: false
    protocol: layer2	# 使用二层协议(ARP/NDP)
    interface: ens160     # 指定网络接口           

2.2 应用 &故障解决

bash 复制代码
[root@k8s-master01 ~]# kubectl apply -f eip.yml 
Error from server (InternalError): error when creating "eip.yml": Internal error occurred: failed calling webhook "validate.eip.network.kubesphere.io": failed to call webhook: Post "https://openelb-controller.openelb-system.svc:443/validate-network-kubesphere-io-v1alpha2-eip?timeout=10s": dial tcp 10.7.129.16:443: connect: connection refused

原因是 OpenELB 的 Admission Webhook 无法正常提供服务,根本原因在于相关 Pod 未正常运行。

检测相关pod & 查看openelb-controller

bash 复制代码
[root@k8s-master01 ~]# kubectl get pod -n openelb-system 
NAME                                  READY   STATUS              RESTARTS   AGE
openelb-admission-create-8ndq2        0/1     ImagePullBackOff    0          6m32s
openelb-admission-patch-pn9n6         0/1     ErrImagePull        0          6m32s
openelb-controller-5cdcf556d4-rtvtg   0/1     ContainerCreating   0          6m32s
openelb-speaker-4plq6                 0/1     ContainerCreating   0          6m32s
openelb-speaker-b4qjf                 0/1     ContainerCreating   0          6m32s
openelb-speaker-c5hwc                 1/1     Running             0          6m32s


[root@k8s-master01 ~]# kubectl describe pod -n openelb-system openelb-controller-5cdcf556d4-rtvtg
.......

Events:
  Type     Reason       Age                From               Message
  ----     ------       ----               ----               -------
  Normal   Scheduled    7m                 default-scheduler  Successfully assigned openelb-system/openelb-controller-5cdcf556d4-rtvtg to k8s-master01
  Warning  FailedMount  48s (x11 over 7m)  kubelet            MountVolume.SetUp failed for volume "webhook-cert" : secret "openelb-admission" not found

解决问题(临时解决方案)

由于 Webhook 配置存在问题,导致 EIP 创建被拦截。可临时删除该 ValidatingWebhookConfiguration 以绕过校验

bash 复制代码
[root@k8s-master01 ~]# kubectl get validatingwebhookconfiguration | grep openelb
openelb-admission               1          8m3s
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# kubectl delete validatingwebhookconfiguration openelb-admission
validatingwebhookconfiguration.admissionregistration.k8s.io "openelb-admission" deleted

验证

bash 复制代码
[root@k8s-master01 ~]# kubectl apply -f eip.yml 
eip.network.kubesphere.io/eip-sample-pool created

[root@k8s-master01 ~]# kubectl get eip
NAME              CIDR                            USAGE   TOTAL
eip-sample-pool   192.168.64.100-192.168.64.150   

3.部署&测试 LoadBalancer Service

3.1 编辑资源清单

bash 复制代码
[root@k8s-master01 ~]# cat test_loadbalancer.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: loadbalancer-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: loadbalancer-container
          image: hb.reg.com/library/myapp:1.0	# 替换为实际可用镜像,这里是我是私人仓库
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-svc
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: myapp

3.2应用

bash 复制代码
[root@k8s-master01 ~]# kubectl apply -f test_loadbalancer.yml 

3.3检测

bash 复制代码
[root@k8s-master01 ~]# kubectl get eip,svc,pod
NAME                                        CIDR                            USAGE   TOTAL
eip.network.kubesphere.io/eip-sample-pool   192.168.64.100-192.168.64.150           

NAME                       TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE
service/kubernetes         ClusterIP      10.0.0.1      <none>           443/TCP        9d
service/loadbalancer-svc   LoadBalancer   10.10.18.79   192.168.64.100   80:32452/TCP   52s

NAME                                       READY   STATUS      RESTARTS   AGE
pod/loadbalancer-deploy-5c6f5f784d-lkvj2   1/1     Running     0          52s
pod/loadbalancer-deploy-5c6f5f784d-tls6p   1/1     Running     0          52s
pod/loadbalancer-deploy-5c6f5f784d-wtm7b   1/1     Running     0          52s

可用看到service的ip就是就是eip(IP地址池)设定的范围

bash 复制代码
[root@k8s-master01 ~]# curl 10.10.18.79
hello jock | welcome to nginx! | version 1.0
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-wtm7b
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-tls6p
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-lkvj2
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-wtm7b
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-tls6p
[root@k8s-master01 ~]# curl 10.10.18.79/hostname.html
loadbalancer-deploy-5c6f5f784d-lkvj2


[root@k8s-master01 ~]# curl 192.168.64.100/hostname.html
loadbalancer-deploy-5c6f5f784d-lkvj2
[root@k8s-master01 ~]# curl 192.168.64.100/hostname.html
loadbalancer-deploy-5c6f5f784d-wtm7b
[root@k8s-master01 ~]# curl 192.168.64.100/hostname.html
loadbalancer-deploy-5c6f5f784d-tls6p

可用看到3个pod轮询

可以在浏览器里面查看该EXTERNAL-IP

用了两个浏览器(谷歌/微软),本来应该有轮询效果的,是浏览器的机制问题,加载也不会变化。

浏览器开启 HTTP Keep‑Alive 复用 TCP 连接,K8s Service 轮询只在新建 TCP 连接时生效,同一个连接内所有请求固定发给同一个 Pod,所以刷新看不到轮询。

一些Tips:

值得注意的是,即使我们现在查看相关pod

bash 复制代码
[root@k8s-master01 ~]# kubectl get pod -n openelb-system 
NAME                                  READY   STATUS              RESTARTS   AGE
openelb-admission-create-8ndq2        0/1     ImagePullBackOff    0          35m
openelb-admission-patch-pn9n6         0/1     ImagePullBackOff    0          35m
openelb-controller-5cdcf556d4-rtvtg   0/1     ContainerCreating   0          35m
openelb-speaker-4plq6                 1/1     Running             0          35m
openelb-speaker-b4qjf                 1/1     Running             0          35m
openelb-speaker-c5hwc                 1/1     Running             0          35m

当前的 Speaker 已正常运行,即使 admission 和 controller 有问题,你的 LoadBalancer Service 仍然可以工作。因为:

  • Speaker:负责实际流量转发,已经正常工作
  • Controller:主要负责 IP 分配和状态管理
  • Admission:负责资源校验,已通过删除 webhook 绕过

如果你只需要基础功能,可以暂时忽略这些错误。但对于生产环境,建议解决所有组件的健康状态。

具体来说,结合本次实验:

Speaker是OpenELB的核心数据平面组件 ,它负责响应ARP请求将外部IP(如你实验中的192.168.64.100)绑定到节点MAC地址,并通过iptables/IPVS规则将到达该IP的流量负载均衡到后端Pod------这正是你实验中curl 192.168.64.100/hostname.html能够成功且轮询返回三个不同Pod名称的根本原因;而Controller仅负责初始的IP池管理和状态更新(你的EIP在创建时已分配好IP就不再需要它),Admission仅负责配置校验(你删除Webhook后配置已生效就无需它),这两个控制平面组件只在资源创建或变更时起作用,不影响已运行服务的流量转发,所以即便它们都异常,只要Speaker在运行,LoadBalancer Service就能正常工作。

相关推荐
星核0penstarry1 小时前
OpenAI 模型第三方网络安全评估事件解析:背景、原理与改进路径(2)
安全·web安全·云原生
java_logo10 小时前
Docker 部署 NetBox:轻松搭建 IPAM / DCIM 网络资产管理平台
docker·容器·轩辕镜像·netbox部署·netbox部署方案·netbox部署文档·docker部署netbox
PC2005-cloud10 小时前
从零上手 openGauss:Docker 部署 + 全场景连接教程
运维·docker·容器
风曦Kisaki11 小时前
Kubernetes(K8s)笔记Day06: 持久化存储(emptyDir,hostPath,NFS),PV 和 PVC,StorageClass存储类
linux·运维·笔记·云原生·容器·kubernetes
Crazy________16 小时前
k8s部署若依微服务架构流程,v3.6.6
运维·云原生·容器·kubernetes·状态模式
阿里云云原生17 小时前
AI 创新实践论坛·上海站精彩回顾 & PPT 下载
云原生
阿里云云原生18 小时前
轮子还要自己造吗?SRE 团队视角:从“全栈自研”到“拥抱云原生可观测底座”的思考
云原生
生活爱好者!18 小时前
NAS还能用来开视频会议?docker一键部署MiroTalk SFU
运维·docker·容器
xiaoxiangsiyan18 小时前
GitLab CI/CD 自托管(EE 企业版)+ Kubernetes Runner 集群 + ArgoCD(GitOps 部署)
运维·网络·ci/cd·容器·kubernetes·gitlab·argocd