• 《Kubernetes权威指南》——网络原理


    1 Kubernetes网络模型

    基本原则:每个Pod都拥有一个独立IP,而且假定所有Pod都在一个可以直接连通的、扁平的网络空间中。

    • 基于基本原则,用户不需要额外考虑如何建立Pod之间的连接,也不需要考虑容器端口映射到主机端口等问题
    • 同一个Pod内部的所有容器共享一个网络堆栈即网络命名空间,Pod内的所有容器的端口是共享的
    • Kubernetes对集群网络要求:
      • 所有容器都可以在不用NAT的方式下同别的容器通信
      • 所有节点都可以在不用NAT的方式下同所有容器通信,反之亦然
      • 容器的地址和别人看到的地址是同一个

    2 Docker的网络基础

    2.1 网络命名空间

    • Linux在网络栈中引入网络命名空间(Network Namespace)为了支持网络协议栈的多个实例,处于不同命名空间的网络栈是完全隔离的
    • Linux的网络命名空间内可以有自己独立的路由表及独立的Iptables/Netfilter设置来提供转发、NAT及IP包过滤等功能
    • 需要纳入命名空间的元素有进程、套接字、网络设备等

    2.1.1 网络命名空间的实现

    • linux实现网络命名空间的核心是让网络栈的全局变量变成一个Net Namespace变量的成员,然后协议栈的函数调用加入一个Namespace的参数
    • 网络空间链表连接所有网络空间,所有网络栈变量都放入到网络空间
    • 所有的网络设置都只能属于一个命名空间,通常物理设置只能关联到root这个命名空间
    • 网络命名空间代表是一个独立的协议栈,所以他们之间是相互隔离的彼此无法通信协议栈内部看不到对方

    2.1.2 网络命名空间的操作

    使用iproute2系列配置工具中的ip命令操作

    ip netns add <name>     #创建一个命名空间
    
    ip netns exec <name> <command>  #在命名空间内执行命令
    
    ip netns exec <name> bash   #执行多个命令先进入sh
    

    2.2 Veth设备对

    Veth设备都是成对出现的,可以实现不同网络命名空间之间进行通信

    • 在Veth设置的一端发送数据时它会将数据直接发送到另一端,并触发另一端的接收操作

    2.2.1 Veth操作命令

    ip link add veth0 type veth peer name veth1     #创建veth设备对
    
    ip link show    #查看所有网络接口
    
    ip link set veth1 netns netns1  #将veth1挂载到netns1命名空间下
    
    ip link set dev veth1 up    #启动veth1设备
    

    2.2.2 Veth设备对如何查看对端

    使用ethtool工具查看

    ip netns exec netns1 ethtool -S veth1   #查询netns1下的veth1的对端,看peer_ifindex
    
    ip netns exec netns2 ip link    #查看peer_ifindex对应的值
    

    2.3 网桥

    • 网桥是一个二层网络设备,可以解析收发报文,读取目标MAC地址信息和自己记录的MAC表结合,来决策报文转发端口
    • Linux中多网卡可以通过网桥提供这些设备之间相互转发数据
    • 网桥处理转发和丢弃报文外还可以将报文发送到上层(网络层)

    2.3.1 Linux网桥的实现

    • Linux内核通过一个虚拟网桥设备(Net Device)来实现桥接,其可以绑定若干个以太网接口设备,从而将它们桥接起来
    • Net Device可以有一个IP

    3 Docker的网络实现

    docker的4类网络模式:

    1. host
    2. container
    3. none
    4. bridge,默认设置
    

    只介绍bridge模式

    • Docker Daemon第一次启动时将创建一个虚拟网桥默认名为docker0,同时给其分配一个子网
    • 针对Docker中的容器都会创建一个Veth设备对,一端关联网桥一端使用Linux的网络命名空间映射到容器内的eth0设备,然后从网桥的地址段内给eth0分配一个IP
    • 为了让容器跨主机通信就必须在主机的地址上分配端口,然后通过这个端口路由或代理到容器上

    4 Kubernetes的网络实现

    4.1 容器到容器的通信

    • 同一个Pod内的容器共享同一个网络命名空间,直接使用localhost即可

    4.2 Pod之间的通信

    • 每个Pod都有一个真实的全局IP,每个Node内的不同Pod之间可以直接采用对方Pod的Ip通信

    4.2.1 同一Node内Pod通信

    • 同一Node内的Pod通过Veth设备对连接到同一个docker0网桥上,Pod的IP也都是该网桥分配的
    • Pod内的默认路由都是docker0的地址,所有数据都通过docker0转发

    4.2.2 不同Node的Pod通信

    • Pod的地址是与docker0在同一个网段内,而docker0网段与宿主机网卡的IP网段完全不同,而通信只能走宿主机的网卡,因此通信必须通过宿主机IP来进行寻址和通信
    • Kubernetes会记录所有正在运行Pod的IP分配信息,并将其写入etcd作为Service的Endpoint
    • 支持不同Node之间Pod的通信条件:
      • 整个Kubernetes集群中Pod的IP不能冲突
      • 能将Pod的IP与Node的IP关联起来,通过这个关联实现相互访问
    • 解决:
      • Kubernetes部署时多docker0的IP地址进行规划保证每个Node上的docker0地址不冲突
      • 通信时先找到Node的IP将数据发送到这个网卡上,然后让宿主机将相应数据转到具体docker0上

    4.3 Pod到Service的通信

    • k8s在创建服务时为服务分配一个虚拟IP,客户端通过该IP访问服务,服务则负责将请求转发到后端Pod上
    • Service是通过kube-proxy服务进程实现,该进程在每个Node上均运行可以看作一个透明代理兼负载均衡器
    • 对每个TCP类型Service,kube-proxy都会在本地Node上建立一个SocketServer来负责接受请求,然后均匀发送到后端Pod默认采用Round Robin负载均衡算法
    • Service的Cluster IP与NodePort等概念是kube-proxy通过Iptables的NAT转换实现,kube-proxy进程动态创建与Service相关的Iptables规则
    • kube-proxy通过查询和监听API Server中Service与Endpoints的变化来实现其主要功能,包括为新创建的Service打开一个本地代理对象,接收请求针对针对发生变化的Service列表,kube-proxy会逐个处理,处理流程:
      • 如果该Service没设置ClusterIP,则不做处理,否则获取该Service的所有端口定义列表
      • 逐个读取端口定义列表,根据端口名、Service名和Namespace对其进行修改
      • 更新负载均衡组件中对应Service的转发Service的转发地址列表
      • 对于已删除的Service则进行清理

    5 开源的网络组件

    • Kubernetes的网络模型假定所有Pod都在一个可以直接连通的扁平网络空间,因此需要对网络进行设置
    • 目前常见的模型有Flunnel、Open vSwitch及直接路由的方式
  • 相关阅读:
    创建vue项目的时候报错,spawn yarn ENOENT
    理解比特币(4)——实现原理
    比特币(3)——比特币的其他优势
    比特币(2)——最大优势是价值存储
    如何在K8S中优雅的使用私有镜像库 (Docker版)
    [Go] godoc 打开本地文档, windows 同样适用
    [FAQ] Golang error strings should not be capitalized or end with punctuation
    [Go] gorm 错误处理 与 链式/Finisher方法
    [Go] golang 替换组件包 更新 go.mod, go.sum 的方式
    [FAQ] golang-migrate/migrate error: migration failed in line 0: (details: Error 1065: Query was empty)
  • 原文地址:https://www.cnblogs.com/suolu/p/6842771.html
Copyright © 2020-2023  润新知