2020-07-25 【K8S网络模型和存储模型】

今日鸡汤

我们能够带进坟墓里的,归根结底,也只有尽心尽责的满足感,以及拼尽全力的证据。

今天好好搞一搞K8S网络模型和存储模型。

Linux网络基础

1. Namespace

Namespace设置的意图是什么?

独立的协议栈被隔离到不同的命名空间中,处于不同命名空间中的网络栈是完全隔离的,彼此之间无法通信。

每个 Namespace需要包含什么?

进程、套接字、网络设备等。

如何在Linux网络协议栈的基础上支持这些私有的独立的协议栈?

实现的核心:让Linux网络的全局变量成为一个Namespace变量的成员,然后为协议栈的函数调用加入一个Namespacee参数。所有网络设备都只属于一个命名空间(物理设备关联到root,虚拟设备创建并关联到给定的ns,但可以在不同的网络ns之间转移设备)。

不同ns网络如何相互通信呢?

使用Veth设备对,利用成对的Veth设备对能直接将两个网络ns连接起来。

# 创建Veth设备对
ip link add veth0 type veth peer name veth1
# 查看Veth设备对信息
ip link show
# 将veth1转移到netns1中
ip link set veth1  netns netns1
# 分配ip地址
ip netns exec netns1 ip addr add 10.1.1.1/24 dev veth1
# 启动
ip netns exec netns1 ip link set dev veth1 up

怎么查看对端的veth设备?

使用ethtool工具。

# Step1:查询对端接口在设备列表中的序列号
ip netns exec netns1 ethtool -S veth1
# Step2:通过grep查看特定序列号代表的设备
ip netns exec  netns2 ip link |  grep 5

Docker网络实现

docker支持几种网络模式?

四种。host;container;none;bridge(默认)

docker bridge模式如何支持网络的?

  1. Docker Deamon启动时会创建一个虚拟网桥(docker0),并给网桥分配一个子网。
  2. 每个docker容器,都创建一个虚拟以太网设备(Veth设备对),一端连接docker0,一端连接使用namespace容器内的eth0设备,然后从网桥地址段给eth0接口分配一个IP地址。

docker网络模型的局限是什么?

Docker没有考虑多主机互联的网络方案。在同一台机器内的容器之间可以互相通信,不同主机间的容器不能互相通信,甚至有可能因为在不同主机上的docker0地址段相同而导致不同主机的容器在相同的地址范围内。
可以协调好端口分配或使用动态端口分配技术来解决这个问题。

K8S网络模型

K8S网络要解决的问题

  1. 容器与容器的通信
  2. Pod到Pod的通信
  3. Pod与Service的通信
  4. 集群外部与内部组件的通信

K8S设计的基础原则

每个Pod都有一个独立的IP地址;所有Pod都在一个可以直连、扁平的网络空间中;Pod要求可以直接通过对方ip进行访问。

IP-per-Pod模型:IP以Pod为单位进行分配。一个Pod内部的所有容器共享一个网络堆栈。

K8S对集群网络的要求

1) 所有容器都可以在不用NAT的方式下同别的容器通信。
2)所有节点都可以在不用NAT的方式下同所有容器通信,反之亦然。
3)容器的地址和别人看到的地址是同一个地址。

K8S内容器到容器的通信是怎么做的?

同一个Pod内的容器共享同一个netns,所以各类网络操作可以直接操作,就像在同一台机器上。

K8S内Pod是怎么通信的?

分为两种情况,在同一个node上Pod的通信和不同node上的pod进行通信。

  1. 对于同一个node上的Pod,他们都通过Veth连接到同一个docker0网桥上,IP地址都是从docker0的网段上动态获取的,他们和网桥本身在同一个网段上,因此可以直接通信。
  2. 对于不同node上的Pod,只能通过宿主机的网卡进行。于是需要满足两个条件:
  1. 在整个K8S集群中对Pod进行IP分配,不能有冲突——Flannel管理资源分配
    2)将Pod的IP与Node的IP关联起来

K8S中Pod的IP数据流的目标是哪里?

使用pause容器,将Pod里面的所有容器都连接到pause容器上,所有应用容器的端口映射都到pause容器上。

