PorterLB使用手册

一、PorterLB介绍

Porter:面向裸金属环境的 Kubernetes 开源负载均衡器

我们知道,在 Kubernetes 集群中可以使用 “LoadBalancer” 类型的服务将后端工作负载暴露在外部。云厂商通常为 Kubernetes 提供云上的 LB 插件,但这需要将集群部署在特定 IaaS 平台上。然而,许多企业用户通常都将 Kubernetes 集群部署在裸机上,尤其是用于生产环境时。而且对于本地裸机集群,Kubernetes 不提供 LB 实施。Porter 是一个专为裸金属 Kubernetes 集群环境而设计的开源的负载均衡器项目,可完美地解决此类问题

Kubernetes 服务介绍

在 Kubernetes 集群中,网络是非常基础也非常重要的一部分。对于大规模的节点和容器来说,要保证网络的连通性、网络转发的高效,同时能做的 IP 和 Port 自动化分配和管理,并提供给用户非常直观和简单的方式来访问需要的应用,这是非常复杂且细致的设计。

Kubernetes 本身在这方面下了很大的功夫,它通过 CNI、Service、DNS、Ingress 等一系列概念,解决了服务发现、负载均衡的问题,也大大简化了用户的使用和配置。其中的 Service 是 Kubernetes 微服务的基础,Kubernetes 是通过 kube-proxy 这个组件来实现服务的。kube-proxy 运行在每个节点上,监听 API Server 中服务对象的变化,通过管理 iptables 来实现网络的转发。用户可以创建多种形式的 Service,比如基于 Label Selector 、Headless 或者 ExternalName 的 Service,kube-proxy 会为 Service 创建一个虚拟的 IP(即 Cluster IP),用于集群内部访问服务。

暴露服务的三种方式

如果需要从集群外部访问服务,即将服务暴露给用户使用,Kubernetes Service 本身提供了两种方式,一种是 NodePort,另外一种是 LoadBalancer。另外 Ingress 也是一种常用的暴露服务的方式。

NodePort

如果将服务的类型设置为 NodePort,kube-proxy 就会为这个服务申请一个 30000 以上的端口号(默认情况下),然后在集群所有主机上配置 IPtables 规则,这样用户就能通过集群中的任意节点加上这个分配的端口号访问服务了,如下图:

img

NodePort 是最方便的暴露服务的方式,缺点也很明显:

  1. 基于 SNAT 进行访问,Pod 无法看到真正的 IP。
  2. NodePort 是将集群中的一个主机作为跳板访问后端服务,所有的流量都会经过跳板机,很容易造成性能瓶颈和单点故障,难以用于生产环境。
  3. NodePort 端口号一般都是用大端口,不容易记忆。

NodePort 设计之初就不是用于生产环境暴露服务的方式,所以默认端口都是一些大端口。

LoadBalancer

LoadBalancer 是 Kubernetes 提倡的将服务暴露给外部的一种方式。但是这种方式需要借助于云厂商提供的负载均衡器才能实现,这也要求了 Kubernetes 集群必须在云厂商上部署。LoadBalancer 的原理如下:

img

LoadBalancer 通过云厂商的 LB 插件实现,LB 插件基于 Kubernetes.io/cloud-provider 这个包实现,这个包会自动选择合适的后端暴露给 LB 插件,然后 LB 插件由此创建对应的负载均衡器,网络流量在云服务端就会被分流,就能够避免 NodePort 方式的单点故障和性能瓶颈。LoadBalancer 是 Kubernetes 设计的对外暴露服务的推荐方式,但是这种方式仅仅限于云厂商提供的 Kubernetes 服务上,对于物理部署或者非云环境下部署的 Kubernetes 集群,这一机制就存在局限性而无法使用。

Ingress

Ingress 并不是 Kubernetes 服务本身提供的暴露方式,而是借助于软件实现的同时暴露多个服务的一种类似路由器的插件。Ingress 通过域名来区分不同服务,并且通过 annotation 的方式控制服务对外暴露的方式。其原理如下图:

img

相比于 NodePort 和 LoadBalancer,Ingress 在企业业务场景中应该是使用的最多的,原因有:

  1. 相比 kube-proxy 的负载均衡,Ingress controller 能够实现更多的功能,诸如流量控制,安全策略等。
  2. 基于域名区分服务,更加直观。也不需要用到 NodePort 中的大端口号。

但是在实际场景中,Ingress 也需要解决下面的一些问题:

  1. Ingress 多用于 L7,对于 L4 的支持不多。
  2. 所有的流量都会经过 Ingress Controller,需要一个 LB 将 Ingress Controller 暴露出去。

第一个问题,Ingress 也可以用于 L4,但是对于 L4 的应用,Ingress 配置过于复杂,最好的实现就是直接用 LB 暴露出去。第二个问题,测试环境可以用 NodePort 将 Ingress Controller 暴露出去或者直接 hostnetwork,但也不可避免有单点故障和性能瓶颈,也无法很好的使用 Ingress-controller 的 HA 特性。

Porter 介绍

