前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8s网络模型

K8s网络模型

作者头像
冬夜先生
修改2021-09-02 18:16:40
1.7K0
修改2021-09-02 18:16:40
举报
文章被收录于专栏:csicocsico

Docker网络模型

容器

容器不是模拟一个完整的操作系统,而是对进程进行隔离,对容器里的进程来说它接触到的各种资源都是独享的,比虚拟机启动快、占用资源少。

Docke

Docker是对Linux底层容器技术的封装,提供容器使用接口,docker将应用程序和该程序的依赖打包在同一个文件,即Docker image,运行Docker image就会生成一个Docker容器,程序在容器里运行就像在物理机或者虚拟机一样。

容器与虚拟机对比

虚拟机要模拟整台机器的操作系统,包括硬件资源;容器和主机共享操作系统,容器之间共享内核。

从架构上看容器比虚拟机少了Hypervisor层和Guest OS层,使用Docker Engine进行资源分配调度,使用Linux namespace隔离,所有应用共享操作系统,因此在体量上docker比虚拟机轻量,性能上优于虚拟化

Docker四大网络模式

我们使用docker run创建docker容器时,可以使用–network指定容器的网络模式

bridge模式:–network=bridge

host模式:–network=host

container模式:–network=container:NAME_or_ID

none模式:–network=none

docker安装完毕后,docker daemon会在宿主机上自动创建三个网络,分别是bridge网络、host网络、none网络。

bridge模式

docker在安装时会创建一个名为docker0的Linux网桥,不指定–network的情况下就是bridge模式,docker为每一个容器分配network namespace设置IP并连接到docker0网桥,docker0是普通的Linux网桥,而非ovs网桥

此时没有创建容器,interface项是空的,执行命令创建容器

docker run -d nginx

1

创建容器后可以看到docker0上挂了一个网卡,网卡的另一端就是主机network namespace veth pair的另一端,使主机的namespace可以和docker容器通信,默认情况下docker0的IP地址为172.17.0.1,连接到docker0上的docker容器的IP均在172.17.0.0/24网段。

host模式

host模式下容器不会获得独立的network namespace,而是和宿主机公用一个network namespace,容器不会虚拟出自己的网卡和IP,而是使用宿主机的IP和端口,而且容器直接端口不可重复,容易发生资源争抢。

container模式

在创建容器的时候容器和已经存在容器共享一个network namespace,但不和宿主机network namespace共享,也不会创建自己的网卡和IP而是共享容器的IP,两个容器可以通过loop0口通信。

none模式

容器拥有独立的network namespace但是不配置IP,无法进行网络通信

端口映射

docker run -p hostport:containerport nginx

容器的dns

容器的dns在默认与主机的一致都在/etc/resolv.conf里,可以手动修改,但是容器重启后又恢复原值,若想永久的修改可通过/etc/docker/daemon.conf里制定dns,/etc/hosts记录容器的ip,/etc/hostname记录容器的名称

Calico网络模型

Calico是一个纯三层网络方案,不同主机的每个容器内部都配一个路由指向容器的IP,可以通过网卡直接到达目标容器,在每一个计算节点,利用Linux Kernal实现数据转发,每个vRouter把自己节点上的路由发给整个Calico网络,使所有容器之间的数据流量都是通过路由互联。

K8s网络模型

K8s术语

K8S 是一个用于容器集群的分布式系统架构。首先,它是基于容器技术,容器是和虚拟机并列的一种虚拟化技术,相比虚拟机来说,容器更加轻量,资源利用率更高,更适合于云原生应用。

Maste

每个K8s集群都需要一个master负责整个集群的管理和控制,我们所有的控制命令都发给它,通常占据独立的服务器,master上运行的进程:

1、kube-apiserver:对外提供http接口,实现对集群内资源的增删改查

2、kube-controller-manager:集群内资源的控制中心

3、kube-scheduler:集群内资源调度

Node

K8s集群中其他机器,可以是一台物理机,也可以是虚拟机,受master管控,当node宕机,他上面的工作负载会被master转移到其他node,node上运行的进程:

1、kubelet:负责pod对应容器的创建、启动、停止,默认会向master注册自己,定时向master汇报自己的操作系统、docker版本、cpu、内存

2、kube-proxy:负责与K8s service通信

3、docker:负责docker的创建、启动、停止

Pod

K8s通过将容器分类组成pod,pod是K8s中特有的概念,它是容器分组的抽象,也是K8s最小的部署单元。

