技术

对容器云平台的理解 Prometheus 源码分析 并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go细节 codereview mat使用 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 MVCC 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes自动扩容缩容 神经网络模型优化 直觉上理解机器学习 knative入门 如何学习机器学习 神经网络系列笔记 TIDB源码分析 《阿里巴巴云原生实践15讲》笔记 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 扩展Kubernetes 副本一致性 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全机制 jvm crash分析 Kubernetes监控 Kubernetes 控制器模型 Prometheus 学习 容器日志采集 容器狂占cpu怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes objects之编排对象 源码分析体会 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 kubernetes实践 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 《深入剖析kubernetes》笔记 精简代码的利器——lombok 学习 编程语言的动态性 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 分布式计算系统的那些套路 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 mysql 批量操作优化 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 calico学习 AQS2——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 硬件对软件设计的影响 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记2 《mysql技术内幕》笔记1 log4j学习 为什么netty比较难懂? 回溯法 apollo client源码分析及看待面向对象设计 学习并发 docker 环境(主要运行java项目)常见问题 Scala的一些梗 OpenTSDB 入门 spring事务小结 事务一致性 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型 java exception Linux IO学习 network channel network byte buffer 测试环境docker化实践 netty(七)netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 Macvlan Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker中涉及到的一些linux知识 hystrix学习 Linux网络源代码学习——整体介绍 zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty(六)netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 Redis概述 机器学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 异构数据库表在线同步 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM内存与执行 git spring rmi和thrift maven/ant/gradle使用 再看tcp 缓存系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 VPN(Virtual Private Network) Kubernetes存储 Kubernetes 其它特性 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 使用etcd + confd + nginx做动态负载均衡 如何通过fleet unit files 来构建灵活的服务 CoreOS 安装 CoreOS 使用 Go学习 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

标签


程序猿视角看网络

2018年03月08日

简介

数据中心网络架构浅谈(三) 中提到:之所以写,是想提供一个非网工的,云计算从业人员的视角。本文也尝试从一个 程序猿的视角,来汇总网络方面的一些知识。

网络分块和分层

为什么要分层

2019.7.5补充:虽然全世界组成一张大的互联网,美国的网站你也能够访问的,但是这个网络不是一整个的。你们小区有一个网络,你们公司也有一个网络,联通、移动、电信运营商也各有各的网络,所以一个大网络是被分成个小的网络。network layer以下就是解决 “小网络”内的事儿。PS:就好像看地图是一片,但实际因为山川河流阻隔,都是一块一块的。去一个地方看似都能走,实际就几条路。

The Layers of the OSI Model Illustrated

为什么网络要分层?因为是个复杂点的程序都要分层。

It conceptually divides computer network architecture into 7 layers in a logical progression. The lower layers deal with electrical signals, chunks of binary data, and routing of these data across networks. Higher levels cover network requests and responses, representation of data, and network protocols as seen from a user’s point of view.

网络各层

层次 数据组织 概念 每一层除数据包不同之外,知道哪一层在哪些行为里也很重要
Physical Layer bit    
Data Link Layer frame mac 1. checks for physical transmission errors
2. packages bits into data “frames”
3. manages physical addressing schemes such as MAC addresses
Network Layer package ip 承担了分组(Packet)转发和路由选择两大功能
1. 根据目的ip地址determine if the data has reached its final destination.
2. If the data has reached the final destination, this Layer 3 formats the data into packets delivered up to the Transport layer. Otherwise, the Network layer updates the destination address and pushes the frame back down to the lower layers.
3. adds the concept of routing above the Data Link layer
4. To support routing, the Network layer maintains logical addresses such as IP addresses for devices on the network.
5. manages the mapping between these logical addresses and physical addresses(ARP)
Transport Layer   error recovery, flow control, re-transmission. etc  

二层到四层都是在 Linux 内核里面处理的

《网络是怎样连接的》:IP 和Ethernet的分工,其中Ethernet的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH 等,它们都可以替代以太网的角色帮助 IP 协议来传输网络包 要使用各种通信技术。像互联网这样庞大复杂的网络,在架构上需要保证 灵活性,这就是设计这种分工方式的原因。

网路通信

本小节来自《Paas实现与运维管理》的笔记。

