测试技能提升篇——k8s的网络核心概念

 绝大多数刚刚接触k8s的同学都会被其中的网络相关知识点搞得晕头转向!各种IP,包括:Node IP,ClusterIP,Node IP纠结是啥东东?internet是怎样访问k8s的?k8s内部各个pod之间又是如何通信的?本文就为大家来解决上述问题。如果您想了解k8s更为全面的核心概念,请参考文章:测试技能提升篇——k8s的核心概念

K8s中网络核心概念介绍

Node IP

Node节点的IP地址,即物理网卡的IP地址。NodePort可以是物理机的IP(也可能是虚拟机IP)。每个Service都会在Node节点上开通一个端口,外部可以通过NodeIP:NodePort即可访问Service里的Pod,和我们访问服务器部署的项目一样,IP:端口/项目名

Cluster IP

Service的IP地址,此为虚拟IP地址。外部网络无法ping通,只有k8s集群内部访问使用。Cluster IP是一个虚拟的IP,但更像是一个伪造的IP网络,原因有以下几点

1.Cluster IP仅仅作用于k8s Service这个对象,并由k8s管理和分配P地址

2.Cluster IP无法被ping,他没有一个“实体网络对象”来响应

3.Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于k8s集群这样一个封闭的空间。

4.在不同Service下的pod节点在集群间相互访问可以通过Cluster IP

Pod IP

Pod IP是每个Pod的IP地址,他是Docker Engine根据docker网桥的IP地址段进行分配的,通常是一个虚拟的二层网络

同Service下的pod可以直接根据Pod IP相互通信

不同Service下的pod在集群间pod通信要借助于 cluster IP

pod和集群外通信,要借助于node IP

简单地总结:外部访问时,先到Node节点网络,再转到service网络,最后代理给pod网络。

K8s如何实现网络通信

三条核心原则

默认情况下,Linux 将所有的进程都分配到 root network namespace,以使得进程可以访问外部网络

K8s为每一个 Pod 都创建了一个 network namespace。

3.在 K8s中,Pod 是一组 docker 容器的集合,这一组 docker 容器将共享一个 network namespace。Pod 中所有的容器都使用该 network namespace 提供的同一个 IP 地址以及同一个端口空间。所有的容器都可以通过 localhost 直接与同一个 Pod 中的另一个容器通信。

容器与容器之间网络通信

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

pod与pod之间网络通信

从 Pod 的视角来看,Pod 是在其自身所在的 network namespace 与同节点上另外一个 network namespace 进程通信。在Linux上,不同的 network namespace 可以通过 Virtual Ethernet Device (opens new window) 或 veth pair (两块跨多个名称空间的虚拟网卡)进行通信。为连接 pod 的 network namespace,可以将 veth pair 的一段指定到 root network namespace,另一端指定到 Pod 的 network namespace。每一组 veth pair 类似于一条网线,连接两端,并可以使流量通过。节点上有多少个 Pod,就会设置多少组 veth pair。下图展示了 veth pair 连接 Pod 到 root namespace 的情况:

 为了让 Pod 可以互相通过 root network namespace 通信,我们将使用 network bridge(网桥)。Linux Ethernet bridge 是一个虚拟的 Layer 2 网络设备,可用来连接两个或多个网段。网桥的工作原理是,在源于目标之间维护一个转发表,通过检查通过网桥的数据包的目标地址和该转发表来决定是否将数据包转发到与网桥相连的另一个网段。桥接代码通过网络中具备唯一性的网卡MAC地址来判断是否桥接或丢弃数据。网桥实现了ARP协议来发现链路层与 IP 地址绑定的 MAC 地址。当网桥收到数据帧时,网桥将该数据帧广播到所有连接的设备上(除了发送者以外),对该数据帧做出相应的设备被记录到一个查找表中。后续网桥再收到发向同一个 IP 地址的流量时,将使用查找表来找到对应的 MAC 地址,并转发数据包。下图中cbr0就是网桥。


不同Node间通信原理

通常,集群中每个节点都被分配了一个 CIDR 网段(简单的理解CIDR可以把几个标准网络合成一个大的网络),指定了该节点上的 Pod 可用的 IP 地址段。一旦发送到该 CIDR 网段的流量到达节点,就由节点负责将流量继续转发给对应的 Pod。下图展示了两个节点之间的数据报文传递过程。

pod与service之间网络通信

Pod 的 IP 地址并非是固定不变的,随着 Pod 的重新调度(例如水平伸缩、应用程序崩溃、节点重启等),Pod 的 IP 地址将会出现又消失。此时,Pod 的客户端无法得知该访问哪个 IP 地址。k8s中,Service 的概念用于解决此问题。Service管理了多个Pods,每个Service有一个虚拟的ip,要访问service管理的Pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。当数据包到达Service虚拟ip后,数据包会被通过k8s给该servcie自动创建的负载均衡器路由到背后的pod容器。

我们知道Service 是 k8s中的一种服务发现机制,总结核心功能如下:

通常通过service来关联pod并提供对外访问接口;

Service 实现负载均衡,可将请求均衡分发到选定这一组 Pod 中;

Service 通过 label selector 选定一组 Pod。


Service的ip分配策略

k8s的一个设计哲学是:尽量避免非人为错误产生的可能性。就设计 Service 而言,k8s应该将您选择的端口号与其他人选择的端口号隔离开。为此,k8s为每一个 Service 分配一个该 Service 专属的 IP 地址。为了确保每个 Service 都有一个唯一的 IP 地址,k8s在创建 Service 之前,先更新 etcd 中的一个全局分配表,如果更新失败(例如 IP 地址已被其他 Service 占用),则 Service 不能成功创建。k8s使用一个后台控制器检查该全局分配表中的 IP 地址的分配是否仍然有效,并且自动清理不再被 Service 使用的 IP 地址。

Service的dns解析

k8s集群中运行了一组 DNS Pod,配置了对应的 Service,并由 k8s将 DNS Service 的 IP 地址配置到节点上的容器中以便解析 DNS names。集群中的每一个 Service(包括 DNS 服务本身)都将被分配一个 DNS name。默认情况下,客户端 Pod 的 DNS 搜索列表包括 Pod 所在的名称空间以及集群的默认域。例如:

假设名称空间 A中有一个 Service 名为 foo:

名称空间 A中的 Pod 可以通过 nslookup foo 查找到该 Service

名称空间 B中的 Pod 可以通过 nslookup foo.A 查找到该 Service

Internet与k8s的网络通信

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

NodePort

NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。

Service LoadBalancer

如果你想要直接暴露服务,这就是默认方式。所有通往你指定的端口的流量都会被转发到对应的服务。它设有过滤条件,路由等功能。值得一提的是,如果是在本地开发测试环境里头搭建的K8s,一般不支持Load Balancer也没必要,因为通过NodePort做测试访问就够了。但是在生产环境或者公有云上的K8s,基本都支持自动创建Load Balancer。

Ingress控制器

它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。它的本质上就是K8s集群中的一个比较特殊的Service(发布Kind: Ingress)。这个Service提供的功能主要就是7层反向代理(也可以提供安全认证,监控,限流和SSL证书等高级功能),功能类似Nginx。Ingress对外暴露出去是通过HostPort(80/443),可以和上面LoadBalancer对接起来。有了这个Ingress Service,我们可以做到只需购买一个LB+IP,就可以通过Ingress将内部多个(甚至全部)服务暴露出去,Ingress会帮忙做代理转发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342