Porter 是 KubeSphere 团队研发的一款开源的基于 BGP 协议的云原生负载均衡器插件。它的主要特性有:

  1. 基于路由器 ECMP 的负载均衡
  2. 基于 BGP 路由动态配置
  3. VIP 管理

Porter 的所有代码和文档已在 GitHub[1] 开源,欢迎大家关注(Star)和使用。

如何快速部署使用

Porter 目前已在如下两种环境下进行过部署和测试,并将部署测试与使用步骤的详细文档记录在 GitHub,大家可以通过以下链接查看,建议大家在分享后动手部署实践一下。

  • 在物理部署的 Kubernetes 集群上部署使用 Porter[2]
  • 在青云 QingCloud 云平台用模拟路由器的方式测试[3]

原理

ECMP

ECMP(Equal-Cost Multi-Pathing,等价路由)即存在多条到达同一个目的地址的相同开销的路径。当设备支持等价路由时,发往该目的 IP 或者目的网段的三层转发流量就可以通过不同的路径分担,实现网络的负载均衡,并在其中某些路径出现故障时,由其它路径代替完成转发处理,实现路由冗余备份功能。如下图:

img

借助于路由器(虚拟路由器),对于某一个IP(对应服务的VIP),ECMP能根据一定的Hash算法从已知的路由中来选择下一跳(Pod),从而实现负载均衡的目的。一般的路由器(虚拟路由器)都具备 ECMP 的能力,Porter 要做的就是查询 Kubernetes API Server,将一个服务对应的后端 Pod 信息通过路由的方式发送给路由器。

BGP

在 Kubernetes 中,Pod 可能会漂移,对于路由器来说,一个服务 VIP 的下一跳是不固定的,等价路由的信息会经常更新。实际上我们参考 Calico,使用了 BGP(Border Gateway Protocol,边界网关协议)实现路由的广播。BGP 是互联网上一个核心的去中心化自治路由协议,在互联网领域用的比较多。BGP 不同于其他路由协议,BGP 使用了 L4 来保证路由信息的安全更新。同时由于 BGP 的去中心化特性,很容易搭建一个高可用路由层,保证网络的持续性。

img

上图简单描述了 Porter 中 BGP 的实现原理。图中左下是一个两节点的 Kubernetes 集群,集群上方是有两个路由器 leaf1 和 leaf2,leaf 连接了核心交换机层 spine,也同样是两个。最右侧是用户,对应的路由器是 border,border 也连接了 spine,用户和 Kubernetes 服务器三层是可达的。Kubernetes 集群中创建了 Service,并且使用了 Porter,Porter 为其分配了一个 1.1.1.1 的 vip(或者手工指定),Porter通过 BGP 告知 leaf1和leaf2,访问 1.1.1.1 的下一跳可以是 node1,也可以是 node2。leaf 一层也会将这个信息告知 spine,spine 的 BGP 经过计算得知访问 1.1.1.1 的下一跳是 leaf1,leaf2。按照同样的逻辑,这个路由也会更新到 border,这样用户访问 1.1.1.1 的完整路径就有了。同时,由于这个图中每一层都有 HA,所以外界访问 1.1.1.1 的路径就有 222*2=16 条,流量能够在整个网络中被分流,并且任意一层一个路由器宕机都不会影响用户的访问。

架构

img

Porter 有两个组件,一个核心控制器和一个部署在所有节点上的 Agent。核心控制器主要功能有:

  1. 监控集群中的 Service 以及对应的 endpoints,获取 Pod 漂移信息
  2. VIP 存储与分配
  3. 与外界建立 BGP 协议,广播路由

img

上图展示了 Porter 核心控制器的工作原理。

Agent 则是一个轻量级组件,用于监控 VIP 资源,增加 Iptables 规则让外部流量能够访问 VIP,默认情况下外部流量访问 VIP 会被内核中的 Forward 表Drop 掉。

面向云原生的设计

Porter 中的所有资源都是 CRD,包括 VIP、BGPPeer、BGPConfig 等。对于习惯 kubectl 的用户使用 Porter 将非常友好。对于想定制 Porter 的高级用户,也可以直接调用 Kubernetes API 来二次开发。Porter 的核心控制器很快就会支持 HA,保证 Porter 的高可用性。

使用注意事项

用户访问 VIP 的流量会通过 BGP 到达 Kubernetes 集群中的某一个节点,因为 Porter 广播路由的路也是 Node 而不是具体的 podip,podip 外部不可访问,后续 Node 到 Pod 的路由是由 kube-proxy 维护的。如下图:

img

流量被 SNAT 之后随机发送给某一个 Pod。由于 Porter 会根据 Service Endpoints 的变化动态调整路由,确保下一跳的 Node 节点一定有 Pod 存在,所以我们可以更改 kube-proxy 这一个默认行为。在 Service 上设置 ExternalTrafficPolicy=local,达到下面的效果:

img

这样做有两个好处:

  1. SourceIP不会NAT
  2. 流量直接走本地,网络路径少一跳

二、PorterLB安装部署使用

1.使用Helm部署

