it_worker365

   ::  ::  ::  ::  :: 管理

云与IDC

都是多个私网VPC组成云企网,再通过网关/边界路由经过专线到IDC

 

LB云厂商实现原理

阿里云 腾讯云

https://help.aliyun.com/document_detail/27544.html

  • 四层采用开源软件LVS(Linux Virtual Server)+ keepalived的方式实现负载均衡,并根据云计算需求对其进行了个性化定制。
  • 七层采用Tengine实现负载均衡。Tengine是由淘宝网发起的Web服务器项目,它在Nginx的基础上,针对有大访问量的网站需求,添加了很多高级功能和特性。

https://cloud.tencent.com/document/product/214/530

  • 四层主要基于腾讯自研的统一接入网关(Tencent Gateway,TGW)来实现负载均衡,TGW 具有可靠性高、扩展性强、性能高、抗攻击能力强等特点,支持 Data Plane Development Kit(DPDK)高性能转发,单集群可支持亿级并发、千万级 PPS。腾讯内部诸多业务均通过 TGW 接入服务,包括腾讯游戏、腾讯视频、微信、QQ 等。
  • 七层主要基于 Secure Tencent Gateway(STGW)实现负载均衡,STGW 是腾讯基于 Nginx 自研的支持大规模并发的七层负载均衡服务,承载了腾讯内大量的七层业务流量,包括腾讯新闻、理财通、腾讯游戏、微信等。

kube-proxy

在kubernetes集群的每个节点上都运行着kube-proxy进程负责实现Kubernetes中Service组件的虚拟IP服务,常见的两种模型iptables和ipvs。

iptables

创建Service的时候会同时建立两个iptables规则,一个是给Service用,另一个是给Endpoints。给Service用的是为了转发流量给后端,给Endpoints用的是为了选择Pod。

kube-proxy创建Service的时候, 通过 Service 的 Informer 感知到API Server中service和endpoint的变化情况,在宿主机上同时建立两个iptables规则,一个是给Service用,另一个是给Endpoints。给Service用的是为了转发流量给后端,给Endpoints用的是为了选择Pod。集群越大,查询更新规则的性能损耗越大。

ipvs

IPVS 并不需要在宿主机上为每个 Pod 设置 iptables 规则,而是把对这些“规则”的处理放到了内核态,从而极大地降低了维护这些规则的代价。

当proxy启动的时候,proxy将验证节点是否安装ipvs模块,如果没有安装将退回iptables模式。IPVS模式也是基于Netfilter,对比iptables模式在大规模有更好的扩展性和性能。支持更复杂的均衡算法(最小复杂、最少连接、加权等),支持Service的健康检查和连接重试功能。IPVS依赖于iptables,使用iptables进行包过滤,SNAT,masuared。IPVS将使用ipset来存储需要DROP或MASQUARED的流量源地址和目标地址,这样可以保证iptables规则数量固定,不需要关心集群中有多少Service。

kube-Proxy会监视Kubernetes Service对象和Endpoints,调用Netlink接口以相应的创建IPVS规则并定期与Kubernets Service和Endpoints对象同步IPVS规则,以确保IPVS状态和期望状态一直。访问服务时,流量将会被重定向到一个Pod。

实例一

创建一个Service,系统会如何处理,测试针对ipvs类型集群创建一个ClusterIP类型的Service,两个后端Endpoints

后端对应两个Pod

节点上会生成虚拟端口 kube-ipvs0

