本文参考戳该链接可以看原文,原文作者整理非常好

一、网络前提条件-网络模型

  • k8s组网要求

    • 所有的Pods之间可以在不使用NAT网络地址转换的情况下相互通信
    • 所有的Nodes之间可以在不使用NAT网络地址转换的情况下相互通信
    • 每个Pod自己看到的自己的ip和其他Pod看到的一致
  • k8s网络模型设计原则
    • 每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中 。
    • 不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问。
    • 设计这个原则的原因 是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题。

由于 Kubemetes 的网络模型假设 Pod 之间访问时使用的是对方 Pod 的实际地址,所以一个Pod 内部的应用程序看到的自己的 IP 地址和端口与集群内其他 Pod 看到的一样。它们都是 Pod 实际分配的IP地址 (从dockerO上分配的)。将IP地址和端口在Pod内部和外部都保持一致, 我们可以不使用 NAT 来进行转换,地址空间也自然是平的。

二、需要解决的网络问题

根据以上的一些要求,需要解决的问题

  • Docker容器和Docker容器之间的网络
  • Pod与Pod之间的网络
  • Pod与Service之间的网络
  • Internet与Service之间的网络

1.容器和容器之间的网络

pod有多个容器,它们之间怎么通信?

pod中每个docker容器和pod在一个网络命名空间内,所以ip和端口等等网络配置,都和pod一样,主要通过一种机制就是,docker的一种网络模式,container,新创建的Docker容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等

2.pod与pod之间的网络

pod与pod之间的网络:首先pod自身拥有一个IP地址,不同pod之间直接使用IP地址进行通信即可

同一台node节点上pod和pod通信

疑问:那么不同pod之间,也就是不同网络命名空间之间如何进行通信(现在还是,同一台node节点上)

解决

简单说veth对就是一个成对的端口,所有从这对端口一端进入的数据包,都将从另一端出来。

为了让多个Pod的网络命名空间链接起来,我们可以让veth对的一端链接到root网络命名空间(宿主机的),另一端链接到Pod的网络命名空间。

嗯,那么继续。

还需要用到一个Linux以太网桥,它是一个虚拟的二层网络设备,目的就是把多个以太网段连接起来,它维护一个转发表,通过查看每个设备mac地址决定转发,还是丢弃数据

  • pod1-->pod2(同一台node上),pod1通过自身eth0网卡发送数据,eth0连接着veth0,网桥把veth0和veth1组成了一个以太网,然后数据到达veth0之后,网桥通过转发表,发送给veth1,veth1直接把数据传给pod2的eth0。

不同node节点上pod和pod通信

CIDR的介绍:

CIDR(Classless Inter-Domain Routing,无类域间路由选择)它消除了传统的A类、B类和C类地址以及划分子网的概念,因而可以更加有效地分配IPv4的地址空间。它可以将好几个IP网络结合在一起,使用一种无类别的域际路由选择算法,使它们合并成一条路由从而较少路由表中的路由条目减轻Internet路由器的负担。

看图,接着往下捋。

k8s集群中,每个node节点都会被分配一个CIDR块,(把网络前缀都相同的连续地址组成的地址组称为CIDR地址块)用来给node上的pod分配IP地址,另外还需要把pod的ip和所在nodeip进行关联

  • 比如node1上pod1和node2上的pod4进行通信

    1. 首先pod1上网卡eth0将数据发送给已经管理到root命名空间的veth0上,被虚拟网桥收到,查看自己转发表之后,并没有pod4的mac地址。
    2. 就会把包转发到默认路由,(root命名空间的eth0上,也就是已经到了node节点的往卡上)通过eth0,发送到网络中。
    3. 寻址转发后包来到了node2,首先被root命名空间的eth0设备接受,查看目标地址是发往pod4的,交给虚拟网桥路由到veth1,最终传给pod4的eth0上。

3.pod与service之间的网络

pod的ip地址是不持久的,当集群中pod的规模缩减或者pod故障或者node故障重启后,新的pod的ip就可能与之前的不一样的。所以k8s中衍生出来Service来解决这个问题。

Service管理了多个Pods,每个Service有一个虚拟的ip,要访问service管理的Pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。