—前提本地是安装好helm3

#添加porterlb heml仓库到本地
helm repo add test https://charts.kubesphere.io/test
#更新helm仓库
help repo update
#部署porterlb
helm install porterdev test/porter -n devops --debug
#查看部署pod
kubectl get pod -n devops  |grep -i porterdev

2.PorterLB配置使用

a.Use PorterLB in Layer 2 Mode
步骤1:为kube-proxy启用strictARP

在第2层模式下,需要为kube-proxy启用strictARP,以便Kubernetes集群中的所有NIC停止回答来自其他NIC的ARP请求,而是通过PorterLB处理ARP请求。

登录Kubernetes集群并运行以下命令来编辑kube-proxy ConfigMap:

kubectl edit configmap kube-proxy -n kube-system

在kube-proxy ConfigMap YAML配置中,设置data.config.conf.ipvs.strictARPtrue

ipvs:
  strictARP: true

运行以下命令以重新启动kube-proxy:

kubectl rollout restart daemonset kube-proxy -n kube-system
步骤2:指定用于PorterLB的NIC

如果安装PorterLB的节点具有多个NIC,则需要在第2层模式下指定用于PorterLB的NIC。如果节点只有一个NIC,则可以跳过此步骤。

在此示例中,安装PorterLB的master1节点具有两个NIC(eth0 192.168.0.2和eth1 192.168.1.2),而eth0 192.168.0.2将用于PorterLB。

运行以下命令以注释master1以指定NIC:

kubectl annotate nodes master1 layer2.porter.kubesphere.io/v1alpha1="192.168.0.2"
步骤3:创建一个Eip对象

Eip对象用作PorterLB的IP地址池。

  1. 运行以下命令为Eip对象创建一个YAML文件:

    vi porter-layer2-eip.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: network.kubesphere.io/v1alpha2
    kind: Eip
    metadata:
      name: porter-layer2-eip
    spec:
      address: 192.168.0.91-192.168.0.100
      interface: eth0
      protocol: layer2
    

    笔记

    • 指定的IP地址spec.address必须与Kubernetes群集节点在同一网段上。
    • 有关Eip YAML配置中的字段的详细信息,请参阅使用Eip配置IP地址池
  3. 运行以下命令以创建Eip对象:

    kubectl apply -f porter-layer2-eip.yaml
    
步骤4:创建部署

下面使用luksa / kubia映像创建两个Pod的部署。每个Pod向外部请求返回其自己的Pod名称。

  1. 运行以下命令为部署创建一个YAML文件:

    vi porter-layer2.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: porter-layer2
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: porter-layer2
      template:
        metadata:
          labels:
            app: porter-layer2
        spec:
          containers:
            - image: luksa/kubia
              name: kubia
              ports:
                - containerPort: 8080
    
  3. 运行以下命令以创建部署:

    kubectl apply -f porter-layer2.yaml
    
步骤5:创建服务
  1. 运行以下命令为服务创建一个YAML文件:

    vi porter-layer2-svc.yaml
    
  2. 将以下信息添加到YAML文件:

    kind: Service
    apiVersion: v1
    metadata:
      name: porter-layer2-svc
      annotations:
        lb.kubesphere.io/v1alpha1: porter
        protocol.porter.kubesphere.io/v1alpha1: layer2
        eip.porter.kubesphere.io/v1alpha2: porter-layer2-eip
    spec:
      selector:
        app: porter-layer2
      type: LoadBalancer
      ports:
        - name: http
          port: 80
          targetPort: 8080
      externalTrafficPolicy: Cluster
    

    笔记

    • 您必须设置spec.typeLoadBalancer
    • lb.kubesphere.io/v1alpha1: porter服务使用PorterLB注解指定。
    • protocol.porter.kubesphere.io/v1alpha1: layer2注释指定PorterLB在二层模式下使用。
    • eip.porter.kubesphere.io/v1alpha2: porter-layer2-eip注释指定由PorterLB使用EIP的对象。如果未配置此注释,PorterLB将自动使用第一个与协议匹配的可用Eip对象。您也可以删除此批注并添加spec.loadBalancerIP字段(例如spec.loadBalancerIP: 192.168.0.91),以为服务分配特定的IP地址。
    • 如果spec.externalTrafficPolicy设置为Cluster(默认值),PorterLB从所有Kubernetes集群节点中随机选择一个节点来处理服务请求。也可以通过kube-proxy到达其他节点上的Pod。
    • 如果spec.externalTrafficPolicy设置为Local,PorterLB会在Kubernetes集群中随机选择一个包含Pod的节点来处理服务请求。只能访问所选节点上的Pod。
  3. 运行以下命令以创建服务:

    kubectl apply -f porter-layer2-svc.yaml
    
步骤6:在第2层模式下验证PorterLB