我们将网络世界的物理设备抽象为三种:计算节点,交换节点和路由节点

  1. 因为计算节点不能两两相连,所以我们需要一个交换节点,负责转发数据。在数据链路层范围内

    • 计算节点在发送数据的时候,应用程序中不可能直接写目的主机的mac地址,所以我们需要一个虚拟地址,即ip地址。arp请求(广播)及arp缓存。
    • 交换节点收到一个包,在转发这个包的时候,没有mac地址与端口的映射,会先广播,然后建立mac地址与串口的映射关系。
  2. 因为一个交换节点负责不了世界上的所有计算节点,(不然广播域也太大了),所以我们需要一个路由节点。

    • 计算节点在发送数据时,通过ip+掩码来判断目的计算节点是否在一个子网内。当发现不在一个子网时,它会将数据包发送给子网内的路由节点(也就是网关)。
    • 路由器根据路由表中的策略来接收和发送包。这就不能叫转发了,因为路由器会修改数据包。路由表中的rule可以静态设置,也可以动态学习。

修正自己以前的几个误区:

  1. 除了功能不同,交换节点和路由节点的另一个区别:交换节点并不修改package
  2. 实际上,计算节点通过交换节点向路由节点发送数据,交换节点转发包可以理解为透明。所以是:计算节点 ==> 路由节点 ==> 计算节点 实现跨网络传输
  3. 不仅计算节点有数据通信,路由节点也有数据通信
  4. 在一个网络数据包传输的过程中(跨网络+路由器),都是源/目标mac在变,源/目标ip都没变

网络发现

Computer networkNetwork是一组可以相互通信的Endpoints,网络提供connectivity and discoverability

尤其是对于discoverability,在网络的各个层次都有体现

  1. dns,有专门的dns服务器,在host组装数据包之前 根据dns 将域名转换为ip
  2. arp,在host 发出frame之前,根据arp 获取目的主机的mac地址
  3. 路由器之间的路由同步协议
  4. 边界路由器之间的路由同步协议,比如bgp
  5. 在oveylay 网络中,经常将 虚拟机/容器/网段在哪个主机上 等信息保存在zk/etc中。

解决了discoverability,数据包发向哪里都明确了,交换设备通过简单的复制,将数据包转发给目的设备,提供connectivity

网络路由——寻找下一跳地址

路由表同时记录了目的计算机地址、下一跳地址和网络接口的关联信息。所谓下一跳地址就是:如果 IP 包从主机 A 发到主机 B,需要经过路由设备 X 的中转。那么 X 的 IP 地址就应该配置为主机 A 的下一跳地址。一旦A配置了下一跳地址,那么接下来,当 IP 包从网络层进入链路层封装成帧的时候,eth0 设备就会使用下一跳地址X_IP对应的 MAC 地址,作为该数据帧的目的 MAC 地址。网关/下一跳的 IP 地址不会出现在任何网络包头中

frame header frame body
A mac X mac A ip B ip body
  1. 如果要访问的目标IP跟自己是一个网段的(根据CIDR就可以判断出目标端IP和自己是否在一个网段内了),就不用经过网关了,先通过ARP协议获取目标端的MAC地址,源IP直接发送数据给目标端IP即可。

    frame header frame body
    A mac B mac A ip B ip body

    如何是一个局域网的, you can just send a packet with any random IP address on it, and as long as the MAC address is right it’ll get there.

  2. 如果访问的不是跟自己一个网段的,就会先发给网关(哪个网关由 The route table 确定),然后再由网关发送出去,网关就是路由器的一个网口,网关一般跟自己是在一个网段内的,通过ARP获得网关的mac地址,就可以发送出去了

    frame header frame body
    A mac gateway mac A ip B ip body
  3. 主机/直接路由 强行指定下一跳地址

    $ ip route
    ...
    10.244.1.0/24 via 10.168.0.3 dev eth0
    

    目的 IP 地址属于 10.244.1.0/24 网段的 IP 包,应该经过本机的 eth0 设备发出去(即:dev eth0);并且,它下一跳地址(next-hop)是 10.168.0.3(即:via 10.168.0.3)。

传统网络架构

网络间通信——网关和路由器

网关,默认网关,自动网关,路由,网关与路由器的关系

  1. 在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。而要实现两个网络之间的通信,则必须通过网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。
  2. 路由器使用静态路由或动态路由来决定网络间的最短路径。

从网关和路由器的定义来看,如果只是简单地连接两个网络,那么只需要网关就足够了。因为只有两个网络,不需要决定网络间最短路径。如果需要连接多个网络,为了保证网络的可靠性,网络结构需要设计为全网状或部分网状,这样,为了网络间的通信,需要网关和路由器两种设备(比如网络A到网路D有两种路径,A-B-D/A-C-D,需要网关连通B和C,需要路由器决策选取哪种路径),因为当前路由器集成了网关的功能,所以只使用路由器一种设备就可以了。

抛开这些陈年往事,从现在情境看,网关实质上是一个网络通向其他网络的IP地址。路由器是一个设备,可以做网关使用。它是一种连接多个网络或网段的网络设备,从而构成一个更大的网络。

linux 的路由表

笔者的直观感受 一直是,路由是路由器做的事儿,既然如此,为了linux 中还有一个路由表?

