k8s之基于metallb实现LoadBalancer型Service

一、实验说明

MetalLB

MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议,主要用于暴露 K8s 集群的服务到集群外部访问,MetalLB 可以让我们在 K8s 集群中创建服务类型为 LoadBalancer 的服务,并且无需依赖云厂商提供的LoadBalancer。

它具有两个共同提供此服务的工作负载:地址分配(address allocation)和外部公告(external announcement),对应在 K8s 中部署的 controller 和 speaker。

1、address allocation

地址分配这个功能比较好理解,首先我们需要给 MetalLB 分配一个 IP 段,接着它会根据K8s 的 Service 中的相关配置来给 LoadBalancer 的服务分配 IP,LoadBalancer 的 IP 可以手动指定,也可以让 MetalLB 自动分配。地址分配主要就是由作为 Deployment 部署的 controller 来实现,它负责监听集群中的 Service 状态并且分配 IP。

2、external announcement

外部公告的主要功能就是要把服务类型为 LoadBalancer 的服务的 EXTERNAL-IP 公布到网络中去,确保客户端能够正常访问到这个 IP。MetalLB 对此的实现方式主要有三种:ARP/NDP 和 BGP,其中ARP/NDP 分别对应 IPv4/IPv6 协议的 Layer2 模式,BGP 路由协议则是对应 BGP 模式。外部公告主要通过由DaemonSet 部署的 speaker 来实现,它负责在网络中发布 ARP/NDP 报文或者是和 BGP 路由器建立连接并发布BGP 报文。

MetalLB 有 Layer2 模式和 BGP 模式,任选一种模式进行配置即可。

  • Layer2 模式

Layer2 模式下,每个 Service 会有集群中的一个 Node 来负责。服务的入口流量全部经由单个节点,然后该节点的 Kube-Proxy 会把流量再转发给服务的 Pods。
也就是说,该模式下 MetalLB 并没有真正提供负载均衡器。尽管如此,MetalLB 提供了故障转移功能,如果持有 IP 的节点出现故障,则默认 10 秒后即发生故障转移,IP 会被分配给其它健康的节点。

Layer2 模式的优缺点:

Layer2 模式更为通用,不需要用户有额外的设备;
Layer2 模式下存在单点问题,服务的所有入口流量经由单点,其网络带宽可能成为瓶颈;
由于 Layer 2 模式需要 ARP/NDP 客户端配合,当故障转移发生时,MetalLB 会发送 ARP 包来宣告 MAC 地址和 IP 映射关系的变化,地址分配略为繁琐。
  • BGP模式


当在第三层工作时,集群中所有机器都和你控制的最接近的路由器建立 BGP 会话,此会话让路由器能学习到如何转发针对 K8S 服务 IP 的数据包。

通过使用 BGP,可以实现真正的跨多节点负载均衡(需要路由器支持 multipath),还可以基于 BGP 的策略机制实现细粒度的流量控制。

具体的负载均衡行为和路由器有关,可保证的共同行为是:每个连接(TCP 或 UDP 会话)的数据包总是路由到同一个节点上。

BGP 模式的优缺点:

不能优雅处理故障转移,当持有服务的节点宕掉后,所有活动连接的客户端将收到 Connection reset by peer ;
BGP 路由器对数据包的源 IP、目的 IP、协议类型进行简单的哈希,并依据哈希值决定发给哪个 K8S 节点。问题是 K8S 节点集是不稳定的,一旦(参与 BGP)的节点宕掉,很大部分的活动连接都会因为 rehash 而坏掉。

BGP 模式问题的缓和措施:

将服务绑定到一部分固定的节点上,降低 rehash 的概率。
在流量低的时段改变服务的部署。
客户端添加透明重试逻辑,当发现连接 TCP 层错误时自动重试。

实验目的

基于metallb实现kubernetes的LoadBalancer型Service。

环境说明

VMware Workstation安装三台虚拟机,安装K8S集群,网络模式NAT模式。

master 11.0.1.131
node01 11.0.1.132
node02 11.0.1.133

root@master:/home/user# kubectl get nodes
NAME     STATUS     ROLES           AGE   VERSION
master   Ready      control-plane   37d   v1.26.3
node01   Ready      <none>          37d   v1.26.3
node02   Ready      <none>          37d   v1.26.3

二、安装metallb

官网安装

1、修改ipvs严格ARP模式

kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

2、创建metallb

root@master:/home/user# kubectl apply -f https://mirror.ghproxy.com/https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/etallb-native.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/webhook-server-cert created
service/webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created
root@master:/home/user# kubectl get ns
NAME              STATUS   AGE
default           Active   37d
dev               Active   18d
kube-node-lease   Active   37d
kube-public       Active   37d
kube-system       Active   37d
metallb-system    Active   2m24s
myapp             Active   26d
myserver          Active   36d