以下内容验证PorterLB是否正常运行。

  1. 在Kubernetes集群中,运行以下命令以获取服务的外部IP地址:

    kubectl get svc porter-layer2-svc
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZCfp6Aj-1616050284770)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-layer-2-mode/service-ip.jpg)]

  2. 在Kubernetes集群中,运行以下命令以获取集群节点的IP地址:

    kubectl get nodes -o wide
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xYkl6g1W-1616050284772)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-layer-2-mode/node-ips.jpg)]

  3. 在Kubernetes集群中,运行以下命令以检查Pod的节点:

    kubectl get po
    

    荚节点

    笔记

    在此示例中,将Pod自动分配给不同的节点。您可以手动将Pod分配给不同的节点

  4. 在客户端计算机上,运行以下命令来ping服务IP地址并检查IP邻居:

    ping 192.168.0.91
    
    ip neigh
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWNJr7or-1616050284774)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-layer-2-mode/ip-neigh.jpg)]

    ip neigh命令输出中,服务IP地址192.168.0.91的MAC地址与worker-p001 192.168.0.3的MAC地址相同。因此,PorterLB已将服务IP地址映射到worker-p001的MAC地址。

  5. 在客户端计算机上,运行以下命令以访问服务:

    curl 192.168.0.91
    

    如果spec.externalTrafficPolicyService YAML配置中将设置为Cluster,则可以同时到达两个Pod。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ihz91kHd-1616050284775)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-layer-2-mode/service-cluster.jpg)]

    如果spec.externalTrafficPolicy在“服务YAML”配置中将设置为Local,则只能访问由PorterLB选择的节点上的Pod。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-spV7nsB7-1616050284776)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-layer-2-mode/service-local.jpg)]

b.Use PorterLB in BGP Mode

本文档不是使用真实的路由器,而是使用带有BIRD的Linux服务器来模拟路由器,这样,没有真实路由器的用户也可以在BGP模式下使用PorterLB进行测试。

先决条件

  • 您需要准备已安装PorterLB的Kubernetes集群
  • 您需要准备一个与Kubernetes集群正确通信的Linux服务器。BIRD将安装在服务器上以模拟BGP路由器。
  • 如果您使用真实的路由器而不是BIRD,则该路由器必须支持BGP和等价多路径(ECMP)路由。此外,路由器还必须支持从同一邻居接收多个等效路由。

本文以以下设备为例:

设备名称IP地址描述
大师1192.168.0.2安装了PorterLB的Kubernetes集群主服务器。
工人p001192.168.0.3Kubernetes集群工作者1
工人-p002192.168.0.4Kubernetes集群工作者2
i-f3fozos0192.168.0.5BIRD机器,将在其中安装BIRD以模拟BGP路由器。
步骤1:安装和配置BIRD

如果使用真实的路由器,则可以跳过此步骤,而是在路由器上执行配置。

  1. 登录到BIRD机器并运行以下命令来安装BIRD:

    sudo add-apt-repository ppa:cz.nic-labs/bird
    sudo apt-get update 
    sudo apt-get install bird
    sudo systemctl enable bird 
    

    笔记

    • BIRD 1.5不支持ECMP。要使用PorterLB的所有功能,建议您安装BIRD 1.6或更高版本。
    • 前面的命令仅适用于基于Debian的操作系统,例如Debian和Ubuntu。在基于RHEL和CentOS的基于Red Hat的操作系统上,请使用yum
    • 您还可以根据BIRD官方文档安装BIRD 。
  2. 运行以下命令以编辑BIRD配置文件:

    vi /etc/bird/bird.conf
    
  3. 如下配置BIRD配置文件:

    router id 192.168.0.5;
       
    protocol kernel {
        scan time 60;
        import none;
        export all;
        merge paths on;
    }
       
    protocol bgp neighbor1 {
        local as 50001;
        neighbor 192.168.0.2 port 17900 as 50000;
        source address 192.168.0.5;
        import all;
        export all;
        enable route refresh off;
        add paths on;
    }
    

    笔记

    • 对于测试用途,您只需要在前面的配置中自定义以下字段:

      router id:BIRD机器的路由器ID,通常设置为BIRD机器的IP地址。

      protocol bgp neighbor1

      • local as:BIRD机器的ASN,必须与Kubernetes集群的ASN不同。
      • neighbor:Kubernetes集群的主节点IP地址,BGP端口号和ASN。使用端口17900而不是默认的BGP端口,179以避免与系统中的其他BGP组件冲突。
      • source address:BIRD机器的IP地址。
    • 如果Kubernetes中的多个节点用作BGP邻居,则需要在BIRD配置文件中配置多个BGP邻居。

    • 有关BIRD配置文件的详细信息,请参阅BIRD官方文档

  4. 运行以下命令以重新启动BIRD:

    sudo systemctl restart bird 
    
  5. 执行以下命令,检查BIRD的状态是否为活动状态。

    sudo systemctl status bird
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24SVMcVf-1616050284777)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-bgp-mode/bird-status.jpg)]

    笔记

    如果BIRD的状态不是活动的,则可以运行以下命令来检查错误日志:

    journalctl -f -u bird
    
步骤2:建立BgpConf对象