当数据包到达Service虚拟ip后,数据包会被通过k8s给该servcie自动创建的负载均衡器路由到背后的pod容器。

  • 在k8s里,iptables规则是由kube-proxy配置,kube-proxy监视APIserver的更改,因为集群中所有service(iptables)更改都会发送到APIserver上,所以每台kubelet-proxy监视APIserver,当对service或pod虚拟IP进行修改时,kube-proxy就会在本地更新,以便正确发送给后端pod
  • pod到service包的流转:

  1. 数据包从pod1所在eth0离开,通过veth对的另一端veth0传给网桥cbr0,网桥找不到service的ip对应的mac,交给了默认路由,到达了root命名空间的eth0
  2. root命名空间的eth0接受数据包之前会经过iptables进行过滤,iptables接受数据包后使用kube-proxy在node上配置的规则响应service,然后数据包的目的ip重写为service后端指定的pod的ip了
  • service到pod包的流转
  1. 收到包的pod会回应数据包到源pod,源ip是发送方ip,目标IP是接收方,数据包进行回复时经过iptables,iptables使用内核机制conntrack记住它之前做的选择,又将数据包源ip重新为service的ip,目标ip不变,然后原路返回至pod1的eth0

4.Internet与service之间的网络

将k8s集群服务暴露给互联网上用户使用,有两个问题;(1)从k8s的service访问Internet,以及(2)从Internet访问k8s的service.

根据参考文章,通过Internet网关,node可以将流量路由到Internet,但是pod具有自己的IP地址,Internet王冠上的NAT转换并不适用。参考方案:就是node主机通过iptables的nat来解决

  • node到internet包的流转

  1. 数据包源自pod1网络命名空间,通过veth对连接到root网络命名空间,紧接着,转发表里没有IP对应的mac,会发送到默认路由,到达root网络命名空间的eth0
  2. 那么在到达root网络明明空间之前,iptables会修改数据包,现在数据包源ip是pod1的,继续传输会被Internet网关拒绝掉,因为网关NAT仅转发node的ip,解决方案:使iptables执行源NAT更改数据包源ip,让数据包看起来是来自于node而不是pod
  3. iptables修改完源ip之后,数据包离开node,根据转发规则发给Internet网关,Internet网关执行另一个NAT,内网ip转为公网ip,在Internet上传输。
  4. 数据包回应时,也是按照:Internet网关需要将公网IP转换为私有ip,到达目标node节点,再通过iptables修改目标ip并且最终传送到pod的eth0虚拟网桥。

Internet到k8s的流量

让Internet流量进入k8s集群,这特定于配置的网络,可以在网络堆栈的不同层来实现:

(1) NodePort

(2)Service LoadBalancer

(3)Ingress控制器。

这里只介绍第三种,如果想看详细的,文章开始有一个链接

  • 第七层流量入口:Ingress Controller

通过一个公开的ip地址来公开多个服务,第7层网络流量入口是在网络堆栈的HTTP / HTTPS协议范围内运行,并建立在service之上。

工作:客户端现针对www.1234.com执行dns解析,DNS服务器返回ingress控制器的ip,客户端拿到ip后,向ingress控制器发送http的get请求,将域名加在host头部发送。控制器接收到请求后,从host头部就知道了该访问哪一个服务,通过与该service关联的endpoint对象查询podIP地址,将请求进行转发

第7层负载均衡器的一个好处是它们具有HTTP感知能力,因此它们了解URL和路径。 这允许您按URL路径细分服务流量。 它们通常还在HTTP请求的X-Forwarded-For标头中提供原始客户端的IP地址。

参考

https://www.jianshu.com/p/3f2401d14c78

