上一篇:PaaS中OpenShift持久化存储的管理实践

由于 OpenShift 网络通信概念较多,相对理解起来困难,为了方便读者能够清晰深入内部,在开始网络模型讲解之前,我们先尝试从 OpenShift 的用户角度,提出 5 个问题,并对 5 个问题作出解答,先对 OpenShift 网络通信有个大致的概念。然后读者带着对这 5 个问题的理解,阅读本章节更为详细的内容。

1. OpenShift 中 Pod 之间通讯是否一定需要 Service?

答案:Pod 之间的通信不需要 Service。

在同一个 Namespace 中, Pod A 开放了某个端口,在一个 Pod B 中 curl pod_A_IP:port,就能与之通信,如下图 2-45 所示。

图 2-45 查看两个 pod 的 IP 地址

所以说:Pod 之间能不能通信,和两个 Pod 经不经过 Service、有没有 Service 无关。

2. 从一个 Pod 访问另外一个 Pod 可以通信,其数据链路是什么?

答案:两个 Pod 如果在一个 OpenShift 节点上,其通信流量没有绕出本宿主机的 OVS:如果两个 Pod 在不同节点上, Pod 之间的通信经过了 Vxlan。具体内容后文将展开说明。

3. 既然 Pod 之间通信不需要 Service,为何 Kubernetes 引入 Service?

我们首先要明确:Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的内部访问入口。它主要解决:

  1. 负载均衡:Service 提供其所属多个 Pod 的负载均衡

  2. 服务注册与发现:解决不同服务之间的通信问题。在 OpenShift 中的创建应用后,需要提供访问应用的地址供其他服务调用,这个地址就是由 Service 提供。

在 OpenShift 中,我们每创建一个 Service,会分配一个 IP 地址,称为 ClusterIP,这个 IP 地址是一个虚拟的地址(OpenShift 外部不可达),这样内部 DNS 就可以通过 Service 名称(FQDN)解析成 ClusterIP 地址。这就完成了服务注册,DNS 解析需要的信息全部保存在 Etcd 中。

那么,Service 注册到 Etcd 的内容是什么呢?

实际上是 Service 资源对象的 Yaml 包含的相关内容。

也就是说,Etcd 中记录的 Services 注册信息里有 Namespace,Service Name,ClusterIP 等,通过这三个信息就可组成 DNS A 记录,也就是,Service 的 FQDN 和 Service ip 之间的对应关系。需要说明的是,Etcd 不是 DNS,DNS A 记录是通过查询生成的。OpenShift 的 DNS 是由 SkyDNS/CoreDNS 实现的(后面内容详细介绍)。

服务发现这个词经常被妖魔化。它的作用是为了 OpenShift 某个服务发现另外一个服务。也就说,Service A 要和 ServiceB 通讯,我需要知道 ServiceB 是谁、在哪、Cluster IP、对应的 Pod IP 都是什么?这就叫服务发现。

4. 有了 Service 以后,Pod 之间的通讯和没有 Service 有何区别?

在数据通讯层,没区别,因为 Service 只是逻辑层面的东西。

但是,没有 Service,多个 Pod 无法实现统一入口,也无法实现负载均衡。也就是说,没有 Service,多个 Pod 之间的负载均衡就要依赖第三方实现。

那么,有了 Service 以后,Pod 之间怎么寻址?

回答这个问题,我们要站在开发者角度。如果一个程序员,要写微服务,微服务之间要相互调用,怎么写?写 Pod IP 和 ClusterIP 是不现实的,因为这两个 IP 可能发生变化。

如果程序员决定用 Kubernetes 做服务发现的前提下(如果使用微服务框架中的服务注册中心做服务注册发现,可以不使用 Kubernetes 的 Service),实现不同服务之间的调用,那么就需要使用 Kubernetes 的 Service 名称。因为 Service 名称我们是可以固定的。

OpenShift/Kubernetes 中 Service 有短名和长名。以下图 2-46 为例,jws-app 就是 Service 的短名,Service 长名的格式是:..svc.cluser.local,也就是 jws-app.web.svc.cluser.local。Service 短名可以自动补充成长名,这是 OpenShift 中的 DNS 做的,这个后面介绍。

图 2-46 查看 Service 的名称

那么,如果在两个不同的 Namespace 中,有两个相同的 Service 短名,微服务调用不是会出现混乱?程序员的代码里是不是要写 Service 全名?

