Calico是k8s诸多网络解决方案中比较优秀的一种,使用起来比较容易,且性能也很优秀,支持IPIP的隧道模式,也支持基于路由的全三层方案,特别是三层方案由于不需要额外的隧道开销,使其性能优秀,路由方案只支持BGP路由,这可能多少限制了一些其使用场景,特别是如果企业现有路由方案不是BGP的话,涉及到比较复杂的路由设计与分发考虑,但是由于k8s平台大部分情况下会是独立建设,因此对于数据中心运维人员来说,单纯的路由问题将会是比较熟悉的领域,因此建设难度并不会过于复杂。
F5是应用交付领域的领导者,凭借其优秀的3-7层控制性使得F5非常适合对应用进行发布和控制,典型的表现在应用路由控制、应用协议控制、灰度发布等。 F5通过在k8s环境下运行控制容器实现与k8s等容器方案的集成,可以替换或增强k8s现有的业务服务发布方法,例如替换Ingress Controller或将cluster方式的service发布到F5 BIGIP上,充分发挥F5服务接入的高级功能,如应用安全、复杂协议控制、应用级监控检查、限流、应用可视化等,对比Nginx有多达20-30种场景可以更好的让k8s适应企业复杂应用场景。
以下测试模拟Calico BGP路由协议与F5动态路由实现F5直接互通容器pod网络,实现F5对K8S服务的直接发布。
两台k8s主机,启用calico BGP路由方案。 k8s主机在同一个2层网络,F5也在同一个2层,模拟基于以太网模型的calico BGP方案。