[root@iZuf634qce0653xtqgbxxmZ ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:2b:7a:71 brd ff:ff:ff:ff:ff:ff
    inet 172.28.127.250/20 brd 172.28.127.255 scope global dynamic eth0
       valid_lft 315090490sec preferred_lft 315090490sec
    inet6 fe80::216:3eff:fe2b:7a71/64 scope link
       valid_lft forever preferred_lft forever
3: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0e:b1:67:c6:7f:3d brd ff:ff:ff:ff:ff:ff
4: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
    link/ether b2:5a:5f:70:36:dd brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.10/32 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    ......
    inet 192.168.113.114/32 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    ......
5: nodelocaldns: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
    link/ether 0e:2c:1c:16:87:65 brd ff:ff:ff:ff:ff:ff
    inet 169.254.20.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever
6: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 72:e9:91:28:05:5e brd ff:ff:ff:ff:ff:ff
    inet 10.16.0.1/26 brd 10.16.0.63 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::70e9:91ff:fe28:55e/64 scope link
       valid_lft forever preferred_lft forever
7: veth349c0776@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master cni0 state UP group default
    link/ether 56:c8:2c:eb:e8:b1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::54c8:2cff:feeb:e8b1/64 scope link
       valid_lft forever preferred_lft forever
......

搜索192.168.113.114,发现分别生成了虚拟服务,和通过rr轮询的后端地址

[root@iZuf634qce0653xtqgbxxmZ ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
 TCP  192.168.113.114:80 rr
  -> 10.16.0.31:80                Masq    1      0          0        
  -> 10.16.0.87:80                Masq    1      0          0        
TCP  192.168.113.114:443 rr
  -> 10.16.0.31:443               Masq    1      0          0        
  -> 10.16.0.87:443               Masq    1      0          0         
.......        
UDP  192.168.0.10:53 rr
  -> 10.16.0.24:53                Masq    1      0          43       
  -> 10.16.0.85:53                Masq    1      0          44

实例二

新建Nodeport类型的服务,信息如下

看下是否同样创建了虚拟映射,是的

[root@iZuf634qce0653xtqgbxxmZ net.d]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
......      
TCP  192.168.48.80:80 rr
  -> 10.16.0.31:80                Masq    1      0          0        
  -> 10.16.0.87:80                Masq    1      0          0        
TCP  192.168.48.80:443 rr
  -> 10.16.0.31:443               Masq    1      0          0        
  -> 10.16.0.87:443               Masq    1      0          0        
......

CNI(Container Network Interface)插件

CNI的目的在于定义一个标准的接口规范,使得kubernetes在增删POD的时候,能够按照规范向CNI实例提供标准的输入并获取标准的输出,再将输出作为kubernetes管理这个POD的网络

  • Kubelet 会首先从 ApiServer 监听到 Pod 的创建,会创建 Pod 的沙箱
  • 然后通过 CNI 接口调用 CNI 的插件去配置容器的网络
  • CNI 会配置 Pod 的网络空间,以及打通不同 Pod 之间的网络访问

CNI插件通过/etc/cni/net.d加载,当前云使用厂商提供默认插件,自建IDC使用Calico

Flannel

Flannel是CoreOS公司开源的CNI网络插件,它的功能是让K8S集群中的不同节点创建的容器都具有全集群唯一的虚拟IP地址。它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,IP分配信息会存于ETCD中。

Flannel通用的Backend类型区分,主要区别是UDP经过用户态,性能低,VXlan不经过用户态,但还是需要隧道技术封包解包,hostgw设置下一跳地址为主机地址

etcd存储子网和宿主机之间的关系,于是flannel0等设备就可以掌握转发路由,现在都是直连apiserver

UDP

flannel0为TUN设备(TUN 在操作系统内核和用户应用程序之间传递 IP 包),收到IP包转发给用户态的flanneld进程,flannel进程通过UDP协议将包发到其他Node,其他flanneld收到解包再用,效率低,淘汰了

VXLAN

在内核态封装,无需TUN设备,通过netlink通知内核建立一个VTEP(VXLAN Tunnel End Point(虚拟隧道端点))的网卡flannel.1,在内核态完成封包解封,flanneld初始化ip->mac关系,维护fdb数据,二层mac通过ARP获取,再从mac到ip,从而完成跨主机通讯

Host-gw

通过主机路由的方式,将请求发送到容器外部的应用,但是有个约束就是宿主机要和其他物理机在同一个vlan或者局域网中,这种模式不需要封包和解包,因此更加高效。

阿里云

以阿里云为例,以下大部分内容来自阿里云文档

kubernates和云之间如何做到联动、优化的?

  • 比如创建一个loadbalance类型的service,是如何创建对应的阿里云LB实例且关联的?
  • 比如云厂商提供的CNI插件为啥宣称比开源的性能要好?优化在哪里?

创建阿里云ACK集群后,如果是托管模式,整个管理节点是被云托管的,所以看不到管理节点,但通过组件管理页面,可以看到默认安装了系统组件Cloud Controller Manager,文档功能描述也比较清晰了

Cloud Controller Manager提供Kubernetes与阿里云基础产品的对接能力,例如CLB(原SLB)、VPC等。CCM主要提供以下功能:

  • 管理负载均衡

    当Service的类型设置为Type=LoadBalancer时,CCM组件会为该Service创建或配置阿里云负载均衡CLB,包括含CLB、监听、后端服务器组等资源。当Service对应的后端Endpoint或者集群节点发生变化时,CCM会自动更新CLB的后端虚拟服务器组。

  • 实现跨节点通信

    当集群网络组件为Flannel时,CCM组件负责打通容器与节点间网络,实现容器跨节点通信。CCM会将节点的Pod网段信息写入VPC的路由表中,从而实现跨节点的容器通信。该功能无需配置,安装即可使用。

CCM文档 

ACK安装时,阿里云可选两种网络模式可选Flannel或Terway

 

 

网络模型

ACK的Flannel插件采用的是阿里云VPC模式,报文经过阿里云VPC的路由表直接转发,不需要Vxlan等隧道封装技术封装报文,所以比Flannel默认的Vxlan模式具有更高的通信性能

每个节点需要对应一个VPC的路由表条目

 

 

Flannel文档 

实际配置

新增cni0网桥,目标为10.50.1.128/25的访问路由到cni0,再转到pod

 容器内对应的外部网卡为veth3b068382

root@bff-gift-service-v0-84c99798d6-26pw8:/# cat /sys/class/net/eth0/iflink
131
 
[root@ali-prod-bff-live-more-0002 /]# ip link | grep -A 1 131
131: veth3b068382@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master cni0 state UP mode DEFAULT group default
    link/ether 26:30:6b:b1:7d:af brd ff:ff:ff:ff:ff:ff link-netnsid 6
 
[root@ali-prod-bff-live-more-0002 /]# ifconfig
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.50.1.129  netmask 255.255.255.128  broadcast 10.50.1.255
        inet6 fe80::acb1:72ff:fefe:5808  prefixlen 64  scopeid 0x20<link>
        ether ae:b1:72:fe:58:08  txqueuelen 1000  (Ethernet)
        RX packets 15855360759  bytes 28152973539857 (25.6 TiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18662545884  bytes 50106349648702 (45.5 TiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 169.254.123.1  netmask 255.255.255.0  broadcast 169.254.123.255
        ether 02:42:5d:35:2c:a1  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.126.44.1  netmask 255.255.254.0  broadcast 10.126.45.255
        inet6 fe80::216:3eff:fe04:f044  prefixlen 64  scopeid 0x20<link>
        ether 00:16:3e:04:f0:44  txqueuelen 1000  (Ethernet)
        RX packets 47299822878  bytes 52009596870995 (47.3 TiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15870629225  bytes 28473012734415 (25.8 TiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 206578406  bytes 41531785821 (38.6 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 206578406  bytes 41531785821 (38.6 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth17c6a045: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c852:a7ff:feea:db79  prefixlen 64  scopeid 0x20<link>
        ether ca:52:a7:ea:db:79  txqueuelen 0  (Ethernet)
        RX packets 1649108222  bytes 1061560042794 (988.6 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2408831694  bytes 1559058233935 (1.4 TiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth33d81a46: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::a00a:79ff:fef6:4580  prefixlen 64  scopeid 0x20<link>
        ether a2:0a:79:f6:45:80  txqueuelen 0  (Ethernet)
        RX packets 30004746  bytes 5482022016 (5.1 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 32532180  bytes 7542843349 (7.0 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth39b96269: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::4870:6bff:fe77:31af  prefixlen 64  scopeid 0x20<link>
        ether 4a:70:6b:77:31:af  txqueuelen 0  (Ethernet)
        RX packets 64426153  bytes 133130314688 (123.9 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 72122493  bytes 30702560591 (28.5 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth3b068382: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::2430:6bff:feb1:7daf  prefixlen 64  scopeid 0x20<link>
        ether 26:30:6b:b1:7d:af  txqueuelen 0  (Ethernet)
        RX packets 27844048  bytes 175916392954 (163.8 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29608187  bytes 7968825461 (7.4 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
veth3bfa9e82: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
......

Terway 

  • Terway网络插件是ACK自研的容器网络接口(CNI)插件,基于阿里云的弹性网卡(ENI)构建网络,可以充分使用云上资源。Terway支持eBPF对网络流量进行加速,降低延迟,支持基于Kubernetes标准的网络策略(Network Policy)来定义容器间的访问策略。
  • 在Terway网络插件中,每个Pod都拥有自己网络栈和IP地址。同一台ECS内的Pod之间通信,直接通过机器内部的转发,跨ECS的Pod通信、报文通过VPC的弹性网卡直接转发。由于不需要使用VxLAN等的隧道技术封装报文,因此Terway模式网络具有较高的通信性能。

Terway文档

Calico

https://www.projectcalico.org/

主要组件

  • Felix:运行在每个需要运行workload的节点上的agent进程。主要负责配置路由及 ACLs(访问控制列表) 等信息来确保 endpoint 的连通状态,保证跨主机容器的网络互通;
  • BGP Client(BIRD):读取Felix设置的内核路由状态,在数据中心分发状态。
  • BGP Route Reflector(BIRD):BGP路由反射器,在较大规模部署时使用。如果仅使用BGP Client形成mesh全网互联就会导致规模限制,因为所有BGP client节点之间两两互联,需要建立N^2个连接,拓扑也会变得复杂。因此使用reflector来负责client之间的连接,防止节点两两相连。

查看calico-node相关组件,启动组件BIRD、Felix

其他信息忽略,通过命令行或CRD可见

其他基础概念 

二层网络 OSI网络模型的数据链路层,处理网络上两个相邻节点的帧传递,mac地址为子层。宿主机之间二层不连通的情况比如宿主机分布在了不同的子网(VLAN)里。但是,在一个 Kubernetes 集群里,宿主机之间必须可以通过 IP 地址进行通信,也就是说至少三层可达
三层网络 OSI网络模型中的网络层,主要关注在二层网络主机之间路由的数据包,ipv4\ipv6\ICMP是第三层网络协议的示例
隧道技术

网络基础设置在网络之间传递数据的方式,使用隧道技术传递可以是不同协议的数据包,隧道协议将这些其他协议的数据包重新封装在新的包头中发送。被封装的数据包在隧道的两个端点之间通过网络进行路由,被封装数据包在网络上传递时所经历的逻辑路径称为隧道

IP隧道是指一种可在两网络间进行通信的通道。在该通道里,会先封装其他网络协议的数据包,之后再传输信息

IPIP

普通的IPIP隧道,就是在报文的基础上再封装成一个IPv4报文

VXLAN 用于将二层以太网帧封装在UDP数据包中帮助云部署扩展,VXLAN虚拟化类似于VLAN,但比VLAN提供了更强大灵活性和功能
网桥 它是一个工作在数据链路层的设备,主要功能是根据 MAC 地址学习来将数据包转发到网桥的不同端口(Port)上
NAT Network Address Translation,网络地址转换 是将IP 数据包头中的IP 地址转换为另一个IP 地址的过程。在实际应用中,NAT 主要用于实现私有网络访问公共网络的功能
SNAT

Source Network Address Translation,源地址转换 是Linux防火墙的一种地址转换操作,也是iptables命令中的一种数据包控制类型,其作用是根据特定的条件修改数据包的源IP地址

比如:内部地址要访问公网上的服务时(如web访问),内部地址会主动发起连接,由路由器或者防火墙上的网关对内部地址做个地址转换,将内部地址的私有IP转换为公网的公有IP,网关的这个地址转换称为SNAT,主要用于内部共享IP访问外部

DNAT

Destination Network Address Translation,目的网络地址转换在Internet中发布位于局域网内的服务器,修改数据包的目的地址

比如:当内部需要提供对外服务时(如对外发布web网站),外部地址发起主动连接,由路由器或者防火墙上的网关接收这个连接,然后将连接转换到内部,此过程是由带有公网IP的网关替代内部服务来接收外部的连接,然后在内部做地址转换,此转换称为DNAT,主要用于内部服务对外发布

Underlay Network 底层设施,硬件通讯基础; 在 kubernetes 中,underlay network 中比较典型的例子是通过将宿主机作为路由器设备,Pod 的网络则通过学习路由条目从而实现跨节点通讯
Overlay 是现有网络上构建的虚拟逻辑网络,通常用于提供现有网络的抽象,能够分离和保护不同逻辑网络
BGP 管理数据包在边缘路由器之间的路由方式,通过考虑可用路径、路由规则和特定网络策略,帮助确定如何将数据包从一个网络发到另一个网络域。它跟普通路由器的不同之处在于,它的路由表里拥有其他自治系统里的主机路由信息,在使用了 BGP 之后,在每个边界网关上都会运行着一个小程序,将各自的路由表信息,通过 TCP 传输给其他的边界网关。而其他边界网关上的这个小程序,则会对收到的这些数据进行分析,然后将需要的信息添加到自己的路由表里
IPTables Linux内核功能,将灵活的规则序列附加到内核的数据包处理管道中的各种钩子上 iptables
IPVS IP Virtual Server是在 Netfilter 上层构建的,并作为 Linux 内核的一部分,实现传输层负载均衡。IPVS 集成在 LVS(Linux Virtual Server,Linux 虚拟服务器)中,它在主机上运行,并在物理服务器集群前作为负载均衡器。IPVS 可以将基于 TCP 和 UDP 服务的请求定向到真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。ipvs
CIDR

表示一段灵活的IP地址范围,ip/n,n标识网络位,前n不变,比如下面/8,就是二进制前8位不动

比如 10.0.0.0/8->00001010.00000000.00000000.00000000~00001010.11111111.11111111.11111111→子网掩码为255.0.0.0,对应网段为10.0.0.0~10.255.255.255

posted on 2023-01-06 17:38  it_worker365  阅读(104)  评论(0编辑  收藏  举报