K8S中Service与Pod怎么通信?

使用kube-proxy服务。Service在多个pod之间抽象一些服务,而且可以在同一个service创建的pod中做负载均衡。kube-proxy 为每个新创建的服务都关联一个随机端口号,并创建负载均衡对象,直接和负载均衡到的Pod进行网络交互。

CNI网络模型

CNI网络模型是什么?

一种容器网络规范。包括容器和网络两种概念。
对容器网络的设置都通过插件来实现。CNI插件包括两种类型:CNI Plugin和IPAM。
CNI Plugin负责为容器配置网络资源,IPAM负责对容器IP地址进行分配管理。

CNI Plugin提供哪些操作?

ADD, DELETE, CHECK, VERSION

K8S存储模型

为什么K8S需要网络共享存储?

在docker容器中,为了实现数据的持久性存储,在宿主机和容器内做映射,可以保证在容器的生命周期结束,数据依旧可以实现持久性存储。

在k8s中,对于在同一节点的pod,可以使用本地数据卷来进行持久化存储。有三种方式:
1)emptyDir:Pod挂载在本地的磁盘或者内存,被称为emptyDir,称为临时空目录,随着Pod删除,也会被删除。适用于pod中容器之间的数据共享。

  1. gitrepo目录:只是emptydir上补添一个git命令来拉取文件而已。当pod创建时候,会拉取git(依赖于宿主机git命令驱动)仓库中数据克隆到本地,并且作为存储卷定义在pod之上。gitrepo基于emptyDir,此存储卷是emptyDir,git仓库中拉取的代码存放在emptyDir后被定义到pod。
  2. hostPath类型:映射node文件系统中的文件或者目录到pod里。可实现针对某一节点的数据持久化,如果节点宕机了,那数据就丢失了。应用于Pod中容器需要访问宿主机时。

对于分布在不同节点的pod,并不能实现不同节点之间持久性数据的共享,并且,在节点故障时,可能会导致数据的永久性丢失。为此,k8s就引入了外部存储卷的功能,通常是PVC和PV组合使用。
PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”。而PVC是用户对存储资源的一个“申请”,用户在创建应用时定义好需要的PVC,PVC会去找K8S当前可用的PV,进行绑定。使用完后进行清理和释放。

PV是怎样定义的?有什么关键参数?

  • Storage:存储能力
  • accessMode:访问模式,分为RWO(读写,被单个Node挂载)、ROX(只读,被多个Node挂载)、RWX(读写,被多个Node挂载)三种,不同存储提供商有不同的访问模式。
  • storageClass:存储类别,当定义StorageClass的时候可以用做动态绑定。
  • ReclaimPolicy:回收策略,有保留、回收空间和删除三种。

PV的生命周期?

四种。

  • Available:可用,未与PVC绑定
  • Bound:与PVC绑定
  • Released:绑定的PVC已删除,资源释放但还没有回收
  • Failed:自动资源回收失败

PVC和PV的生命周期是什么?

  1. 资源供应:静态和动态两种方式来创建PV。
  2. 资源绑定:系统根据PVC对存储资源的请求,在已存在的PV中选择一个绑定,如果没有PVC会一直pending,直到有符合要求的PV。
  3. 资源使用:Pod根据volume定义,将PVC挂载到容器内某个路径进行使用。
  4. 资源释放:用户删除PVC,与PVC绑定的PV会被标记为“已释放”。
  5. 资源回收:如何处理遗留数据。

K8S中PV的创建有哪些方式?

两种。静态和动态模式。

  • 静态模式:管理员手工创建PV,定义他的属性。
    缺点:当PVC申请的资源比PV的资源少时,整个PV空间都会被该PVC占据,造成资源浪费。
  • 动态模式:管理员定义StorageClass,描述后端存储,标记为某种类型,比如Fast, Standard, Slow。
    优势:通过声明StorageClass和PVC完成资源绑定。系统在为PVC找到合适的StorageClass后,将自动创建一个PV并完成与PVC的绑定,没有资源浪费。

Pod与PV与PVC的关系?

一个PV只能被一个PVC使用,一个PVC可被多个Pod使用。

你可能感兴趣的:(2020-07-25 【K8S网络模型和存储模型】)