1.Calico关闭ipip模式,改为使用BGP路由模式。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | [root@k8s-master calico]# calicoctl get bgpPeer -o yaml apiVersion: projectcalico.org/v3 items: - apiVersion: projectcalico.org/v3   kind: BGPPeer   metadata:     creationTimestamp: 2019-01-04T15:36:59Z     name: bgppeer-global-f5-1     resourceVersion: "9530940"     uid: 92ecf52a-1036-11e9-bf61-005056b34685   spec:     asNumber: 64512     peerIP: 172.16.40.202 kind: BGPPeerList metadata:   resourceVersion: "9531851" [root@k8s-master calico]# calicoctl get node -o yaml apiVersion: projectcalico.org/v3 items: - apiVersion: projectcalico.org/v3   kind: Node   metadata:     creationTimestamp: 2018-08-05T14:42:30Z     name: k8s-master     resourceVersion: "9531878"     uid: c7b4efba-98bd-11e8-aeed-000c29850765   spec:     bgp:       ipv4Address: 172.16.40.199/24       ipv4IPIPTunnelAddr: 10.244.0.1 - apiVersion: projectcalico.org/v3   kind: Node   metadata:     creationTimestamp: 2018-08-05T17:10:45Z     name: k8s-node1     resourceVersion: "9531882"     uid: 7dff767b-98d2-11e8-aeed-000c29850765   spec:     bgp:       ipv4Address: 172.16.40.198/24       ipv4IPIPTunnelAddr: 10.244.1 [root@k8s-master calico]# calicoctl get ipPool -o yaml apiVersion: projectcalico.org/v3 items: - apiVersion: projectcalico.org/v3   kind: IPPool   metadata:     creationTimestamp: 2019-01-04T12:05:32Z     name: default-ipv4-ippool     resourceVersion: "9524594"     uid: 08ffa4b6-1019-11e9-9cec-005056b34685   spec:     blockSize: 26     cidr: 10.244.0.0/16     ipipMode: Never     natOutgoing: true kind: IPPoolList metadata:   resourceVersion: "9531814" | 
2.配置calico 全局 bgp peer
| 1 2 3 4 5 6 7 8 9 10 | [root@k8s-master calico]# cat global-bgp-peer.yaml  apiVersion: projectcalico.org/v3 kind: BGPPeer metadata:   name: bgppeer-global-f5-1 spec:   peerIP: 172.16.40.202   asNumber: 64512 [root@k8s-master calico]# calicoctl apply -f global-bgp-peer.yaml  | 
3.F5上配置:
1). 在route domain下启动 BGP
2). 进入路由模块做最简配置:
| 1 2 3 4 5 6 7 8 | [myf5@v13-common:Active:Not All Devices Synced] config # imish v13-common.lab.f5se.io[0]>en v13-common.lab.f5se.io[0]#configure terminal  Enter configuration commands, one per line.  End with CNTL/Z. v13-common.lab.f5se.io[0](config)#router bgp 64512 v13-common.lab.f5se.io[0](config-router)#neighbor 172.16.40.199 remote-as 64512 v13-common.lab.f5se.io[0](config-router)#neighbor 172.16.40.198 remote-as 64512 v13-common.lab.f5se.io[0](config-router)#redistribute kernel | 
3.1 bgp邻居建立后
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | v13-common.lab.f5se.io[0]#show ip bgp neighbors  BGP neighbor is 172.16.40.198, remote AS 64512, local AS 64512, internal link   BGP version 4, remote router ID 172.16.40.198   BGP state = Established, up for 00:22:23   Last read 00:22:23, hold time is 90, keepalive interval is 30 seconds   Neighbor capabilities:     Route refresh: advertised and received (new)     Address family IPv4 Unicast: advertised and received   Received 78 messages, 2 notifications, 0 in queue   Sent 78 messages, 0 notifications, 0 in queue   Route refresh request: received 0, sent 0   Minimum time between advertisement runs is 5 seconds  For address family: IPv4 Unicast   BGP table version 11, neighbor version 11   Index 1, Offset 0, Mask 0x2   AF-dependant capabilities:     Graceful restart: advertised, received   Community attribute sent to this neighbor (both)   1 accepted prefixes   2 announced prefixes  Connections established 3; dropped 2  Graceful-restart Status:   Remote restart-time is 120 sec Local host: 172.16.40.202, Local port: 36730 Foreign host: 172.16.40.198, Foreign port: 179 Nexthop: 172.16.40.202 Nexthop global: fe80::250:56ff:feb3:cb7c Nexthop local: :: BGP connection: non shared network Last Reset: 00:23:43, due to BGP Notification received Notification Error Message: (Cease/Peer Unconfigured.) BGP neighbor is 172.16.40.199, remote AS 64512, local AS 64512, internal link   BGP version 4, remote router ID 172.16.40.199   BGP state = Established, up for 00:22:15   Last read 00:22:15, hold time is 90, keepalive interval is 30 seconds   Neighbor capabilities:     Route refresh: advertised and received (new)     Address family IPv4 Unicast: advertised and received   Received 77 messages, 2 notifications, 0 in queue   Sent 78 messages, 0 notifications, 0 in queue   Route refresh request: received 0, sent 0   Minimum time between advertisement runs is 5 seconds  For address family: IPv4 Unicast   BGP table version 11, neighbor version 11   Index 2, Offset 0, Mask 0x4   AF-dependant capabilities:     Graceful restart: advertised, received   Community attribute sent to this neighbor (both)   1 accepted prefixes   2 announced prefixes  Connections established 3; dropped 2  Graceful-restart Status:   Remote restart-time is 120 sec Local host: 172.16.40.202, Local port: 35752 Foreign host: 172.16.40.199, Foreign port: 179 Nexthop: 172.16.40.202 Nexthop global: fe80::250:56ff:feb3:cb7c Nexthop local: :: BGP connection: non shared network Last Reset: 00:23:43, due to BGP Notification received Notification Error Message: (Cease/Peer Unconfigured.) | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | v13-common.lab.f5se.io[0]#sh ip route Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP        O - OSPF, IA - OSPF inter area        N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2        E1 - OSPF external type 1, E2 - OSPF external type 2        i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area        * - candidate default C       10.244.0.0/16 is directly connected, flannel_vxlan B       10.244.0.0/24 [200/0] via 172.16.40.199, int_vlan, 00:22:53 B       10.244.1.0/24 [200/0] via 172.16.40.198, int_vlan, 00:23:01 C       127.0.0.1/32 is directly connected, lo C       127.1.1.254/32 is directly connected, tmm C       172.16.10.0/24 is directly connected, bigip_cc_vlan C       172.16.30.0/24 is directly connected, ext_vlan C       172.16.40.0/24 is directly connected, int_vlan K       172.16.40.81/32 [0/0] is directly connected, tmm K       172.16.99.99/32 [0/0] is directly connected, tmm | 
可以看到F5上已经有到pod的BGP路由了
3.2 如果尝试将F5 VIP 注入到BGP的话,可以在k8s节点上看到VIP的路由
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [root@k8s-master calico]# ip route default via 172.16.10.254 dev ens33 proto static metric 100  default via 172.16.40.254 dev ens160 proto dhcp metric 101  blackhole 10.244.0.0/24 proto bird  10.244.0.76 dev cali7adc62d51c0 scope link  10.244.0.77 dev cali0761ccbeace scope link  10.244.0.78 dev calicd88c4c95c8 scope link  10.244.0.79 dev cali3b3d3e2702c scope link  10.244.0.80 dev calif1c9cee6be2 scope link  10.244.0.81 dev calie89075bc69f scope link  10.244.1.0/24 via 172.16.40.198 dev ens160 proto bird  172.16.0.0/16 dev ens33 proto kernel scope link src 172.16.10.201 metric 100  172.16.40.0/24 dev ens160 proto kernel scope link src 172.16.40.199 metric 101  172.16.40.81 via 172.16.40.202 dev ens160 proto bird <<<<<<! 172.16.99.99 via 172.16.40.202 dev ens160 proto bird <<<<<<<! 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1  | 
4. 做一些ping测试进行验证:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | K8S节点ping VS IP [root@k8s-master calico]# ping 172.16.99.99 PING 172.16.99.99 (172.16.99.99) 56(84) bytes of data. 64 bytes from 172.16.99.99: icmp_seq=1 ttl=255 time=0.190 ms 64 bytes from 172.16.99.99: icmp_seq=2 ttl=255 time=0.224 ms 到一个容器里ping VSIP [root@k8s-master calico]# kubectl exec -it busybox2-54b7b7cd58-gn8pf sh / # ip route default via 169.254.1.1 dev eth0  169.254.1.1 dev eth0 scope link  / # ping 172.16.99.99 PING 172.16.99.99 (172.16.99.99): 56 data bytes 64 bytes from 172.16.99.99: seq=0 ttl=254 time=1.543 ms 64 bytes from 172.16.99.99: seq=1 ttl=254 time=0.253 ms ^C F5上ping pod的IP [myf5@v13-common:Active:Not All Devices Synced] config # ping 10.244.1.37 PING 10.244.1.37 (10.244.1.37) 56(84) bytes of data. 64 bytes from 10.244.1.37: icmp_seq=1 ttl=63 time=0.797 ms 64 bytes from 10.244.1.37: icmp_seq=2 ttl=63 time=0.429 ms ^C --- 10.244.1.37 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1101ms rtt min/avg/max/mdev = 0.429/0.613/0.797/0.184 ms [myf5@v13-common:Active:Not All Devices Synced] config # ping 10.244.0.81 PING 10.244.0.81 (10.244.0.81) 56(84) bytes of data. 64 bytes from 10.244.0.81: icmp_seq=1 ttl=63 time=0.566 ms 64 bytes from 10.244.0.81: icmp_seq=2 ttl=63 time=0.523 ms | 
5. 部署F5 bigip ctlr 容器,以及发布一个configmap 资源
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | [root@k8s-master f5-k8s]# cat bigip-ctlr-deployment-calico.yaml  apiVersion: extensions/v1beta1 kind: Deployment metadata:   name: k8s-bigip-ctlr-deployment   namespace: kube-system spec:   # DO NOT INCREASE REPLICA COUNT   replicas: 1   template:     metadata:       name: k8s-bigip-ctlr-calico       labels:         app: k8s-bigip-ctlr-calico     spec:       # Name of the Service Account bound to a Cluster Role with the required       # permissions       serviceAccountName: bigip-ctlr       containers:         - name: k8s-bigip-ctlr-calico           image: "myf5/k8s-bigip-ctlr:1.7.1"           env:             - name: BIGIP_USERNAME               valueFrom:                 secretKeyRef:                   # Replace with the name of the Secret containing your login                   # credentials                   name: bigip-login                   key: username             - name: BIGIP_PASSWORD               valueFrom:                 secretKeyRef:                   # Replace with the name of the Secret containing your login                   # credentials                   name: bigip-login                   key: password             - name: TZ               value: Asia/Shanghai           command: ["/app/bin/k8s-bigip-ctlr"]           args: [             # See the k8s-bigip-ctlr documentation for information about             # all config options             # https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest             "--bigip-username=$(BIGIP_USERNAME)",             "--bigip-password=$(BIGIP_PASSWORD)",             "--bigip-url=172.16.20.202",             "--bigip-partition=k8s",             "--namespace=default",             "--pool-member-type=cluster",             ]       imagePullSecrets:         # Secret containing the BIG-IP system login credentials         - name: bigip-login [root@k8s-master f5-k8s]# kubectl create -f bigip-ctlr-deployment-calico.yaml [root@k8s-master f5-k8s]# kubectl create -f f5-vs.yaml  configmap "nginx-deploy-svc.vs" created [root@k8s-master f5-k8s]# cat f5-vs.yaml  kind: ConfigMap apiVersion: v1 metadata:   name: nginx-deploy-svc.vs   labels:     f5type: virtual-server data:   # See the f5-schema table for schema-controller compatibility   # https://clouddocs.f5.com/containers/latest/releases_and_versioning.html#f5-schema   schema: "f5schemadb://bigip-virtual-server_v0.1.7.json"   data: |     {       "virtualServer": {         "backend": {           "servicePort": 80,           "serviceName": "nginx-deploy-svc",           "healthMonitors": [{             "interval": 15,             "protocol": "http",             "send": "GET / HTTP/1.1\r\nConnection: close\r\nHost: 1.1.1.1\r\n\r\n",             "recv": "cka",             "timeout": 30           }]         },         "frontend": {           "virtualAddress": {             "port": 80,             "bindAddr": "172.16.40.80"           },           "partition": "k8s",           "balance": "least-connections-member",           "mode": "http"         }       }     } [root@k8s-master f5-k8s]# kubectl create -f f5-vs.yaml  configmap "nginx-deploy-svc.vs" created | 


