之前详细介绍了calico的ipip、vxlan、bgp模式, 但是所有的k8s节点都是同网段的, 本篇使用ensp和workstation在自己家里就可以模拟测试跨网段k8s集群calico方案的纯bgp模式。

 Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问) k8s集群 第1张

之前详细介绍了Calico的ipip、vxlan、bgp模式, 但是所有的k8s节点都是同网段的, 本篇使用Ensp和workstation在自己家里就可以模拟测试跨网段k8s集群calico方案的纯bgp模式。

架构搭建

本测试搭建的是"每机柜独立自治系统"架构, 参考:The *AS Per Rack* model[1]

 Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问) k8s集群 第2张

跨网段k8s集群架构

整个架构分为ensp部分和workstation部分, ensp部分主要是搭建出R1和R2的ebgp关系以及分别在R1和R2上添加各自网段内的k8s节点的bgp peer,workstation部分为构建跨网端的k8s集群。因为192.168.219.0/24网段的主机加入集群需要依赖ensp中的路由, 操作的顺序是先搭建出ensp的网络部分再将新节点加到k8s中继而配置bgp。现有k8s集群有三台服务器均通过桥接联网, 一台master节点两台普通节点, 分别如下

  • k8s-master:10.30.81.127
  • k8s-node1:10.30.81.128
  • k8s-node2:10.30.81.130

ensp配置

按照上图搭建出ensp部分的网络设备连接拓扑, 然后分别配置R1、R2和两朵云, R1和R2上配置如下

  1. :'
  2. R1上配置
  3. '
  4. #接口ip配置
  5. intg0/0/0
  6. ipa20.20.20.1024
  7. intg0/0/1
  8. ipa10.30.81.11824
  9. intg0/0/2
  10. ipa30.30.30.1024
  11. #设置静态路由,跳到下一个网段
  12. iproute-static192.168.219.02420.20.20.20
  13. iproute-static192.168.219.02430.30.30.20
  14. #bgp配置,把同AS内的ibgppeer也配置了
  15. bgp64512
  16. peer10.30.81.127as-number64512
  17. peer10.30.81.128as-number64512
  18. peer10.30.81.130as-number64512
  19. peer192.168.219.10as-number64513
  20. peer192.168.219.10ebgp-max-hop5
  21. peer192.168.219.10connect-interfaceg0/0/1
  22. peer10.30.81.127reflect-client
  23. peer10.30.81.128reflect-client
  24. peer10.30.81.130reflect-client
  25. displaybgppeer
  26. displaybgpip-routing
  27. displayipinterfacebr
  28. displayiprouting-table
  29. :'
  30. R2上配置
  31. '
  32. #接口ip配置
  33. intg0/0/0
  34. ipa192.168.219.1024
  35. intg0/0/1
  36. ipa20.20.20.2024
  37. intg0/0/2
  38. ipa30.30.30.2024
  39. #设置静态路由,跳到下一个网段
  40. iproute-static10.30.81.02420.20.20.10
  41. iproute-static10.30.81.02430.30.30.10
  42. #bgp配置,把同AS内的ibgppeer也配置了
  43. bgp64513
  44. peer10.30.81.118as-number64512
  45. peer10.30.81.118ebgp-max-hop5
  46. peer10.30.81.118connect-interfaceg0/0/0
  47. peer192.168.219.20as-number64513
  48. peer192.168.219.40as-number64513
  49. peer192.168.219.20reflect-client
  50. peer192.168.219.40reflect-client
  51. displaybgppeer
  52. displaybgpip-routing
  53. displayipinterfacebr
  54. displayiprouting-table

按如上配置好后R1和R2, 并且配置好两朵云后, 在R2上ping 10.30.81.118是可以成功的了, 并且我们也可以观察到R1和R2已经建立起了EBGP关系。但是从R2上ping k8s集群的任何一台主机都不通, 而是会报host unreachable, 因为k8s节点主机上并没有回程路由, 它们并不知道将icmp的replay包发往往R1, 因此需要在三台主机上添加路由

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33

在k8s所有节点添加了如上的路由就可以在R2上ping通所有的k8s节点了

新机器加入k8s集群

创建虚机并配置它的网络为nat模式,配置它们的网卡和路由, 注意不要让它们有10.30.81.0/24网段的路由指向vmnet8。网卡配置如下

  1. #网卡配置如下
  2. [root@k8s-node4~]#catifcfg-ens33
  3. TYPE=Ethernet
  4. DNS1=8.8.8.8
  5. IPADDR=192.168.219.40
  6. NETMASK=255.255.255.0
  7. GATEWAY=192.168.219.10
  8. BOOTPROTO=static
  9. DEFROUTE=yes
  10. IPV4_FAILURE_FATAL=no
  11. NAME=ens33
  12. UUID=6ef9b5bf-31c1-43b9-89d6-b8e89ab3c9c3
  13. DEVICE=ens33
  14. ONBOOT=yes
  15. #下面的路由可以不加
  16. routeadd-net10.30.81.0/24gw192.168.219.10devens33