BgpConf对象用于在PorterLB上配置本地(Kubernetes群集)BGP属性。

  1. 运行以下命令为BgpConf对象创建YAML文件:

    vi porter-bgp-conf.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: network.kubesphere.io/v1alpha2
    kind: BgpConf
    metadata:
      name: default
    spec:
      as: 50000
      listenPort: 17900
      routerId: 192.168.0.2
    

    笔记

    有关BgpConf YAML配置中字段的详细信息,请参阅使用BgpConf配置本地BGP属性

  3. 运行以下命令以创建BgpConf对象:

    kubectl apply -f porter-bgp-conf.yaml
    
步骤3:建立BgpPeer对象

BgpPeer对象用于在PorterLB上配置对等(BIRD机器)BGP属性。

  1. 运行以下命令为BgpPeer对象创建YAML文件:

    vi porter-bgp-peer.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: network.kubesphere.io/v1alpha2
    kind: BgpPeer
    metadata:
      name: porter-bgp-peer
    spec:
      conf:
        peerAs: 50001
        neighborAddress: 192.168.0.5
    

    笔记

    有关BgpPeer YAML配置中字段的详细信息,请参阅使用BgpPeer配置对等BGP属性

  3. 运行以下命令以创建BgpPeer对象:

    kubectl apply -f porter-bgp-peer.yaml
    
步骤4:创建一个Eip对象

Eip对象用作PorterLB的IP地址池。

  1. 运行以下命令为Eip对象创建一个YAML文件:

    vi porter-bgp-eip.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: network.kubesphere.io/v1alpha2
    kind: Eip
    metadata:
      name: porter-bgp-eip
    spec:
      address: 172.22.0.2-172.22.0.10
    

    笔记

    有关Eip YAML配置中的字段的详细信息,请参阅使用Eip配置IP地址池

  3. 运行以下命令以创建Eip对象:

    kubectl apply -f porter-bgp-eip.yaml
    
步骤5:创建部署

下面使用luksa / kubia映像创建两个Pod的部署。每个Pod向外部请求返回其自己的Pod名称。

  1. 运行以下命令为部署创建一个YAML文件:

    vi porter-bgp.yaml
    
  2. 将以下信息添加到YAML文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: porter-bgp
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: porter-bgp
      template:
        metadata:
          labels:
            app: porter-bgp
        spec:
          containers:
            - image: luksa/kubia
              name: kubia
              ports:
                - containerPort: 8080
    
  3. 运行以下命令以创建部署:

    kubectl apply -f porter-bgp.yaml
    
步骤6:建立服务
  1. 运行以下命令为服务创建一个YAML文件:

    vi porter-bgp-svc.yaml
    
  2. 将以下信息添加到YAML文件:

    kind: Service
    apiVersion: v1
    metadata:
      name: porter-bgp-svc
      annotations:
        lb.kubesphere.io/v1alpha1: porter
        protocol.porter.kubesphere.io/v1alpha1: bgp
        eip.porter.kubesphere.io/v1alpha2: porter-bgp-eip
    spec:
      selector:
        app: porter-bgp
      type: LoadBalancer
      ports:
        - name: http
          port: 80
          targetPort: 8080
      externalTrafficPolicy: Cluster
    

    笔记

    • 您必须设置spec.typeLoadBalancer
    • lb.kubesphere.io/v1alpha1: porter服务使用PorterLB注解指定。
    • protocol.porter.kubesphere.io/v1alpha1: bgp注释指定PorterLB在BGP模式下使用。
    • eip.porter.kubesphere.io/v1alpha2: porter-bgp-eip注释指定由PorterLB使用EIP的对象。如果未配置此注释,PorterLB将自动使用第一个与协议匹配的可用Eip对象。您也可以删除此批注并添加spec.loadBalancerIP字段(例如spec.loadBalancerIP: 172.22.0.2),以为服务分配特定的IP地址。
    • 在BGP模式下,您可以将spec.loadBalancerIP多个服务设置为相同的IP地址共享值(服务由不同的服务端口区分)。在这种情况下,你必须设置spec.ports.port为不同的值,并spec.externalTrafficPolicyCluster该服务。
    • 如果spec.externalTrafficPolicy设置为Cluster(默认值),PorterLB会将所有Kubernetes群集节点用作发往该服务的下一跳。
    • 如果spec.externalTrafficPolicy设置为Local,PorterLB仅使用包含Pods作为发往服务的下一跳的Kubernetes群集节点。
  3. 运行以下命令以创建服务:

    kubectl apply -f porter-bgp-svc.yaml
    
步骤7:在BGP模式下验证PorterLB