6. 其它输出:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | [root@k8s-master f5-k8s]# calicoctl node status Calico process is running. IPv4 BGP status +---------------+-------------------+-------+----------+-------------+ | PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     | +---------------+-------------------+-------+----------+-------------+ | 172.16.40.198 | node-to-node mesh | up    | 14:02:04 | Established | | 172.16.40.202 | global            | up    | 15:37:55 | Established | +---------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found. Bird里的BGP配置 / # cat  /etc/calico/confd/config/bird.cfg # Generated by confd include "bird_aggr.cfg"; include "bird_ipam.cfg"; router id 172.16.40.199; # Configure synchronization between routing tables and kernel. protocol kernel {   learn;             # Learn all alien routes from the kernel   persist;           # Don't remove routes on bird shutdown   scan time 2;       # Scan kernel routing table every 2 seconds   import all;   export filter calico_kernel_programming; # Default is export none   graceful restart;  # Turn on graceful restart to reduce potential flaps in                      # routes when reloading BIRD configuration.  With a full                      # automatic mesh, there is no way to prevent BGP from                      # flapping since multiple nodes update their BGP                      # configuration at the same time, GR is not guaranteed to                      # work correctly in this scenario. } # Watch interface up/down events. protocol device {   debug { states };   scan time 2;    # Scan interfaces every 2 seconds } protocol direct {   debug { states };   interface -"cali*", "*"; # Exclude cali* but include everything else. } # Template for all BGP clients template bgp bgp_template {   debug { states };   description "Connection to BGP peer";   local as 64512;   multihop;   gateway recursive; # This should be the default, but just in case.   import all;        # Import all routes, since we don't know what the upstream                      # topology is and therefore have to trust the ToR/RR.   export filter calico_export_to_bgp_peers;  # Only want to export routes for workloads.   source address 172.16.40.199;  # The local address we use for the TCP connection   add paths on;   graceful restart;  # See comment in kernel section about graceful restart.   connect delay time 2;   connect retry time 5;   error wait time 5,30; } # ------------- Node-to-node mesh ------------- # For peer /host/k8s-master/ip_addr_v4 # Skipping ourselves (172.16.40.199) # For peer /host/k8s-node1/ip_addr_v4 protocol bgp Mesh_172_16_40_198 from bgp_template {   neighbor 172.16.40.198 as 64512; } # ------------- Global peers ------------- # For peer /global/peer_v4/172.16.40.202 protocol bgp Global_172_16_40_202 from bgp_template {   neighbor 172.16.40.202 as 64512; } # ------------- Node-specific peers ------------- # No node-specific peers configured. | 
对于F5在k8s上的网络模型对接选型:
•如果一定要考虑隧道模型,那么选flannel vxlan (canal也可以),vxlan模型F5上需要注入太多静态arp条目,当容器实例很多的时候这是一个需要考虑的问题
•如果集群规模很小,flannel host-gw可选,F5上使用静态路由指向各个pod网络
•Calico的BGP路由模型适合较大的k8s集群,网络上对接更容易,F5路由模块可直接互通pod网络。 同时还可以继续保留Calico的对networ policy支持属性,可以实现较好的容器访问控制,加上F5的分区配置隔离,可以比较方便的实现租户隔离。 关于租户隔离方面文章请参考博客中其它文章。
•且双机时候不用考虑 flannel vxlan模型下备机tunnel不建立问题。
•Calico由于是动态路由,pod本身也可以访问F5注入的vip, 这样很适合让容器访问其它外部的资源。且calico在路由模式下性能很好,推荐优先考虑calico
 
                
文章评论