之后就是节点加入k8s的准备

系统配置, 如下

  1. echo"StopFirewalld"
  2. systemctlstopfirewalld
  3. systemctldisablefirewalld
  4. sed-ie's/SELINUX=enforcing/SELINUX=disabled/g'/etc/selinux/config
  5. setenforce0
  6. echo"net.ipv4.ip_forward=1">>/etc/sysctl.conf
  7. echo"net.bridge.bridge-nf-call-ip6tables=1">>/etc/sysctl.conf
  8. echo"net.bridge.bridge-nf-call-iptables=1">>/etc/sysctl.conf
  9. echo"net.bridge.bridge-nf-call-arptables=1">>/etc/sysctl.conf
  10. swapoff-a
  11. echoswapoff-a>>/etc/rc.local
  12. sysctl-p

从已k8s集群节点中将kubeadm、kubelet、kubectl的二进制文件拷贝到/usr/bin目录下,设置kubelet开机自启,kubelet的配置如下

  1. [Unit]
  2. Description=kubelet:TheKubernetesNodeAgent
  3. Documentation=https://kubernetes.io/docs/
  4. Wants=network-online.target
  5. After=network-online.target
  6. [Service]
  7. ExecStart=/usr/bin/kubelet--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf--kubeconfig=/etc/kubernetes/kubelet.conf--config=/var/lib/kubelet/config.yaml--network-plugin=cni--pod-infra-container-image=k8s.gcr.io/pause:3.2--fail-swap-on=false
  8. Restart=always
  9. StartLimitInterval=0
  10. RestartSec=10
  11. [Install]
  12. WantedBy=multi-user.target

安装docker

从已有k8s集群节点中将calico相关的容器镜像、kube-proxy镜像导出并给导入到新节点中。集群已经存在了, k8s控制平面的apiserver、etcd、controller-manager、scheduler镜像可以不拷到新节点。

使用kubeadm将新节点加入k8s集群

验证跨网段之间的通信是走了ensp网络的, 从k8s-master上跟踪到k8s-node3的路由路径, 下一跳中存在20.20.20.20为R2的接口

  1. [root@k8s-master~]#traceroute192.168.219.20
  2. tracerouteto192.168.219.20(192.168.219.20),30hopsmax,60bytepackets
  3. 110.30.81.118(10.30.81.118)18.396ms79.412ms79.396ms
  4. 220.20.20.20(20.20.20.20)79.387ms79.380ms83.814ms
  5. 3k8s-node3(192.168.219.20)108.104ms112.777ms117.847ms

通过如上搭建出了5节点的跨网段k8s集群, 如下

  1. [root@k8s-node4~]#kubectlgetnode-owide
  2. NAMESTATUSROLESAGEVERSIONINTERNAL-IP
  3. k8s-masterReadycontrol-plane,master45dv1.20.010.30.81.127
  4. k8s-node1Ready<none>45dv1.20.010.30.81.128
  5. k8s-node2Ready<none>9dv1.20.010.30.81.130
  6. k8s-node3Ready<none>20hv1.20.0192.168.219.20
  7. k8s-node4Ready<none>20hv1.20.0192.168.219.40

calico配置bgp

配置bgp需要使用calicoctl工具, 自己准备好, 配置bgp主要分为以下步骤

  1. 确认calico部署是纯BGP模式
  2. 关闭BGP默认的full mesh模式
  3. 修改指定主机k8s-node3和k8s-node4的bgp as number值为64513
  4. 给所有主机打标签进行bgp as分组, 满足bpg peer选择特定的peer对等体
  5. 创建bgp peer, 通过第四步打的标签让rr client与rr建立ibgp关系

确认calico-node的如下两个配置为Never

  1. -name:CALICO_IPV4POOL_IPIP
  2. value:"Never"
  3. -name:CALICO_IPV4POOL_VXLAN
  4. value:"Never"

calico的bgp模式默认是full mesh的, 将其关闭

  1. calicoctlgetbgpconfigurationdefault-oyaml
  2. apiVersion:projectcalico.org/v3
  3. items:
  4. -apiVersion:projectcalico.org/v3
  5. kind:BGPConfiguration
  6. metadata:
  7. creationTimestamp:"2021-09-05T06:23:50Z"
  8. name:default
  9. resourceVersion:"555583"
  10. uid:9438105f-cdd8-4315-8694-6d4885c76c85
  11. spec:
  12. logSeverityScreen:Info
  13. nodeToNodeMeshEnabled:false#修改为false后calicoctlapply-fbgpconfiguration.yaml
  14. kind:BGPConfigurationList
  15. metadata:
  16. resourceVersion:"580613"

