Kubernetes-网络通信的部署
Kubernetes-网络通信的部署一.k8s网络通信二. Flannel1. 了解flannel2. 部署fannel组件1> Vxlan模式2>host-gw模式三. calico网络插件1. 了解calico2. 部署calico组件3. calico网络策略1>限制访问指定服务2> 允许指定pod访问服务3> 禁止 namespace 中所有 Pod 之间的相
Kubernetes-网络通信的部署
Kubernetes的网络通信方式是整个K8s的重点,所以更好的理解它的网络通信方式有助于我们更好的掌握Kubernetes。
一.k8s网络通信
Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中,这在GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes假定这个网络已经存在。而在私有云里搭建Kubernetes集群,就不能假定这个网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的Docker容器之间的互相访问先打通,然后运行Kubernetes。
同一个Pod内的多个容器之间网络互访:基于Pause容器的网络栈Lo(共享网卡)
各个Pod之间的网络通信:Overlay Network
Pod与Service之间的通讯:各节点的IpTables规则(新版本中已经加入了LVS机制,转发效率将会更高,上限也更高)
k8s通过CNI接口接入其他插件来实现网络通讯。目前比较流行的插件有flannel,calico等。
插件使用的解决方案如下:
a. 虚拟网桥,虚拟网卡,多个容器共用一个虚拟网卡进行通信。
b. 多路复用:MacVLAN,多个容器共用一个物理网卡进行通信。
c. 硬件交换:SR-LOV,一个物理网卡可以虚拟出多个接口,这个性能最好。
Kubernetes网络设计模型:
基本原则:
每个Pod都有一个独立的IP地址,而且假定所有的Pod都在一个可以直接联通、扁平的网络空间中;
设计原因:
用户不需要额外考虑如何建立Pod之间的连接,也不需要将容器端口映射到主机端口的问题;
网络要求:
所有的容器都可以在不用NAT的情况下于其他容器进行通信;所有Node都可以在不用NAT的情况下于其他容器进行通信;容器的地址和别人看到的地址是同一个;
主要包含四大类通信问题:
同一个Pod中容器间的通信:
同一个Pod共享同一个网络命名空间,共享同一个Linux协议栈
同一Node不同Pod间的通信:
Pod1与Pod2在同一台机器,由docker0网桥直接转发请求至Pod2,不需要经过Flannel
不同Node间的Pod通信:
Pod1与Pod2不在同一台主机,Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。
Pod与service之间的通信:
目前基于性能考虑,全部为iptables维护和转发。最新版已经完全可以由LVS进行转发和维护。
补充:
Pod到外网:
Pod向外网发送请求,查找路由表,转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables执行Masquerade,把源IP更改为宿主网卡的IP,然后向外网服务器发送请求。
外网访问Pod:
Service
在Kuberbetes中,只有Node网络是真实存在的,Pod以及Service网络都是虚拟网络
二. Flannel
1. 了解flannel
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,他的作用就是实现Pod资源跨主机进行网络通信。即(不同Node间的Pod通信;)
原理:
flannel可以让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址,使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
flannel的作用:
1.使集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
2.建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。
3.创建一个新的虚拟网卡flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。
4.etcd保证了所有node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化。
flannel支持多种后端:
- Vxlan
- vxlan //报文封装,默认
- Directrouting //直接路由,跨网段使用vxlan,同网段使用host-gw模式。
- host-gw: //主机网关,性能好,但只能在二层网络中,不支持跨网络。如果有成千上万的Pod,容易产生广播风暴,不推荐
- UDP: //性能差,不推荐
2. 部署fannel组件
1> Vxlan模式
2> host-gw模式
开始之前现在server3查看以下ip类型:
是falnnel.1并且网关并不是虚拟机ip
修改kube-flannel配置文件,将type改为直连模式
我们查看pod信息的时候,flannel模式还在
是因为没有更新pod节点
更新它!并查看pod节点信息:
在server3查看进程flannel插件
并查看
ip的类型变为了eth0,网关变为了虚拟机ip:
在server4上查看也是一样发变为了eth0
三. calico网络插件
1. 了解calico
Calico是一个纯三层的协议,为OpenStack虚机和Docker容器提供多主机间通信。Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。
Calico结构组成
Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心;Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。
Calico 的核心组件:
Felix: Calico agent,跑在每台需要运行 workload 的节点上,主要负责配置路由及 ACLs 等信息来确保 endpoint 的连通状态;
etcd: 分布式键值存储,主要负责网络元数据一致性,确保 Calico 网络状态的准确性;
BGPClient(BIRD): 主要负责把 Felix 写入 kernel 的路由信息分发到当前 Calico 网络,确保 workload 间的通信的有效性;
BGP Route Reflector(BIRD): 大规模部署时使用,摒弃所有节点互联的 mesh 模式,通过一个或者多个BGP Route Reflector来完成集中式的路由分发;
Calico 工作原理
Calico把每个操作系统的协议栈认为是一个路由器,然后把所有的容器认为是连在这个路由器上的网络终端,在路由器之间跑标准的路由协议——BGP的协议,然后让它们自己去学习这个网络拓扑该如何转发。所以Calico方案其实是一个纯三层的方案,也就是说让每台机器的协议栈的三层去确保两个容器,跨主机容器之间的三层连通性。
由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有方案中最高的。
Calico网络方式
IPIP
从字面来理解,就是把一个IP数据包又套在一个IP包里,即把 IP 层封装到 IP 层的一个 tunnel。它的作用其实基本上就相当于一个基于IP层的网桥!一般来说,普通的网桥是基于mac层的,根本不需 IP,而这个 ipip 则是通过两端的路由做一个 tunnel,把两个本来不通的网络通过点对点连接起来。ipip 的源代码在内核 net/ipv4/ipip.c 中可以找到。
BGP
边界网关协议(Border Gateway Protocol, BGP)是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。
推荐一篇讲的非常详细的文章:
https://www.cnblogs.com/jokerjason/p/13206594.html
2. 部署calico组件
在server1上传镜像:
在server2上新建目录用来存储文件:
更改calico.yaml资源清单的镜像:
将隧道模式关闭
删除之前的网络插件flannel
kubectl delete -f kube-flannel.yml
将所有k8s节点的网络插件配置缓存文件移走
server2.3.4操作相同:
执行calico.yaml清单,完成初始化:
从上图可以看到是初始化正在进行,稍等一下:
全部为running即可:
查看网关,和svc信息
将之前实验的svc删除
重新运行一个svc,并访问IP!!
curl 10.111.239.230
3. calico网络策略
1> 限制访问指定服务
在server4添加ip:
与ext文件保持一致
2> 允许指定pod访问服务
deny-nginx.yaml文件下面添加如下内容:
执行清单,查看信息,发现多了一条允许的策略
注意标签:
不对的话用这个更改:
3> 禁止 namespace 中所有 Pod 之间的相互访问
执行ns.yaml清单并查看状态:
查看详细信息:
查看节点ip:
测试:发现pod内外均无法访问:
更多推荐
所有评论(0)