k8s中的网络(较详细汇总)的更多相关文章

  1. K8s中的网络

    Kubernetes的网络通信问题: 1. 容器间通信: 即同一个Pod内多个容器间通信,通常使用loopback来实现. 2. Pod间通信: K8s要求,Pod和Pod之间通信必须使用Pod-IP ...

  2. 3G 4G 5G中的网络安全问题——文献汇总

    Modeling and Analysis of RRC-Based Signalling Storms in 3G Networks 还是使用状态机模型来做恶意UE识别 https://san.ee ...

  3. 新版的K8S中的flannel.yaml文件中要注意的细节

    部署flannel作为k8s中的网络插件,yaml文件都大小同异. 但在要注意以下细节. 以前,只需要前面master判断. 现在也需要有not-ready状态了. tolerations: - ke ...

  4. (原)torch中显示nn.Sequential()网络的详细情况

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6065526.html 本部分多试几次就可以弄得清每一层具体怎么访问了. step1. 网络定义如下: ...

  5. SQL语句详细汇总

    SQL语句详细汇总 | 浏览:3061 | 更新:2013-06-10 19:50 一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 d ...

  6. 在k8s中的基本概念

    在k8s中的基本概念 一.Pod1. podk8s下最重要也最基本的概念,由一个根容器Pause和许多用户业务容器组成,是容器的载体. 2. pod的yaml定义格式及字段 apiVersion: v ...

  7. k8s 中 Pod 的控制器

    k8s 中 Pod 的控制器 前言 Replication Controller ReplicaSet Deployment 更新 Deployment 回滚 deployment StatefulS ...

  8. PHP网络操作函数汇总

    PHP网络操作函数汇总 投稿:junjie 字体:[增加 减小] 类型:转载   这篇文章主要介绍了PHP网络操作函数汇总,本文列举了如gethostbyaddr.gethostbyname.head ...

  9. 已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。

    今天写ASP.NET程序,在网页后台的c#代码里写了个事务,事务内部对一张表进行批量插入,对另外一张表进行查询与批量插入. 结果第二张表查询后foreach迭代操作时报错:已禁用对分布式事务管理器(M ...

随机推荐

  1. Qt bug

    1.Qt5.2.1不支持QQuickwidget来承载qml 2.Qt5.12以及以上,不支持跨线程调用数据库连接 3.线程A不断产生sql语句,需要让两个数据库分别执行这个sql语句.所以在线程A中 ...

  2. Python json序列化时default/object_hook指定函数处理

    在Python中,json.dumps函数接受参数default用于指定一个函数,该函数能够把自定义类型的对象转换成可序列化的基本类型.json.loads函数接受参数objec_thook用于指定函 ...

  3. 【计算机视觉】OpenCV篇(5) - 仿射变换与透视变换

    参考: 图像处理的仿射变换与透视变换(https://www.imooc.com/article/27535) http://ex2tron.wang/opencv-python-extra-warp ...

  4. 【JQuery插件】扑克正反面翻牌效果

    里面有两个demo,支持X横向和Y纵向翻转两个效果. 对元素的布局有一定的讲究,需要分析一下demo的css. 默认翻转速度为80,不要大于100ms. <!DOCTYPE> <ht ...

  5. beyond Compare 30天过期后的处理办法

    打开Beyond Compare 4,提示已经超出30天试用期限制,解决方法: 修改C:\Program Files\Beyond Compare 4\BCUnrar.dll,这个文件重命名或者直接删 ...

  6. [Xamarin] - Xamarin.Forms Project with .Net Standard 2.0

    1. Install .NET Core 2.0 SDK .https://www.microsoft.com/net/download/core 2. Install Android 7.1 (AP ...

  7. Python爬虫刷回复

    最近闲的无聊,就想着去看看爬虫,顺着爬虫顺利的做到了模拟登录.刷帖子等等,这里简要说一下. 使用Python2.7写的爬虫,对某论坛做模拟登陆和刷帖子.回复等等,由于之前是没有接触过爬虫,这次之后感觉 ...

  8. Git学习(一)——熟悉git操作流程

    本篇笔记前面都是仔细介绍使用方法,如果想跳过这些直接熟悉怎么使用,跳到最后一个知识点完整流程介绍. git 了解:特点.优点 1.git用户版和服务版整合在一起,任何机器上都安装了两个版本 2.git ...

  9. WUSTOJ 1321: Alphabet Cookies(Java)字符统计

    题目链接:1321: Alphabet Cookies Description Kitty likes cookies very much, and especially the alphabet c ...

  10. linux查看系统未被挂载的磁盘空间的方法

    原文URL:https://www.cnblogs.com/lemon-flm/p/7597403.html 解决AWS 挂载.解决挂载完重启就消失等问题 linux上的盘和window的有区别,磁盘 ...