root@master:/home/user# kubectl api-versions
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apiregistration.k8s.io/v1
apps/v1
authentication.k8s.io/v1
authorization.k8s.io/v1
autoscaling/v1
autoscaling/v2
batch/v1
certificates.k8s.io/v1
coordination.k8s.io/v1
crd.projectcalico.org/v1
discovery.k8s.io/v1
events.k8s.io/v1
flowcontrol.apiserver.k8s.io/v1beta2
flowcontrol.apiserver.k8s.io/v1beta3
metallb.io/v1alpha1
metallb.io/v1beta1
metallb.io/v1beta2
networking.k8s.io/v1
node.k8s.io/v1
policy/v1
rbac.authorization.k8s.io/v1
scheduling.k8s.io/v1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1

root@master:/home/user# kubectl get pod -n metallb-system
NAME                          READY   STATUS              RESTARTS   AGE
controller-586bfc6b59-wg286   1/1     Running             0          61s
speaker-bzhpc                 1/1     Running             0          60s
speaker-k2s9j                 1/1     Running             0          61s

3、创建metallb地址池
metallb的Addres Allocation (地址分配) : 基于用户配置的地址池,为用户创建的LoadBalancer分配IP地址,并配置在节点上。
本实验的地址池选择宿主机的NAT池网段,必须保证网络可达。

root@master:/home/user# cat metallb-ippool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: localip-pool
  namespace: metallb-system
spec:
  addresses:
  - 11.0.1.140-11.0.1.146
  autoAssign: true
  avoidBuggyIPs: true

root@master:/home/user# kubectl apply -f metallb-ippool.yaml
ipaddresspool.metallb.io/localip-pool created

root@master:/home/user# kubectl get ipaddresspool  -n metallb-system
NAME           AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
localip-pool   true          true              ["11.0.1.140-11.0.1.146"]

4、通过网卡对外通告
External Announcement(对外公告):让集群外部的网络了解新分配的IP地址,MetallB使用ARP、NDP或BGP实现。

root@master:/home/user# cat metallb-l2.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: localip-pool-l2a
  namespace: metallb-system
spec:
  ipAddressPools:
  - localip-pool
  interfaces:
  - ens33

root@master:/home/user# kubectl apply -f metallb-l2.yaml
l2advertisement.metallb.io/localip-pool-l2a created

root@master:/home/user# kubectl get l2advertisement -n metallb-system
NAME               IPADDRESSPOOLS     IPADDRESSPOOL SELECTORS   INTERFACES
localip-pool-l2a   ["localip-pool"]                             ["ens33"]

三、实现应用的对外发布
1、创建deployment型工作负载的应用

root@master:/home/user# kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=3
deployment.apps/demoapp created
root@master:/home/user# kubectl get pod
NAME                      READY   STATUS                   RESTARTS   AGE
demoapp-75f59c894-2p5wr   1/1     Running                  0          101s
demoapp-75f59c894-fx8xh   1/1     Running                  0          101s
demoapp-75f59c894-k5stt   1/1     Running                  0          101s

2、创建loadbalancer Service对外发布应用

root@master:/home/user# cat services-loadbalancer-demo.yaml
kind: Service
apiVersion: v1
metadata:
  name: demoapp-loadbalancer-svc
spec:
  type: LoadBalancer
  selector:
    app: demoapp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
root@master:/home/user# kubectl apply -f services-loadbalancer-demo.yaml
service/demoapp-loadbalancer-svc created
root@master:/home/user# kubectl get svc
NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
demoapp-loadbalancer-svc   LoadBalancer   10.200.135.7   11.0.1.140    80:30970/TCP   18s
kubernetes                 ClusterIP      10.200.0.1     <none>        443/TCP        37d

以上已经为service自动分配外部地址11.0.1.140

四、通过外部IP访问集群

root@master:/home/user# kubectl get pod -o wide
NAME                      READY   STATUS                   RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
demoapp-75f59c894-2p5wr   1/1     Running                  0          36m   10.100.231.117   node02   <none>           <none>
demoapp-75f59c894-fx8xh   1/1     Running                  0          36m   10.100.231.119   node02   <none>           <none>
demoapp-75f59c894-k5stt   1/1     Running                  0          36m   10.100.231.118   node02   <none>           <none>

刷新网页可以看到实现了流量的负载均衡,


五、参考

https://blog.csdn.net/weixin_39246554/article/details/129343617
https://zhuanlan.zhihu.com/p/617807098
https://fafucoder.github.io/categories/

posted @   *一炁化三清*  阅读(197)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示