首先,站在 OpenShift 集群管理员的角度,我们看所有的项目,有几十个或者而更多,会觉得在不同 Namespaces 中存在相同的 Service 短名是可能(比如 Namespace A 中有个 acat 的 Service,Namespace B 中也有个 acat 的 Service)。但站在程序员角度,他只是 OpenShift 的使用者、拥有有自己的 Namespace 的管理权,其他 Namespace 不能访问。而且绝大多数情况下,同一个业务项目的微服务一般会运行在同一个 Namespace 中,默认如果使用短名称(只写 Service Name),则会自动补全成当前 Namespace 的 FQDN,只有在跨 Namespace 调用的时候才必须写全名 FQDN。

所以,程序员写的程序用到了 Service Name。那么,真正运行应用的 Pod 之间的通讯,也必然会以 Service Name 去找。通过 Service 名称解析为 Service ClusterIP,然后经过 Kube-proxy(默认 Iptables 模式)的负载均衡最终选择一个实际的 Pod IP。找到 Pod IP 以后,接下来就会进行实际的数据交换,这就和 Service 没有关系了。

5. ClusterIP 到 Pod IP 这部分的负载均衡怎么实现的?

目前版本 OpenShift 中是通过 kube-proxy(iptables 模式)实现的。具体内容后面内容详细介绍。

6

通过以上 5 个问题的问答,相信很多读者关于 OpenShift 通信网络的疑问有了大致的了解。接下来,我们针对 OpenShift 的网络通信展开讲述。

7

OpenShift 的网络模型

OpenShift 的网络模型继承于 Kubernetes,从内到外共包含如下四个方面:

  1. Pod 内部容器通信的的网络。

  2. Pod 与 Pod 通信的网络。

  3. Pod 和 Service 之间通信的网络。

  4. 集群外部与 Service 或 Pod 通信的网络。

这四部分构成了整个 OpenShift 的网络模型,下面我们分别进行说明。

7.1

Pod 内部容器通信的网络

我们都知道 Pod 是一组容器的组合,意味着每个 Pod 中可以有多个容器存在,那么这多个容器之间如何通信呢?这就是这部分要解决的问题。

Kubernetes 通过为 Pod 分配统一的网络空间,实现了多个容器之间网络共享,也就是同一个 Pod 中的容器之间通过 Localhost 相互通信。

7.2

Pod 与 Pod 通信的网络

关于这部分 Kubernetes 在设计之时的目标就是 Pod 之间可以不经过 NAT 直接通信,即使 Pod 跨主机。而这部分 Kubernetes 早期并未提供统一标准的方案,需要用户提前将节点网络配置完成,各个厂商提供了不同的解决方案,诸如 Flannel、OVS 等等。随着 Kubernetes 的发展,在网络方向上希望通过统一的方式来集成不同的网络方案,也就有了现在的网络开放接口 CNI(Container Network Interface)。

CNI 项目是由多个公司和项目创建组成的,包括 CoreOS、红帽、Apache Mesos、Cloud Foundry、Kubernetes、Kurma 和 rkt。CoreOS 首先提出定义网络插件和容器之间的通用接口,CNI 被设计为规范,它仅关注容器的网络连接并在删除容器时删除分配的网络资源。

CNI 有三个主要组成部分:

  1. CNI 规范:定义容器运行时和网络插件之间的 API。

  2. 插件:对各种 SDN 对接的组件。

  3. 库:提供 CNI 规范的 Go 实现,容器运行时可以使用它来便捷地使用 CNI。

各厂商遵守规范开发网络组件,在技术实现上共分为两大阵营:

  1. 基于二层实现:通过将 Pod 放在一个大二层网络中,跨节点通信通常使用 Vxlan 或 UDP 封包实现,常用的此类插件有 Flannel(UDP 或 Vxlan 封包模式)、OVS、Contiv、OVN 等。

  2. 基于三层实现:将 Pod 放在一个互联互通的网络中,通常使用路由实现,常用的此类插件有 Calico、Flannel-GW、Contiv、OVN 等。

可以看到网络插件的种类较为繁多,OpenShift 默认使用的是基于 OVS 的二层网络实现 Pod 与 Pod 之间的通信,后面我们将详细介绍。

7.3

Pod 和 Service 之间通信的网络

Pod 与 Service 之间的通信主要指在 Pod 中访问 Service 的地址。在 OpenShift 中, Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的内部访问入口。主要解决以下两个问题:

服务注册与发现:服务注册发现在微服务架构中,解决不同服务之间的通信问题。在 OpenShift 中的创建应用后,需要提供访问应用的地址供其他服务调用,这个地址就是由 Service 提供。

每创建一个 Service 会分配一个 Service IP 地址,称为 ClusterIP,这个 IP 地址是一个虚拟的地址,无法执行 ping 操作。同时自动在内部 DNS 注册一条对应的 A 记录,这就完成了服务注册,注册信息全部保存在 Etcd 中。服务发现支持环境变量和 DNS 两种方式,其中 DNS 的方式最为常用,关于 DNS 的部分我们将在后面章节详细说明。