普通的主机与路由器之间的根本区别在于:主机不会将一个报文从一个接口转发到另一个接口,而路由器可以转发报文。但是,一个普通路由算法可以被用在路由器上,同样也可以用在一台普通主机上。当一台主机可以用作路由器时,我们通常说这台主机嵌入了路由器的功能。这种具备嵌入路由器功能的主机平常不会转发报文,除非我们对它进行了配置,使它开启这种功能。

Linux路由分析提到: Linux默认情况下会丢掉不属于本机IP的数据包(类似的,网卡默认会丢弃mac地址不是本网卡的数据包,除非开启混杂模式)。将net.ipv4.ip_forward设置为1后,会开启路由功能,Linux会像路由器一样对不属于本机的IP数据包进行路由转发。linux 有路由表,是因为开启了路由功能。

root@ubuntu-1:/home/ops# ip route
default via 10.0.2.2 dev enp0s3
10.0.2.0/24 dev enp0s3  proto kernel  scope link  src 10.0.2.15
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1 linkdown
172.32.135.128/26 via 192.168.56.103 dev tunl0  proto bird onlink
blackhole 172.32.185.64/26  proto bird
172.32.185.70 dev calie34960bc671  scope link
172.32.185.71 dev cali6d5e7989019  scope link
172.32.243.0/26 via 192.168.56.102 dev tunl0  proto bird onlink
192.168.56.0/24 dev enp0s8  proto kernel  scope link  src 192.168.56.101

如何看待这个输出 route table explanation

proto,发现该路由的路由协议(即路由来源),一般是协议名,proto kernel 表示 The route was installed by the kernel during autoconfiguration.

scope,The scope of a route in Linux is an indicator of the distance to the destination network.

  • Link-local address are supposed to be used for addressing nodes on a single link. Packets originating from or destined to a link-local address will not be forwarded by a router. 还有一种说法 valid only on this device
  • Site,valid only within this site (IPv6)
  • Host,A host address is something that will only exist within the host machine itself. For instance 127.0.0.1 is a host address commonly assigned to the loopback interface. The loopback interface has no external connectivity and so it’s scope is confined to within that of the host machine.
  • A global address is what you might currently consider a “normal” address. Global which is visible on and routable across an external network.

数据中心网络架构

数据中心网络架构和传统网络架构的不同:数据中心网络架构 更侧重局域网,更多的使用交换机, 交换机之间怎么连接都可以玩出花活儿来,比如fabric。

路由器的每一个port 都对应一个网卡(三层交换机类似,有待验证),都有ip和mac地址,这是其与二层交换机port 不同的地方,后者只是一个port。

整体结构

数据中心网络架构 也可以说是一种 网络硬件设备架构

数据中心网络架构浅谈(一)要点:

  1. 数据中心网络架构、三层网络架构、大二层网络架构 是什么?
  2. 数据中心网络,本质上是一个局域网, 但机器很多,为了减少网络广播等考虑,通常会划分几个子网。
  3. 一个交换机最多也就几百个端口,再多的话,交换这么多数据太忙了,接那么多物理机 接口也挺麻烦的。所以,一个交换机是无法支撑一个数据中心网络架构的
  4. 交换机可以只是单纯的连接物理机,提供连通性,比如access switch(通常一个机架一个)。也可以是一个子网入口,或者一个词POD(Point Of Delivery)
  5. 互联网的发展,使得数据中心以南北流量(数据中心的主机与外网相互访问)为主转变为东西流量(数据中心内主机彼此访问)为主。比如hadoop 集群就只是内网彼此访问
  6. 虚拟化的流行 大大提高了单台服务器的利用率,单台服务器网络流量也随之提高
  7. 东西流量要求原来的 三层网络架构 的核心交换机(core switch)具备很高的性能,代价较高

数据中心网络架构浅谈(二)

  1. Fabric网络架构,fabric 一词的由来

数据中心网络架构浅谈(三)

  1. 虚拟网络 和 物理网络是紧密联系的。
  2. overlay网络,只要求物理网络提供连通性。只要hostA(192.168.0.0/16)和 hostB(172.16.0.0/16)连通,就可以提供一个10.10.0.0/16 网络来。物理网络上跑的 数据包 还都是 hostA和 hostB的。

二层网络与三层网络