Pod是由一个或多个容器构成的集合,作为一个整体部署到一个节点上,同一个Pod中的容器共享协议栈、主机名、存储等资源,K8s的Pod使得用户能够更方便的对一组功能相似的容器进行管理、迁移,一个节点上可运行0个或多个Pod,每个pod上有一个特殊的pause容器,pod容器之间是可以互通的,当pod内容器停止时,K8s会检测到并重启整个pod,pod内的多个容器共享volume。

Namespace

资源隔离,默认在K8s启动时创建名为default的namespace,后续如果不特别指定,所有资源都放在这个namespace下

kubectl get namespaces // 查看namespace

kubectl get pods // 仅能看到default namespace下的pod

kubectl get pods --namespace=xxx // 指定namespace

1

2

3

从基础设施的角度看,K8s提供了更佳的控制方式,无需用户对每个容器单独处理,而是集中在K8s主节点的指派。

其中,docker在K8s中扮演的角色就是执行其原本的任务,即管理容器和镜像,当K8s把Pod调度到节点上,节点上的Kubelet会指示docker启动特定的容器,Kubelet会通过cgroup收集容器的信息然后提交给K8s管理层面。

K8s网络

K8s网络包括CNI、Service、Ingress、DNS

在K8s网络模型中,每个节点上的容器都有自己独立的IP段,节点之间的IP段不能重复,而节点也需要具备路由能力,使从本节点Pod里出来的流量可以根据目的IP转发到对应的节点。总结来说,K8s的容器网络重点关注两方面,IP地址分配和路由。

1、IP地址分配

系统会从集群的VPC网络为为每个节点分配一个IP地址,用于提供从Kubelet到K8s master的连接

系统为每个Pod分配一个IP网段内的IP,Pod内的容器共享同一个network namespace和IP,Pod内的容器之间可以直接通信,也可以在创建集群时通过–pod-cidr制定网段范围

2、出站流量

1、Pod到Pod

K8s集群中,每个Pod都有自己的IP地址,Pod内的应用程序都可以使用标准端口号无需映射,所有Pod都可保持3层网络联通,比如互相ping、发送TCP/UDP数据包,CNI就是用来实现这些网络功能的接口。

2、Pod到Service

Pod的生命周期很短,而为了维持可靠的服务,K8s引入Service就是Pod前面的4层负载均衡,Service有4种类型最常用的就是clusterID,会自动分配一个集群内部都可以访问的虚拟IP,Pod和Service之间的流量主要是过滤和NAT

3、Pod到集群外

Pod内部到集群外的流量K8s会通过SNAT来处理,将Pod内部的IP和Port换成宿主机的IP和Port,当数据包返回时再将宿主机的IP和Port换成Pod内部的IP和Port,这个过程Pod是不感知的。

K8s创建Pod

当用户在K8s的master里创建一个Pod时,Kubelet观察到新Pod的创建,调用CRI创建pod内的若干个容器,第一个创建的容器pause容器是K8s自带的,一启动就会阻塞,它的作用是占用一个network namespace,用户创建的容器与其共享namespace和IP,创建pod内的容器是调用同一个命令:docker run --net=none,而pause的eth0和IP都是通过CNI分配的,pod内所有容器共享这一个IP。

K8s主机内网络模型

K8s采用的是veth pair+bridge的模式,veth pair将容器与主机的网络协议栈连接起来,可以使pod之间通信。

Node1上Pod10.1.1.1想要访问Node2上Pod10.1.2.1,根据Node1上的路由转发到宿主机的接口eth0,通过物理网络到达Node2的eth0口后查看路由转发到cni网桥,到网桥后广播发给网桥上的Pod,回程同理。

bridge模式的跨主机通信本身不解决跨主机通信问题,需要显示书写路由,集群中若有N个主机就需要N-1条路由。

overlay模式

overlay模式与bridge模式的区别就是路由转发给tun口,tun口是overlay隧道的入口,所有机器只需要一条路由表,而在两个主机的tun口之间以flannel为例,会借助分布式数据库记录容器IP与宿主机IP映射,而每个节点上会运行一个agent,监听tun口的封包和拆包,比如Node1的容器发给Node2的容器,当数据包到达Node1的tun口之后,flannel会查询Node2容器的宿主机IP,在tun处将192.168.1.101:8472封装在原始数据包之外(并将包的校验和为0),然后借着eth0物理网络到达Node2的eth0口,Node2的flannel监听到校验和为0的包知道这是一个overlay包将其拆包,看到内层IP根据路由发给cni在广播到容器。

K8s微服务service