负载均衡:每个 Service 后端可能对应多个 Pod 示例,在访问 Service 的时候需要选择一个合适的后端处理请求。

Service 的负载均衡可以由很多的实现方式,目前 Kubernetes 官方提供了三种代理模式:userspace、iptables、ipvs。目前版本 OpenShift 默认的代理模式是 iptables,本文主要介绍这种模式。有兴趣的读者参考 Kubernetes 官网中对 Service 的介绍自行了解其他模式。

Iptables 模式官方示意图如下图 2-47 所示:

图 2-47 Iptables 模式

从图中可以看出,当客户端访问 Servcie 的 ClusterIP 时,由 Iptables 实现负载均衡,选择一个后端处理请求,默认的负载均衡策略是轮询。在这种模式下,每创建一个 Service,会自动匹配后端实例 Pod 记录在 Endpoints 对象中,并在所有 Node 节点上添加相应的 iptables 规则,将访问该 Service 的 ClusterIP 与 Port 的连接重定向到 Endpoints 中的某一个后端 Pod,由于篇幅有限,关于负载均衡实现的细节不再赘述。

这种模式有两个缺点需要关注:

第一,不支持复杂的负载均衡算法;

第二,当选择的某个后端 Pod 没有响应时,无法自动重新连接到另一个 Pod,用户必须利用 Pod 的健康监测来保证 Endpoints 列表中 Pod 都是存活的。

集群外部与 Service 或 Pod 通信的网络上节中我们说过,创建 Service 分配的 ClusterIP 是一个虚拟 IP 地址,外部是无法访问的,那么该如何实现集群外部访问部署在集群中的应用呢?

目前 OpenShift 共有以下五种对外暴露服务的方式:

  • Hostport

  • Nodeport

  • Hostnetwork

  • Ingress/router

  • LoadBalancer

不同方式的使用场景各不相同,关于每种方式的具体细节我们将在后面小节中进行说明。

8

多租户的隔离

对于 OpenShift 来说,认为一个 Namespace 就是一个租户,实现多组户隔离主要表现在网络上,即每个租户都拥有与其他租户完全隔离的自有网络环境。而 OpenShift 的网络可以由多种第三方插件实现,是否支持多租户隔离要看选择的 Pod 网络插件。目前广泛使用的是通过网络策略控制网络隔离,网络策略采用了比较严格的单向流控制,最小粒度可控制到 Pod 与 Pod,而不仅仅是 Namespace 级别的隔离。

在了解了 OpenShift 网络模型之后,可以看到 OpenShift 网络涉及的范围大而复杂,除了 Pod 内部容器通信比较简单、无需管理之外,其余的四部分都是可以配置管理的,如替换不同的插件或者通过不同的方式实现。

本文选自《OpenShift 在企业中的实践》(第 2 版),经出版社授权发布。

推荐语:经典畅销书再次升级!红帽首席解决方案架构师联合撰写,20位全球知名企业IT负责人推荐,基于OpenShift v4,详述PaaS、DevOps、云原生、微服务治理。完整描绘企业数字化转型路线,为企业通过OpenShift实现IT转型给出具体建议和参考架构。

推荐阅读

分布领域驱动设计(DDD):领域接口化设计式缓存的选择

2021-09-27

2W 字详解设计模式!

2021-09-22

PaaS中OpenShift持久化存储的管理实践

2021-10-18

消息幂等(去重)通用解决方案,RocketMQ

2021-10-11

柴华:DDD在哈啰交易中台的实践

2021-09-02

肖然:DDD分层架构的代码结构实战

2021-08-26

资深架构师谈 DDD 兴起,解决难题与实现步骤

2021-08-23

DDD 搭上了微服务这个顺风车,又快又稳

2021-07-15

从架构演进谈 DDD 兴起的原因以及与微服务的关系

2021-06-30

微服务等于Spring Cloud?了解微服务架构和框架

2021-10-21

限流 & 熔断的考量

2021-10-19

用企业架构下好数字化转型这盘大棋

2021-10-25

技术架构的战略和战术原则

2021-10-25

2021 编程语言排行榜

2021-10-22

微服务等于Spring Cloud?了解微服务架构和框架

2021-10-21

一个电商供应链系统的DDD实战

2021-10-20