二层网络结构和三层网络结构的对比在这里的二层、三层是按照逻辑拓扑结构进行的分类,并不是说ISO七层模型中的数据链路层和网络层,而是指数据中心网络架构,具体的说是核心层,汇聚层和接入层,这三层都部署的就是三层网络结构,二层网络结构没有汇聚层。数据中心网络架构浅谈(一)

  1. 二层交换机根据MAC地址表进行数据包的转发,有则转发,无则泛洪。即将数据包广播发送到所有端口,如果目的终端收到给出回应,那么交换机就可以将该MAC地址添加到地址表中。但频繁这样做,在大规模网络架构中会形成网络风暴,限制了二层网络的规模。
  2. 三层交换机工作原理文中提到了vlan场景下的三层交换过程。如果来一个非同一网段ip1,交换机可以通过查询过程建立ip1与port1 的映射关系,此后,去向ip1的包直接由port1转发。

其它:

为什么三层交换机无法替代路由器? - 萧骁的回答 - 知乎提高三层交换机与路由器的区别时提到:

  1. 三层交换机: 三层交换技术就是将路由技术与交换技术合二为一的技术。在对第一个数据流进行路由后,它将会产生一个MAC地址与IP地址的映射表,当同样的数据流再次通过时,将根据此表直接从二层通过而不是再次路由,从而消除了路由器进行路由选择而造成网络的延迟,提高了数据包转发的效率。三层交换技术就是二层交换技术+三层转发技术。它解决了局域网中网段划分之后,网段中子网必须依赖路由器进行管理的局面,解决了传统路由器低速、复杂所造成的网络瓶颈问题。三层交换机的路由功能通常比较简单,因为它所面对的主要是简单的局域网连接。
  2. 路由器,本质是维护ip与port的关系,其处理过程从不涉及mac。路由器的重点是向网络中广播和更新自己的路由信息。路由器一般由基于微处理器的软件路由引擎执行数据包交换,虽然也适用于局域网之间的连接,但更主要的是路由功能,更多的体现在不同类型网络之间的互联上。
  3. 三层交换机的最重要的目的是加快大型局域网内部的数据交换,所具有的路由功能也是为这目的服务的,能够做到一次路由,多次转发。对于数据包转发等规律性的过程由硬件高速实现,更适用于数据交换频繁的局域网中。

交换机,维基百科解释:是一个扩大网络的器材,能为子网络中提供更多的port,以便连接更多的电脑。

二层交换机、三层交换机和路由器的基本工作原理和三者之间的主要区别出于安全和管理方便的考虑,主要是为了减小广播风暴的危害,必须把大型局域网按功能或地域等因素化成一个个小的局域网,这就使得VLAN技术在网络中得到大量应用,而不同VLAN之间的通信都要经过路由器来完成转发,随着网间互访的不断增加。单纯使用路由器来实现网间访问,不但由于端口数量有限,而且路由速度较慢。从而限制了网络的规模和访问速度。基于这种情况三层交换机便应用而生。

所谓的二层设备、三层设备,都是这些设备上跑的程序不同而已。什么叫二层设备呀,就 是只把 MAC 头摘下来,看看到底是丢弃、转发,还是自己留着。那什么叫三层设备呢?就是把 MAC 头摘下来之后,再把 IP 头摘下来,看看到底是丢弃、转发,还是自己留着。

其它

NAT

为什么 IPv6 难以取代 IPv4网络地址转换(Network Address Translation、NAT)是一种在 IP 数据包通过路由器时修改网络地址的技术,它能够将当前地址空间中的 IP 地址映射到另一个地址空间。

当数据包从内部访问外部网络时,NAT 会为当前请求分配一个端口、覆写数据包中的源地址和端口并将地址和端口信息存储到本地的转换表中;当数据包从外部进入网络内部时,NAT 会根据数据包的 IP 地址和端口号查找到私有网络中对应的主机和端口号并覆写数据包中的目的地址和端口。

通过 NAT 这一中间层,我们不仅可保护私有的网络,还能缓解 IP 地址的短缺问题。不过 NAT 技术也并不是只有好处,它也带来了很多的问题,在 NAT 网络下的主机并不能与对端建立起真正的端到端连接,也不能参与部分因特网协议。

隧道技术

为什么需要IP隧道?为了在TCP/IP网络中传输其他协议的数据包

Linux Networking/IPIP Encapsulation

Linux ipip隧道及实现

隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址

PPP、PPTP和L2TP等协议或软件不是基于内核模块的,Linux系统内核实现的IP隧道技术主要有三种,都是不加密的。对于ip 连通的hostA 和 hostB来说(可以直接连通,或者hostA ==> routeA ==> routeB ==> hostB):

  1. ipip,点对点tunnel,hostA和hostB 均包含tunnel设备(负责解封包)
  2. gre,解封包在 routeA 和 route B 上完成,hostA 和host B 只需要配置路由即可。因而支持广播。
  3. sit

为什么隧道封装是Docker多数网络项目的共同选择?

  1. 对于厂商来说,docker网络可能跨多个环境,统一acl等比较复杂
  2. 容器相较于虚拟机在一台主机上的密度大大增加