出现背景:若客户端想访问容器,最简单的方式是直接访问容器的ip+port,但当有多个后端实例时如何做到负载均衡?容器迁移IP会发生什么变化?如何通过域名访问?健康检查如何做?

K8s的解决方案是在客户端和Pod之间引入service,K8s使用标签label将多个Pod组合成一个逻辑单元即Service,Service有稳定的IP和端口,并在Pod之间提供负载均衡,匹配的条件是Service的selector和Pod的label相匹配。

K8s从可用IP池中为服务分配一个稳定的IP,称为cluster IP,K8s还会通过DNS为cluster IP分配主机名,cluster IP和主机名在集群中都是独一无二的,在整个生命周期都不会更改,直到服务从集群删除才会释放cluster IP和主机名,用户可通过访问cluster IP和主机名访问到Pod。也不必担心单点故障,service会负载均衡将流量打到Pod上,同时若干个pod失效也不影响整体服务。

clusterIP是一个虚拟IP,只有和port一起使用才有作用,单独ping clusterIP或者访问它的其他接口都没有意。

K8s使用Kube-proxy组件管理service与后端Pod的连接,该组件部署在每个节点,Kube-proxy是一个负载均衡控制器,监控service并将cluster IP映射到运行良好的pod上,落实到主机上就是iptables路由规则。

当service的后端Pod准备就绪后,K8s会生成新的Endpoint对象,这个Endpoint与service同名。

kubectl get endpoints // 获取endpoints列表

1

7层负载均衡K8s Ingress

四层负载均衡主要是通过修改目的地址,在根据负载均衡设备选择后端服务器的规则之间与该服务器建立TCP连接并发送数据。

七层负载均衡器主要起了一个代理服务器的作用,client与七层负载均衡器建立三次握手,七层负载均衡器选择后端服务器后再次建立三次握手。

K8s Ingress是指授权入站连接到集群内服务的规则集合,Ingress的作用是在边界路由处开个口子,是建立在service之上的7层访问入口,它支持通过URL的方式将service暴露到K8s集群外,支持自定义service访问策略,提供按域名访问service功能。

MacVlan

MacVlan的原理是在物理网卡(父设备)上虚拟出多块虚拟网卡(子设备),并允许用户针对每个子设备单独设置MAC地址与IP地址。当父设备接收网络报文时,首先判断目标MAC地址是否与子设备匹配,若匹配,则将报文发送至子设备。父设备与子设备共享一个广播域。

Bridge:属于同一个parent接口的macvlan接口之间挂到同一个bridge上,可以二层互通,macvlan接口都无法与parent 接口互通。

VPEA(Virtual Ethernet Port Aggregator):所有接口的流量都需要到外部switch才能够到达其他接口。

Private:接口只接受发送给自己MAC地址的报文。

1、分别在2个主机上基于macvlan创建虚拟网卡

ip link add link eth0 dev eth0.03 type macvlan

ip link add link eth0 dev eth0.04 type macvlan

2、创建后的虚拟网卡并没有被激活,需要手动激活

ip link set eth0.03 up

ip link set eth0.04 up

3、激活后的虚拟网卡被分配了mac,但是没有ip

4、k8s在主机上创建pod,调用cni分配ip并与pod绑定

同主机同vlan下pod之间通信:

1、主机上的172.16.0.2想访问172.16.0.3,封包时不知道其mac地址要先发arp广播,arp包到交换机时,交换机记录下172.16.0.2的ip、mac到arp表,同时将172.16.0.2的mac和对应的交换机端口记录到cam表,然后广播给交换机的所有接口,只有172.16.0.3的pod会单播回复,交换机同理记下172.16.0.3的mac和ip到arp表,同时将172.16.0.3的mac和对应的交换机端口记录到cam表

2、主机的pod172.16.0.2拿到172.16.0.3的mac地址封包后到交换机,查看cam表发现172.16.0.3的mac和转发端口,直接送回原主机,macvlan 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡,虚拟网卡再把包交给上层的协议栈处理。

跨主机同vlan下pod之间通信:

1、主机1上的172.16.0.1想访问172.16.0.2,封包时不知道其mac地址要先发arp广播,arp包到交换机时,交换机记录下172.16.0.1的ip、mac到arp表,同时将172.16.0.1的mac和对应的交换机端口记录到cam表,然后广播给交换机的所有接口,只有172.16.0.2的pod会单播回复(这里解释一下,arp广播包到达主机2时因为开启了macvlan,arp包会继续上送到pod里然后回复),交换机同理记下172.16.0.2的mac和ip到arp表,同时将172.16.0.2的mac和对应的交换机端口记录到cam表