将calico节点k8s-node3和k8s-node4的bgp as number设置为64513

  1. calicoctlgetnodek8s-node3-oyaml>node3.yaml
  2. apiVersion:projectcalico.org/v3
  3. kind:Node
  4. metadata:
  5. annotations:
  6. projectcalico.org/kube-labels:'{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"k8s-node3","kubernetes.io/os":"linux"}'
  7. creationTimestamp:"2021-09-04T14:03:35Z"
  8. labels:
  9. beta.kubernetes.io/arch:amd64
  10. beta.kubernetes.io/os:linux
  11. kubernetes.io/arch:amd64
  12. kubernetes.io/hostname:k8s-node3
  13. kubernetes.io/os:linux
  14. name:k8s-node3
  15. resourceVersion:"580885"
  16. uid:64f44ad1-f537-43f3-9f0e-d5d5b80adba2
  17. spec:
  18. addresses:
  19. -address:192.168.219.20/24
  20. type:CalicoNodeIP
  21. -address:192.168.219.20
  22. type:InternalIP
  23. bgp:
  24. asNumber:64513#添加这一行
  25. ipv4Address:192.168.219.20/24
  26. orchRefs:
  27. -nodeName:k8s-node3
  28. orchestrator:k8s
  29. status:
  30. podCIDRs:
  31. -10.244.4.0/24

给节点打标签

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33
0

创建calico的bgp peer实例, 因为在ensp配置部分已经在R1、R2上配置好了RR模式。在RR模式下我们选择将所有的k8s节点都作为rr的client, 因此同意as下的k8s节点间不需要再建立ibgp对等体关系,剩下的则让各自as的k8s节点分别和R1与R2建立ibgp关系即可

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33
1

验证bgp路由宣告和pod间通信

使用标签在各个节点行创建pod, 然后找跨网端的两台主机的pod进行ping通信并抓包。创建pod

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33
2

看看创建出来的pod的分布情况

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33
3

在bird客户端看看学习到的bgp路由, 在k8s-master节点上操作, 其自身pod子网段为:10.244.235.192/26

 Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问) k8s集群 第3张

rr路由宣告

在ensp网络的R1上其应该能学习到所有k8s节点的pod子网对应的子网段路由

 Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问) k8s集群 第4张

R1学习的bgp路由

接着通过跨网段节点的pod间通信抓包验证, as64512的k8s-master节点的pod master与as64513的k8s-node3的pod node3间通信抓包, 在R2上抓包

  1. #此时添加如下路由也不会有效,因为从R2上发出来的ping包源ip不是192.1168.219.0/24网段的
  2. routeadd-n192.168.219.0/24gw10.30.81.118devens33
  3. echorouteadd-n192.168.219.0/24gw10.30.81.118devens33>>/etc/rc.local
  4. iprouteadd192.168.219.0/24via10.30.81.118devens33
  5. #添加如下路由才会在R2上ping通现有k8s集群节点。可以在ping通后删除掉,因为R2只是中间节点而已
  6. routeadd-n20.20.20.0/24gw10.30.81.118devens33
  7. routeadd-n30.30.30.0/24gw10.30.81.118devens33
4

 Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问) k8s集群 第5张

R2抓包

如上跨节点k8s集群基于bgp实现了pod间的通信

手动维护bgp

实验过程中在ENSP部分有关R1/R2的bgp配置都是手工进行维护的, 针对每机架一个AS的部署模式, 怎么监控到一个AS内的主机的上下线, 然后自动的更新RR上client的信息。

bgp架构的思考

在本篇测试中只建立了"每机架作为一个独立as"架构的测试,该架构中最上层是采用交换机连接, 因此要求所有不同网段中的RR要建立其ebgp关系, 不一定要全互联但是要保证每个RR都可以从某一个RR学到其他剩余的RR宣告的BGP路由。"每机架作为一个独立AS"架构的另一种为最上层为路由器, 他们与所有RR都建立EBGP关系,这样在RR之间就不需要再建立BGP关系了。另外就是考虑路由条目变多后, 哪种架构更合适, 暂未涉及。

问题记录

  • ensp使用云无法找到vmnet8网卡问题, 重装winPcap,重装ensp, 路由和同网段主机突然不通了可能是网卡找不到...
  • ensp路由设备无效问题:见ensp界面右上角菜单查找帮助手册, 删掉页面上的所有设备重新注册, 还是失败考虑重装ensp...
  • workstation在nat模式下无法连接虚机:先查主机上vmnet8网卡的ip地址,在虚拟网络编辑器中设置nat时, 设置的nat范围需要和vmnet8的ip地址在同一网段且网关设置为vmnet8的ip
  • 新增k8s节点在安装必备的工具时可以先切换回桥接联网,然后再切换回nat, 然后在加入k8s集群
  • ensp部分网络配置不通可以直接在路由器R1和R2的两端接口处抓包, 分析哪段不通, 哪段接到请求但是没有响应

本文为原创投稿文章,文章原文:https://larioy.gst.monster/2021/09/05/k8s-ji-chong-cni-fang-an-jie-xi/calico/ensp-mo-ni-calico-kua-wang-duan-bgp-wang-luo/

参考资料

[1]The AS Per Rack model: https://docs.projectcalico.org/reference/architecture/design/l3-interconnect-fabric

转载请说明出处
知优网 » Ensp 模拟 Calico 跨网段 Bgp 网络(ensp跨网段访问)

发表评论

您需要后才能发表评论