以下内容验证PorterLB是否正常运行。

  1. 在Kubernetes集群中,运行以下命令以获取服务的外部IP地址:

    kubectl get svc
    

    服务IP

  2. 在Kubernetes集群中,运行以下命令以获取集群节点的IP地址:

    节点IP

  3. 在BIRD机器上,运行以下命令以检查路由表。如果显示使用Kubernetes群集节点作为到达服务的下一跳的等效路由,则PorterLB正常运行。

    ip route
    

    如果spec.externalTrafficPolicyService YAML配置中将设置为Cluster,则所有Kubernetes群集节点都将用作下一跳。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NX8QygPc-1616050284779)(https://porterlb.io/images/docs/getting-started/usage/use-porter-in-bgp-mode/bgp-routes-cluster.jpg)]

    如果spec.externalTrafficPolicyService YAML配置中将设置为Local,则仅将包含Pod的Kubernetes群集节点用作下一跳。

    bgp-routes-local

  4. 在BIRD机器上,运行以下命令以访问服务:

    curl 172.22.0.2
    

    访问服务

3.配置详解

a.Configure IP Address Pools Using Eip

本文档介绍了如何配置Eip对象,该对象在BGP模式和第2层模式下均用作PorterLB的IP地址池。

PorterLB将Eip对象中的IP地址分配给Kubernetes集群中的LoadBalancer Services。此后,PorterLB通过BGP(在BGP模式下),ARP(在IPv4的第2层模式下)或NDP(在IPv6的第2层模式下)发布发往服务IP地址的路由。

笔记

当前,PorterLB仅支持IPv4,并将很快支持IPv6。

为PorterLB配置Eip对象

您可以创建一个Eip对象来为PorterLB提供IP地址池。以下是Eip YAML配置的示例:

apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
    name: eip-sample-pool
spec:
    address: 192.168.0.91-192.168.0.100
    protocol: layer2
    interface: eth0
    disable: false
status:
    occupied: false
    usage: 1
    poolSize: 10
    used: 
      "192.168.0.91": "default/test-svc"
    firstIP: 192.168.0.91
    lastIP: 192.168.0.100
    ready: true
    v4: true

字段描述如下:

metadata

  • name:Eip对象的名称。

spec

  • address:一个或多个IP地址,PorterLB将使用该IP地址。值格式可以是:

    • IP address,例如192.168.0.100
    • IP address/Subnet mask,例如192.168.0.0/24
    • IP address 1-IP address 2,例如192.168.0.91-192.168.0.100

    笔记

    不同Eip对象中的IP段不能重叠。否则,将发生资源创建错误。

  • protocol:指定Eip对象用于哪种PorterLB模式。该值可以是layer2bgp。如果未指定此字段,bgp则使用默认值。

  • interface:PorterLB在其上侦听ARP或NDP请求的NIC。仅当protocol设置为时,此字段才有效layer2

    小费

    如果Kubernetes集群节点的NIC名称不同,则可以将值设置为can_reach:IP address(例如can_reach:192.168.0.5),以便PorterLB自动获取可以访问IP地址的NIC的名称。在这种情况下,必须确保Kubernetes群集节点不使用该IP地址,但群集节点可以访问该IP地址。

  • disable:指定是否禁用Eip对象。该值可以是:

    • false:PorterLB可以将Eip对象中的IP地址分配给新的LoadBalancer服务。
    • true:PorterLB停止将Eip对象中的IP地址分配给新的LoadBalancer服务。现有服务不受影响。

status:下面的字段status指定Eip对象的状态并自动进行配置。创建Eip对象时,无需配置这些字段。

  • occupied:指定Eip对象中的IP地址是否已用完。

  • usage:指定已将Eip对象中的IP地址分配给服务的数量。

  • used:指定使用的IP地址和使用IP地址的服务。服务以Namespace/Service name格式显示(例如default/test-svc)。

  • poolSize:Eip对象中IP地址的总数。

  • firstIP:Eip对象中的第一个IP地址。

  • lastIP:Eip对象中的最后一个IP地址。

  • v4:指定地址族是否为IPv4。当前,PorterLB仅支持IPv4,其值只能为true

  • ready:指定用于BGP / ARP / NDP路由发布的Eip关联程序是否已初始化。该程序已集成在PorterLB中。

b.Configure PorterLB in BGP Mode

本文档介绍了如何在BGP模式下配置PorterLB。如果PorterLB在第2层模式下使用,则无需配置PorterLB。

使用BgpConf配置本地BGP属性

您可以在Kubernetes集群中创建BgpConf对象,以在PorterLB上配置本地BGP属性。以下是BgpConf YAML配置的示例:

apiVersion: network.kubesphere.io/v1alpha2
kind: BgpConf
metadata:
  name: default
spec:
  as: 50000
  listenPort: 17900
  routerId: 192.168.0.2

字段描述如下:

metadata

  • name:BgpConf对象名称。PorterLB仅识别名称default。具有其他名称的BgpConf对象将被忽略。

spec

  • as:本地ASN,必须spec.conf.peerAS与BgpPeer配置中的值不同。
  • listenPort:PorterLB侦听的端口。默认值为179(默认BGP端口号)。如果Kubernetes群集中的其他组件(例如Calico)也使用BGP和端口179,则必须设置其他值以避免冲突。
  • routerID:本地路由器ID,通常设置为Kubernetes主节点主NIC的IP地址。如果未指定此字段,则将使用porter-manager所在节点的第一个IP地址。
使用BgpPeer配置对等BGP属性

您可以在Kubernetes集群中创建BgpPeer对象,以在PorterLB上配置对等BGP属性。以下是BgpPeer YAML配置的示例:

apiVersion: network.kubesphere.io/v1alpha2
kind: BgpPeer
metadata:
  name: bgppeer-sample
spec:
  conf:
    peerAs: 50001
    neighborAddress: 192.168.0.5
  afiSafis:
    - config:
        family:
          afi: AFI_IP
          safi: SAFI_UNICAST
        enabled: true
      addPaths:
        config:
          sendMax: 10
  nodeSelector:
    matchLabels:
      porter.kubesphere.io/rack: leaf1

字段描述如下:

metadata

  • name:BgpPeer对象的名称。如果有多个对等BGP路由器,则可以创建多个具有不同名称的BgpPeer对象。

spec.conf

  • peerAS:对等BGP路由器的ASN,必须spec.as与BgpConf配置中的值不同。
  • neighborAddress:对等体BGP路由器的IP地址。

spec.afiSafis.addPaths.config

  • sendMax:PorterLB可以发送给对等BGP路由器以进行等价多路径(ECMP)路由的最大等效路由数。默认值为10

spec.nodeSelector.matchLabels

  • porter.kubesphere.io/rack:如果Kubernetes集群节点部署在不同的路由器下,并且每个节点都有一个PorterLB副本,则需要配置此字段,以便正确节点上的PorterLB副本与对等BGP路由器建立BGP连接。默认情况下,所有端口管理器副本都将响应BgpPeer配置,并尝试与对等BGP路由器建立BGP连接。

下面的其他字段spec.afiSafis指定地址族。当前,PorterLB仅支持IPv4,您可以直接在示例配置中使用这些值。

c.Configure PorterLB for Multi-router Clusters (BGP Mode)

本文档介绍了如何为部署在多个路由器下的Kubernetes群集节点以BGP模式配置PorterLB。如果所有Kubernetes集群节点都部署在同一路由器下,则可以跳过此文档。

笔记

本文档仅适用于BGP模式。第2层模式要求所有Kubernetes群集节点都在同一第2层网络上(在同一路由器下)。

配置前的网络拓扑

本节说明为什么需要执行配置。下图显示了配置之前Kubernetes集群的网络拓扑。

多路由器拓扑-1

上图中的IP地址仅是示例。拓扑描述如下:

  • 在Kubernetes集群中,主节点1和工作节点1部署在叶子1 BGP路由器下,工作者2节点部署在叶子2 BGP路由器下。PorterLB仅安装在叶子1下(默认情况下,仅安装一个PorterLB副本)。
  • 由两个Pod支持的服务部署在Kubernetes集群中,并分配了IP地址172.22.0.2用于外部访问。Pod 1和Pod 2分别部署在工作程序1和工作程序2上。
  • PorterLB与叶1建立BGP连接,并将主节点和工作服务器1的IP地址(192.168.0.3和192.168.0.4)发布到叶1,作为到达服务IP地址172.2.2.0.2的下一跳。
  • 叶子1与主干BGP路由器建立BGP连接,并将其自己的IP地址192.168.0.2发布到主干路由器,作为到达服务IP地址172.2.2.0.2的下一跳。
  • 当外部客户端计算机尝试访问服务时,主干路由器将服务流量转发到叶子1,叶子1负载平衡主节点和工作者1之间的流量。
  • 尽管也可以通过kube-proxy到达worker 2上的Pod 2,但是路由器级别的负载平衡仅在主节点和worker 1之间实现,并且服务带宽限于主节点和worker 1的带宽。

要解决该问题,您需要标记Kubernetes群集节点并更改PorterLB部署配置,以便将PorterLB安装在所有分支路由器下的节点上。另外,您需要在BgpPeer配置中指定spec.nodeSelector.matchLabels字段,以便PorterLB副本与正确的BGP路由器建立BGP连接。

配置后的网络拓扑

本节介绍您需要实现的配置结果。下图显示了配置后的Kubernetes集群的网络拓扑。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-usnwliAZ-1616050284783)(https://porterlb.io/images/docs/getting-started/configuration/configure-porter-for-multi-router-clusters/multi-router-topology-2.jpg)]

上图中的IP地址仅是示例。拓扑描述如下:

  • 配置完成后,PorterLB将安装在所有分支路由器下的节点上。
  • 除了配置之前发生的情况之外,安装在叶子2下的PorterLB复制副本还与叶子2建立BGP连接,并将工作人员2 IP地址192.168.1.2发布到叶子2,作为到达服务IP地址172.22.0.2的下一跳。 。
  • 叶子2与主干路由器建立BGP连接,并将其自己的IP地址192.168.1.1发布到主干路由器,作为到达服务IP地址172.2.2.0.2的下一跳。
  • 当外部客户端计算机尝试访问服务时,主干路由器将负载平衡叶1和叶2之间的服务流量。叶1负载平衡主节点和工作服务器1之间的流量。叶2将流量转发给工作服务器2。因此,服务流量在所有三个Kubernetes群集节点之间实现负载平衡,并且可以利用所有三个节点的服务带宽。
配置步骤

以下步骤中的节点名称,叶路由器名称和名称空间仅是示例。您需要在您的环境中使用实际值。

  1. 登录Kubernetes集群并运行以下命令来标记要安装PorterLB的Kubernetes集群节点:

    kubectl label --overwrite nodes master1 worker-p002 lb.kubesphere.io/v1alpha1=porter
    

    笔记

    如果PorterLB仅安装在每个分支路由器下的一个节点上,则它可以正常工作。在此示例中,PorterLB将安装在leaf1下的master1上,以及leaf2下的worker-p002上。但是,为了确保生产环境中的高可用性,建议您在每个分支路由器下的至少两个节点上安装PorterLB。

  2. 运行以下命令,将porter-manager Pod的数量缩放为0:

    kubectl scale deployment porter-manager --replicas=0 -n porter-system
    
  3. 运行以下命令以编辑porter-manager部署:

    kubectl edit deployment porter-manager -n porter-system
    
  4. 在porter-manager部署YAML配置中,在以下位置添加以下字段spec.template.spec

    nodeSelector:
      kubernetes.io/os: linux
      lb.kubesphere.io/v1alpha1: porter
    
  5. 运行以下命令以将porter-manager Pod的数量缩放为所需的数量(将其更改2为实际值):

    kubectl scale deployment porter-manager --replicas=2 -n porter-system
    
  6. 运行以下命令,检查PorterLB是否已安装在所需的节点上。

    kubectl get po -n porter-system -o wide
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zod8Fx0D-1616050284784)(https://porterlb.io/images/docs/getting-started/configuration/configure-porter-for-multi-router-clusters/verify-configuration-result.jpg)]

  7. 运行以下命令以标记Kubernetes集群节点,以便PorterLB副本与正确的BGP路由器建立BGP连接。

    kubectl label --overwrite nodes master1 porter.kubesphere.io/rack=leaf1
    
    kubectl label --overwrite nodes worker-p002 porter.kubesphere.io/rack=leaf2
    
  8. 创建BgpPeer对象时,请为每个叶路由器在BgpPeer YAML配置中配置spec.nodeSelector.matchLabels字段。以下YAML配置指定master1上的PorterLB副本与leaf1进行通信,而worker-p002上的PorterLB副本与leaf2进行通信。

    # BgpPeer YAML for master1 and leaf1
    nodeSelector:
        matchLabels:
          porter.kubesphere.io/rack: leaf1
    
    # BgpPeer YAML for worker-p002 and leaf2
    nodeSelector:
        matchLabels:
          porter.kubesphere.io/rack: leaf2
    
d.Configure Multiple PorterLB Replicas

本文档介绍了如何配置多个PorterLB副本以确保生产环境中的高可用性。如果在测试环境中使用PorterLB,则可以跳过此文档。默认情况下,Kubernetes集群中仅安装一个PorterLB副本。

  • 如果所有Kubernetes集群节点都部署在同一路由器(BGP模式或第2层模式)下,建议至少配置两个PorterLB副本,分别安装在两个Kubernetes集群节点上。
  • 如果Kubernetes集群节点部署在不同的叶路由器下(仅BGP模式),则建议在每个叶路由器下至少配置两个PorterLB副本(一个节点一个副本)。有关详细信息,请参阅“为多路由器集群配置PorterLB”

以下步骤中的节点名称和名称空间仅是示例。您需要在您的环境中使用实际值。

  1. 登录Kubernetes集群并运行以下命令来标记要安装PorterLB的Kubernetes集群节点:

    kubectl label --overwrite nodes master1 worker-p002 lb.kubesphere.io/v1alpha1=porter
    

    笔记

    在此示例中,PorterLB将安装在master1和worker-p002上。

  2. 运行以下命令,将porter-manager Pod的数量缩放为0:

    kubectl scale deployment porter-manager --replicas=0 -n porter-system
    
  3. 运行以下命令以编辑porter-manager部署:

    kubectl edit deployment porter-manager -n porter-system
    
  4. 在porter-manager部署YAML配置中,在以下位置添加以下字段spec.template.spec

    nodeSelector:
      kubernetes.io/os: linux
      lb.kubesphere.io/v1alpha1: porter
    
  5. 运行以下命令以将porter-manager Pod的数量缩放为所需的数量(将其更改2为实际值):

    kubectl scale deployment porter-manager --replicas=2 -n porter-system
    
  6. 运行以下命令,检查PorterLB是否已安装在所需的节点上。

    kubectl get po -n porter-system -o wide
    

    验证配置结果

笔记

  • 在第2层模式下,PorterLB使用Kubernetes的领导者选举功能来确保只有一个副本响应ARP / NDP请求。
  • 在BGP模式下,默认情况下,所有PorterLB副本将响应BgpPeer配置,并尝试与对等BGP路由器建立BGP连接。如果Kubernetes集群节点部署在其他路由器下,则需要执行进一步的配置,以便PorterLB副本与正确的BGP路由器建立BGP连接。有关详细信息,请参阅“为多路由器集群配置PorterLB”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值