2、主机1的pod172.16.0.1拿到172.16.0.2的mac地址封包后到交换机,查看cam表发现172.16.0.2的mac和转发端口,直接转发到对应主机,macvlan 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡,虚拟网卡再把包交给上层的协议栈处理。

跨主机跨vlan下pod之间通信:

1、主机1上的172.16.0.1想访问192.168.0.2,主机1判断是跨网段的访问,则需要经过网关,发送的arp请求的是网关的mac,交换机上送到网关,得到回复后返回给主机1

2、主机1拿到网关的mac后封包(注意这里目的ip是192.168.0.2,目的mac是网关的mac),交换机收到包后发现目的mac是网关直接送到网关,网关根据路由条目将数据包转发到192.168.0.2的网关

3、192.168.0.2的网关收到包后拆包,发现目的mac是自己,目的ip不是自己,先查看arp表,查到直接转发,查不到则发arp请求192.168.0.2的mac,收到回复后转发

注意点总结:

1、交换机的口必须是trunk才可接受macvlan给pod划分的vlan

2、vlan标签是在出主机时就已封装

3、arp广播时发给交换机下所有主机

基于macvlan的evpn方案

macvlan的局限性:

1、网段与交换机绑定,在pod漂移时必须更换ip

2、漂移意味着申请更高的内存及CPU资源,在同一交换机下漂移很有可能出现资源耗尽的情况

1、这种互联模式让2个网段分别连接不同交换机(前提是交换机配置evpn),可以实现pod跨交换机的漂移

2、开启了evpn的交换机,对于物理网段10.255.86.0/24要手动network通告bgp,对于容器网段172.16.0.0/24是交换机自动学习(免费arp)对外通告自动学习的bgp明细路由

3、一个evpn集群内部的evpn交换机之间是通过隧道互联

同vlan下pod之间通信:

1、主机1上的172.16.0.1想访问172.16.0.2,封包时不知道其mac地址要先发arp广播,arp包到交换机时,交换机1记录下172.16.0.1的ip、mac到arp表,同时将172.16.0.1的mac和对应的交换机端口记录到cam表,然后广播给evpn集群内所有交换机的所有接口,只有172.16.0.2的pod会单播回复(这里解释一下,arp广播包到达主机2时因为开启了macvlan,arp包会继续上送到pod里然后回复),交换机2同理记下172.16.0.2的mac和ip到arp表,同时将172.16.0.2的mac和对应的交换机端口记录到cam表

2、主机1的pod172.16.0.1拿到172.16.0.2的mac地址封包后到交换机,查看bgp表发现172.16.0.2的明细路由是由交换机2通告的,直接封装vxlan后转发到交换机2,交换机2查看cam表转发到对应接口,主机收到后macvlan 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡,虚拟网卡再把包交给上层的协议栈处理。

跨vlan下pod之间通信:

1、主机1上的172.16.0.1想访问192.168.0.2,主机1判断是跨网段的访问,则需要经过网关,发送的arp请求的是网关的mac,交换机上送到网关(分布式网关,在交换机1上),得到回复后返回给主机1

2、主机1拿到网关的mac后封包(注意这里目的ip是192.168.0.2,目的mac是网关的mac),交换机收到包后发现目的mac是网关直接送到网关,网关根据bgp路由条目封装vxlan后将数据包转发到192.168.0.2的网关

3、192.168.0.2的网关收到包后拆包,发现目的mac是自己,目的ip不是自己,先查看arp表,查到直接转发,查不到则发arp请求192.168.0.2的mac,收到回复后转发

IPVlan

IPVlan 和 macvlan 类似,都是从一个主机接口虚拟出多个虚拟网络接口。一个重要的区别就是所有的虚拟接口都有相同的 macv 地址,而拥有不同的 ip 地址。因为所有的虚拟接口要共享 mac 地址,这种场景多用于在云厂商的虚拟机内部创建容器,因为云厂商默认不识别macvlan的mac地址。

L2模式: 同网段之间可通过父接口通信

ipvlan L2 模式和 macvlan bridge 模式工作原理很相似,父接口作为交换机来转发子接口的数据。同一个网络的子接口可以通过父接口来转发数据,而如果想发送到其他网络,报文则会通过父接口的路由转发出去。

L3模式: 同父接口内所有网段可以通信

ipvlan 有点像路由器的功能,它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相 ping 通对方,因为 ipvlan 会在中间做报文的转发工作。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档