解密OpenShift内部通信网络相关推荐

  1. 中国版ChatGPT高潮即将到来,解密ChatGPT底层网络架构

    2022年11月30日人工智能研究实验室OpenAI发布全新聊天机器人ChatGPT,在中国用户无法访问的前提下,上线仅两个月月活用户就突破了1亿.ChatGPT如同重磅炸弹,一时间火遍全球. 面对这 ...

  2. 解析OpenShift的存储规划

    上一篇分享了:PaaS中OpenShift持久化存储的管理实践和 解密OpenShift内部通信网络 本篇继续分享OpenShift的存储规划 1 OpenShift 使用存储类型选择 选择合适的存储 ...

  3. 从0开始搭建公司后台技术栈,这套架构值得拥有...

    来源:ju.outofmemory.cn/entry/351897 有点眼晕,以下只是我们会用到的一些语言的合集,而且只是语言层面的一部分,就整个后台技术栈来说,这只是一个开始,从语言开始,还有很多很 ...

  4. 《网络营销推广技术、技巧深度解密》文档

    在这个"互联网时代"里,我们见多了各种关于"网络营销推广"方面的导师,也听过.学过这些导师们的课程,我们不得不承认,很多所谓的"干货"只是& ...

  5. 揭秘:《网络营销推广技术、技巧深度解密》的前世今生

    互联网发展到今天,各种营销方法.推广渠道都陆陆续续的涌现出来,大家也真正意识到了"互联网"确实是当下进行营销推广的一个即有效果又费用低的好载体. 俗话说:"哪里有钱赚,哪 ...

  6. 从ODX(Open diagnostic Data eXchange)谈车联网应用绕不开的底层网络“基建”

    前言:"车联网应用代表着资本的下一个风口,也是汽车电子技术竞争的重要角斗场.但与其谈些美妙的应用设想,不妨构想下让为这些应用成为现实的"基建工程",即真正地让车和外部通信 ...

  7. 叙述无保密机制的rsa签名过程_安全系列之——RSA的公钥私钥有多少人能分的清楚?RSA的签名验签与加密解密如何使用公私钥?...

    在对接很多的互联网公司的开发平台时,这些互联网公司未来自身平台的安全,都会需要调用方签名确认调用方的身份是合法的,同时未来信息网络传输的安全可能还需要加密解密.比如对接支付宝.微信开放平台时,需要配置 ...

  8. 给fiddle 解密_fiddler学习笔记2 字段说明;移动设备、解密证书

    # :           抓取顺序从1开始递增 result:    http 请求状态 protocol:   请求使用的协议如:http https ftp Host:         请求地址 ...

  9. OpenShift 4 - 通过设置SDN的NetworkPolicy定义Pod访问策略

    <OpenShift 4.x HOL教程汇总> 说明:本文已经在OpenShift 4.9环境中验证 文章目录 NetworkPolicy简介 应用环境和测试方法 部署测试应用 测试验证 ...

最新文章

  1. IOS的UI基础02
  2. 【阿里云课程】图神经网络基础:图的应用、表示与图卷积
  3. WDS 自动化部署安装 win2008 服务器实验
  4. mysql该账户已存在_mysql 查看函数的所属用户和已存在的函数
  5. 新版本阿里云网站的云服务器添加安全组规则
  6. 【蓝桥杯嵌入式】【STM32】7_RTC之实时时间显示和硬件闹钟设置
  7. 前缀树(字典树,单词查找树,Trie树)
  8. 工信部同意中国互联网信息中心设立域名根服务器及运行机构
  9. Java集合(十三)Iterator和Enumeration的区别和对比
  10. c语言创意作业蜂鸣器,蜂鸣器c语言程序_c语言编写蜂鸣器发声
  11. 在ppt中怎么加入倒计时 里面怎么加入倒计时【方法】
  12. axios跨域访问报错500
  13. 基于遗传算法的新安江模型参数优化率定(二)
  14. html5 梵高 星,上海梵高星空艺术馆门票
  15. python案例3:货币转换---初级
  16. 用 js 开启本地服务器,实现短信发送
  17. 在EXCEL中如何设置打印区域,只打印部分区域
  18. 混沌者 pat basic 练习七十一 小赌怡情
  19. Python中jieba库的安装方法
  20. IntelliJ IDEA:安装/搭建/配置/插件

热门文章

  1. android outofmemory 原理及解决方案
  2. 操作系统之I/O管理:4、缓冲区管理(单缓冲、双缓冲、循环缓冲、缓冲池)
  3. USACO-Section1.3 Milking Cows (区间问题)
  4. Shell sed命令,替换文件内容、替换目录下所有文件内容、读取文件内容
  5. Python 域名转IP(可包含http、https)
  6. golang map使用总结
  7. jqgrid表格下拉搜索多选框优化—使用select下拉多选插件
  8. js获取数组前n项的和
  9. php生成随机验证码
  10. Manasa and Combinatorics