1.3kubernetes核心架构_kubernetes生产化实践之路

较大规模集群时,建议管理节点单独使用。较小规模集群时,管理节点可以和工作节点混合使用。

管理节点:运行的控制平面组件
工作节点:运行的是用户业务
各种插件:监控、日志、DNS服务、ingress,常以用户态的形式存在

在这里插入图片描述

1.3.1 核心控制平面组件

由 API Server、etcd、Scheduler、controller manager 组成。

1.3.1.1 etcd

etcd 是高可用的键值对的分布式安全存储系统,用于持久化存储集群中所有的资源对象:集群中的node、service、pod的状态和元数据,以及配置数据等。

多个节点的etcd集群 成员间使用 Raft 共识算法复制请求并达成协议。
在这里插入图片描述

etcd 先写log,再根据log 将数据存储在磁盘中,这个步骤很好。

任何etcd 节点都可以处理读请求,不需要共识。

只有领导者 节点才能处理写请求,包括更改,新增,删除等。

当来自客户端API Server 的写请求被提交到etcd 成员处时,如果它不是领导者,那么它会将此请求转移给领导者,领导者会将请求复制到集群的其他成员中进行仲裁,当超过半数成员同意更改时,领导者才将更改后的新值提交到日志wal中,并通知集群成员进行写操作,将日志中的值写入磁盘中。

同一时间内只能有一个领导者,如果领导者不再响应,那么其余成员在预定的选举计时器超时后就会开始新的选举,将自己标记为候选者,并请求其他节点开始投票来开始新的选举,每个节点为请求其投票的第一个候选者投票。

如果候选节点获得集群中大多数节点的投票,那么它将成为新的领导者。

每个节点维护的选举计时器的超时时间不同,因此第一个候选节点通常会成为新的领导者。 但是,如果存在多个候选节点获得相同的选票,则这个选举任期就没领导节点而结束。

新的选举任期从新的随机选举计时器开始,因此建议在部署etcd 集群时采用奇数个成员为佳。

根据Raft 的工作机制,每个写请求需要集群中的每个成员做仲裁。
因为建议集群节点数量不要超过7个,推荐5个,个数越多仲裁时间越慢,写的吞吐量会越低。

如果集群中某个成员节点处理请求特别慢,就会让整个etcd 集群不稳定,性能受限制。
因此需要监控每个成员节点的性能,及时修复或者移除性能差的成员。

1.3.1.2 API Server

API Server 就是常说的kube-API Server ,承担API 的网关职责,是用户请求及其他系统组件与集群交互的唯一入口。

所有资源的创建、更新和删除都需要调用API Server 接口来完成。

对内:k8s内部各个模块之间的数据交互也是通过api server 来通信的,有etcd的封装接口api,其他模块通过这些api 可以监听到集群中的资源对象的新增,删除,和修改的变化情况。

对外:充当安全网关的作用,集群安全机制,客户端身份验证和授权,对资源进入准入控制。

用户可以通过kubectl 命令行或者 Restful 来调用HTTP 客户端(例如 curl、wget、浏览器)并与 api server通信。
api server 的HTTPS 安全端口默认为6443(可以通过 --secure-port 参数指定)
HTTP 非安全端口(可以通过 --insecure-port 参数指定,默认值8080)在新版本中已经被弃用。

api server 本身是无状态的,可以横向扩展,借助HAproxy 等来做负载均衡。
负载均衡器需要支持健康检查,防止某个api 节点宕机而不知道。

在这里插入图片描述

api server 会在Default Namespace 下创建一个类名为Kubernetes的service 对象。同时将它自己的 podIP 更新到对应的Endpoint 对象中。
通过coredns 插件,集群内部的pod 就可以通过服务名访问api server了。pod 到 api server 的流量就只会在集群内部转发,不会转发到外部的负载均衡器上。

k8s 某些版本中,api server 的endpoints 对象的个数也有长度限制,有 --apiserver-count 参数指定,默认是1。如果有多个api server 实例,需要将此值设置为实际值,否则流量只会转发到一个api server 实例上。 最新的版本应该是移除了这个参数,默认将启动的api server 都加入到endpoints中。

1.3.1.3 Controller Manager

控制器是k8s 集群的自动化管理控制中心,有30多个控制器
pod的:replication控制器、Deployment控制器
网络的:endpoints控制器、service控制器
存储:attachdetach控制器

大多数的控制器工作模式雷同,都是通过api server 监听相应的资源对象,根据对象的状态来决定接下来的动作,使其达到预期的效果。

很多场景都需要多个控制器协同工作,比如某个节点宕机了:

  • kubelet 将会停止汇报状态到node对象
  • nodelifecycle 控制器会发现节点状态没有按时更新,超过一段时间(可通过参数 --pod-eviction-timeout 来指定) 后,它将驱逐节点上的pod
  • 如果pod属于某个deployment 对象,那么deployment 对象所需的副本数量将减少,这时deployment 控制器将会补齐pod 副本数量,替换掉因为宕机而被删除的pod

控制器采用主备模式和leader Election 机制来实现故障转移(Fail Over)
也就是允许多个副本处于运行状态,但是只有一个副本作为领导者在工作,其他副本作为竞争者则不断尝试获取锁,试图通过竞争成为领导者。
一旦领导者无法继续工作,其他竞争者就能立刻上岗,而不需等待较长的创建时间。
在kubernetes中,锁就是一个资源对象,目前支持的资源是 Endpoints 和 Configmap,控制器的锁在 kube-system Namespace 下名为 kube-controller-manager的Endpoint 对象中。

在这里插入图片描述

Leader Election 有三个与时间相关的参数: leaseDuration、renewDeadline 和 retryPeriod。

  • leaseDuration:资源锁定后的租约时间,竞争者在该时间间隔内不能锁定资源,如果领导者在这段时间间隔后没有更新锁时间,则竞争者可以认为领导者已经挂掉,不能正常工作了,则重新选举领导者。
  • renewDeadline:领导者主动放弃锁,当它在 renewDeadline 内没有成功地更新锁,它将释放锁。 如果更新锁无法成功地执行,那么释放锁大概率也无法成功地执行,所以在kubernetes 中这种情况很少见。
  • retryPeriod:竞争者获取锁和领导者更新锁的时间间隔。

这种机制保证了集群组件的高可用性,如果领导者因为某种原因无法继续提供服务,则有其他竞争者副本,竞争成为新的领导者,继续执行业务逻辑。

1.3.1.4 Scheduler

集群中的调度器负责pod在集群节点中的调度分配。

调度器:通过调整单个和集群的资源需求、服务质量需求、硬件和软件的策略约束、亲和力和反亲和力规范、数据位置、工作负载间的干扰、期限等,来提升集群的可用性、性能和容量。

调度器和控制器类似,也是Leader Election 的主备模式。通过 kube-system Namespace 下名为 kube-scheduler 的Endpoint 对象进行领导者仲裁。

调度器监听 API Server 处pod 的变化,当新的pod被创建后,如果其pod的spec.nodename 为空,就会根据这个pod的 Resources、Affinity 和 Anti-Affinity 等约束条件和Node 的实时状态等为该pod 选择最优节点,然后更新节点名字到pod 的 spec.NodeName 字段。
下面由节点上的kubelet 接管了。

调度器调度pod的过程分为两个阶段:

  • 调度周期(scheduling cycle):为pod选择最优节点的过程
  • 绑定周期(binding cycle):通知api server 这个决定的过程

调度周期阶段是串行运行的,绑定周期阶段是可以并行运行的。

目前调度器采用插件式的框架,是的用户定制更加方便,向框架内的插件扩展点添加自定义的插件组即可。 调度器只需实现一组API 并编译到调度器中,通过配置文件来决定“使能” 还是“禁止” 。默认情况下的 default-scheduler 是没有扩展这些插件的。Filter 相当于我们平常所说的 Predicate 功能,Scoring 相当于Priority的功能。

在这里插入图片描述

Predicate 的功能可以理解为硬性条件(Hard Constraits)预选,将所有不能运行pod的节点排除出去。
如果在这个过程中任何一个策略将节点标记成“不可用”,那么接下来的策略也都不会考虑这个节点。
Predicate 完成后,我们最终会得到一个候选节点列表。如果候选节点列表为空,那么pod暂时无法安排。 调度器会将其再次放回队列中。

下面是调度器的预选策略:

  • PodFitsHostPorts:判断Pod 所要求的端口是否在节点中被占用
  • PodFitsHost:判断节点是否是Pod的spec.nodeName 指定的节点
  • PodFitsResources:判断节点是否能够满足pod中申请的CPU 内存要求
  • PodMatchNodeSelector:判断节点是否满足Pod的spec.nodeSelector 限制
  • NovolumeZoneConflict:在给定存储卷的Failure Zone 的限制下,评估Pod 的spec.volume 申请的存储卷是否在这个节点可用
  • NoDiskConflict:判断Pod的Volumes 和该节点上已挂载的磁盘是否有冲突
  • MaxCSIVolumeCount:判断节点上挂载的CSI Volumes 是否超出最大值
  • CheckNodeMemoryPressure:判断节点是否已经在汇报有内存压力
  • CheckNodePIDPressure:判断节点是否已经在汇报PID即将耗尽
  • CheckNodeDiskPressure:判断节点是否已经在汇报有存储压力(系统磁盘满了或者接近满了)
  • CheckNodeCondition:根据节点的status.conditions 判断节点状态,如果节点网络不可用、kubelet 的状态不是ready的,等等,那么这个节点不适合运行pod
  • podToleratesNodeTaints:判断Pod 上的Toleration是否能满足节点上的Taints
  • CheckVolumeBinding:检查节点是否能满足pod 所有的Volume 请求,包括bound 和unbound 的pvcs

Priority 的功能,可以理解为软性条件(soft Contraints) 优选,根据各个策略对可行节点队列中的每个节点打分,最终总得分最高的节点就是最优节点。如果多个节点都是相同的分数,它将会在他们之中任选一个。

  • SelectorSpreadPriority:尽量将相同的Service、StatefulSet 或者 ReplicaSet的Pod 分布在不同节点
  • InterPodAffinityPriority:遍历weighted的PodAffinityTerm 的元素,如果节点满足相应的PodAffinityTerm 条件,则总和加上该条件的“权重”,再计算总和,总和越高的节点,分数越高。
  • LeastRequestedPriority:节点上的已有pod所申请的资源总数越少,节点得分越高。这个策略能使负载在各个节点上更均衡。
  • MostRequestedPriority:节点上的已有pod申请的资源总数越多,节点得分越高,这个策略能使pod 调度到小规模的节点上。
  • RequestedToCapacityRatioPriority: 资源利用率(Requested / capacity ) 越低,节点得分越高
  • NodePreferAvoidPodsPriority:如果节点的Annotationscheduler.alpha.kubernetes.io/preferAvoidPods 没有显示指定规避此节点,则节点得分高
  • NodeAffinityPriority:满足pod 的 PreferredDuringSchedulingIgnoredDuringExecution 条件的节点得分高
  • TaintTolerationPriority:pod不满足节点上的Taints的数量越少,节点得分越高
  • ImageLocalityPriority:如果已经有了Pod所需的容器镜像的节点,则得分相对高
  • ServiceSpreadingPriority:保障Service后端的Pod运行在不同节点上,对于Service服务来说,更能容忍单节点故障。
  • CalculateAntiAffinityPriorityMap:尽量使属于同一个service的Pod 在某个节点上的数量最少。
  • EqualPriorityMap:所有节点都具有相同的权重

由于调度器在系统中“承上启下”,所以调度器的性能也就容易成为系统的瓶颈。

在k8s 1.12之前,调度器做Predicate 时都是检查所有的节点,后面的版本加了一个特性,允许调度器在发现一定数量的候选节点后,暂时停止寻找更多的后端节点,这会提高调度器在大集群中的性能。

这个参数由 percentOfNodesToScore 的配置选项控制,范围在1到100之间,0 表示未设置此选项,如果候选节点总体数量小于50个,这个参数也是无效的。

1.14版本中,如果没有指定参数,调度器会根据集群的大小找到合适的节点百分比。它使用一个线性公司,对于一个100节点的集群,该值为50%,对于一个具有5000节点的集群,该值为10%,这个值的下线是5%,除非用户提供的参数小于5,否则最低5%的节点进行评分。

1.3.2 工作节点控制平面组件

工作节点是具体运行容器的节点,可以是虚拟机也可以是物理机。

一个新的Node 加入集群是非常容易的,在节点上安装 kubelet、kube-proxy、容器运行时和网络插件服务,然后将kubelet 和 kube-proxy 的启动参数中的 API Server URL 指向目标集群的API Server 即可。API Server 在接受kubelet 的注册后,会自动将此节点纳入当前集群的调度范围,这样pod 就能调度该节点了。

1.3.2.1 kubelet

kubelet 是运行在每个节点上负责启动容器的重要的守护进程。

启动时,kubelet 进程加载配置参数,向API Server 处创建一个Node 对象来注册自身的节点信息,例如操作系统、Kernel版本、IP地址、总容量(capacity)和可供分配的容器(Allocatable Capacity)等。

然后kubelet 须定时(默认值每10s通过NodeStatusUpdateFrequency设置参数)向API Server 汇报自身情况,例如磁盘空间是否用满,CPU和Memory 是否有压力,自身服务是否Ready等,这些信息将被调度器使用,在调度器pod时给节点打分。
如果kubelet停止汇报这些信息,那么NodeLifecycle 控制器将人为kubelet 已经不能正常工作,会将Node 状态设置为Unknown,并在一段时间后开始驱逐其上的Pod对象。

节点上的pod来源有两个:

  • 普通pod:也就是通过API Server 创建Pod,是被Scheduler调度到该节点上的
  • 静态pod(static pod):不经过API Server,kubelet 通过观测本地目录或HTTP URL 下的定义文件所创建的Pod,静态Pod始终绑定到 kubelet 所在的节点上。

静态Pod信息:
kubelet 会自动尝试在API Server 上为每个静态Pod创建一个镜像Pod(Mirror Pod),这样它在API Server上可见,但是不能从API Server处控制。
staticPodPath 来指定本地目录
staticPodURL 来指定HTTP URL
在这个URL和 目录下的文件的所有更新都可以被kubelet检测到,周期默认是20s。可以通过配置参数 FileCheckFrequency 和 HTTPCheckFrequency来指定。

当Pod被调度到kubelet 所在的节点上时,kubelet 首先将pod中申请的Volume 挂载到当前节点上。
当volume 挂载完毕后,kubelet 才会调用容器运行时为pod创建容器沙箱(PodSandbox)和容器。
kubelet 也会周期性的查询容器的状态和汇报给API Server,通过cAdvisor 监控容器资源的使用情况。

容器沙箱,即 pause 容器的抽象概念,有时也称为 infra 容器。
与用户容器捆绑运行在同一个pod中,共享 CGroup、Namespace等资源,与其他Pod资源隔离。
在pause 容器中运行一个非常简单的pause 进程,不执行任何功能,一启动就永远把自己阻塞住(pause系统调用)。
容器沙箱最大作用:维护Pod网络协议栈。

容器启动过程:
kubelet 先调用容器运行时为该Pod 创建容器沙箱即pause容器,容器运行时为容器沙箱设置网络环境。
当容器沙箱启动成功后,kubelet 才会调用容器运行时在该容器沙箱的网络命名空间中(Net Namespace)中创建和启动容器。
用户容器会启动失败退出,但因为有容器沙箱存在,容器的网络命名空间不会被摧毁,重建用户容器的时候,无需为它设置网络了。(也就是pod的名称不会变,因为pause还在)

········

kubelet 不是直接操作容器的,是通过容器运行时接口(Container Runtime Inferface,CRI),调用容器运行时对容器和镜像进行操作的,例如创建、启动、停止和删除镜像。

容器运行时的选用有多条,使用内置的dockershim和远端的容器运行时等。 目前默认情况下,kubelet通过内置的dockershim 调用docker来完成容器操作的。 我们也可以指定remote 模式(通过参数 --container-runtime 来指定),使用外部的遵循CRI 的容器运行时。

虽然kubelet 不直接参与容器的创建与运行,但是它是管理和监管节点上的pod和pod中的容器的生老病死的核心。

在这里插入图片描述

···········

如下图,kubelet的核心函数是 syncLoop,此函数是由事件驱动的,kubelet 会从API Server 的静态POD的本地目录和HTTP URL处监听到Pod资源对象的变化,产生新增、更改、删除事件。 kubelet 还会启动一个PLEG(Pod Lifecycle Event Generator)线程,每秒从容器运行时中查询容器的状态,更新Pod的缓存,并根据容器的状态产生同步的事件。
在这里插入图片描述

kubelet 的syncLoop 函数将Pod对象及容器状态的变化产生的4类UpdatePodOptions(SyncPodUpdate、SyncPodCreate、SyncPodKill、SyncPodSync)分发给Pod对应的PodWorker进行处理,每个Pod都有一个PodWorker。

PodWorker 会根据UpdatePodOptions的类型调用相关容器运行时接口进行相关操作。

对于SyncPodUpdate 和 SyncPodSync 类型的UpdatePodOptions,PodWorker 会事先根据当前Pod的 Spec (目标状态)和 status(当前状态) 调用 computePodActions 函数计算是否需要停止容器,删除沙箱容器等操作。

kubelet 就是通过这样的闭环反馈控制Pod的status及其Spec最终达到一致的。

···········

kebelet 还有别的功能:

  • 对容器进行健康检查:Liveness:表示容器是否处于存活状态,如果kubelet 检查容器处于死亡状态,则kubelet 会停止此容器,并创建新的容器。
    Readiness 用来判断容器中的用户进程是否处于可服务状态,如果检测结果是不可服务状态,则kubelet 不会重启容器,但会把Pod中的容器状态更新为 ContainersReady=false,如果pod 的容器处于不可服务状态,Endpoint 控制器就会将该Pod的ip地址从Endpoint 中移除,该Pod将不能再接收任何用户请求,这个对Service 的高可用而言非常重要。

  • 保护节点不被容器抢占所有资源。如果镜像占用磁盘空间的比例超过高水位(默认值是90%,可以通过参数ImageGCHighThresholdPercent 进行配置),kubelet 就会清理不用的镜像。 当节点CPU 、Memory 或者磁盘少于某特定值或比例(由参数EvictionHard 配置)时,kubelet 就会驱逐低优先级的pod(例如BestEffort 的Pod) ,通过这些操作,保障节点上已有的pod能够在保证的QoS(Quality of Service)下继续正常运行。

  • 处理Master 节点下发到本节点的任何,比如exec、logs、attach等请求。 API Server 是无法完成这类工作的,此时 API Server 需要向 kubelet 发起请求,让kubelet 完成此类请求的处理。

1.3.2.2 kube-proxy

在这里插入图片描述

kube-proxy 也是在每个节点上都运行的,它是实现kubernetes Service 机制的重要组件。

kube-proxy 也是一个控制器,它从API Server 监听Service 和 Endpoint 对象的变化,并根据Endpoint 对象的信息设置Service 到后端Pod 的路由,维护网络规则,执行TCP、UDP 和 SCTP 流转发。

如上图:
标签app=example的pod 都是此Service 的后端pod,他们的pod ip 将会被Endpoint控制器实时更新到Endpoint 对象中,此Service 被分配的 clusterip 为 192.168.232.109,nodeport 是 30004,pod 的8080 端口映射到Service 的 80 端口。
因此在集群内部 通过 192.168.232.109:80 就能访问此Service 的后端pod 8080 端口提供的服务。
集群外部可以通过 nodeIP:30004 来访问此Service。

········

kube-proxy 有两种模式都可以实现流量转发,分别是 iptables模式和IPVS(IP Virtual Server)模式(可以通过参数–proxy-mode来指定)。默认是iptables 模式,该模式是通过每个节点上的iptables 规则来实现的。我们可以通过iptables命令查看相关的 iptables rules:

在这里插入图片描述

从上图中的规则来看:
集群内,使用ClusterIP:192.168.232.109(规则2)或 nodePort 30004(规则1)访问Service时,会被跳转到 Chain KUBE-SVC-BBVI5ZxxxxxKVW42。

对于Chain KUBE-SVC-BBVI5ZxxxxxKVW42 ,它有三条可以跳转的路径(规则345)。

当我们查询到规则3时,它将有33.33%的概率命中,并跳转到 KUBE-SEP-RXBFMCxxxxxMAHP。

如果规则3未命中,则接下来我们考虑规则4,它将有 50%的概率进入 Chain KUBE-SEP-CCTNxxxLBDD。

如果此条仍没有命中,就会进入 Chain KUBE-SEP-HJGBxxxxP5Q3I。

因此分别进入到这三个Chain 的概率是一样的,kube-proxy 也是利用iptables的这一特性实现流量的负载均衡。

随着Service 数量的增大,iptables 模式由于线性查找匹配,全量更新特点,其性能会显著下降。从kubernetes的1.8版本开始,kube-proxy 引入了 IPVS 模式。

IPVS 与 iptables 同样基于netfilter ,但是采用的哈希表而且运行在内核态,当Service 数量达到一定规模时,哈希表的查询速度优势就会显现出来。从而提供Service 的性能,我们可以通过 ipvsadm 命令查看 IPVS模式下的转发规则:

在这里插入图片描述

1.3.2.3 容器运行时

容器运行时是真正删除和管理容器的组件。
分为:高层运行时,底层运行时

高层运行时:Docker、Containerd、Cri-o
底层运行时:runc、kata、Visor。 使用runc的多。

kubelet 通过内嵌的DocketShim 操作Docker API 来操作容器,进而达到一个面向终态的效果。
因为后续还支持的运行时,k8s的代码越来越复杂,因此k8s 推出了 CRI(Container Runtime Interface )接口。
把容器运行时的操作,抽象出一组接口。

在这里插入图片描述

kubelet 能够通过CRI 接口对容器、沙盒、及容器镜像进行操作。

Containerd 是Docker 的核心组件,Containerd也可以直接与kubelet 通过CRI 对接,独立在kubernetes中使用。

相对Docker 而言,Containerd 减少了Docker 所需的处理模块 Dockerd、Docker-shim。 因此在容器的创建、启动、停止、删除以及镜像的拉取上都有性能上的优势。

不过Docker 支持对日志的大小和文件限制,在 overlayfs2 做存储驱动的情况下,可以通过xfs_quota 来对容器的可写层进行大小限制等。

1.3.2.4 网络插件

k8s 网络设计的原则:

  • 所有的POD能够不通过NAT就能相互访问
  • 所有的节点能够不通过NAT就能相互访问
  • 容器的IP地址和外部组件看到的容器IP地址是一样的

IP 地址以POD为单位进行分配,每个POD 都有独立的IP地址。
一个POD 内的容器共享一个网络栈,即宿主机上的一个网络命名空间,包括他们的IP地址、网络设备、配置等都是共享的。
POD 的容器可以通过 localhost 相互访问。

k8s中提供了一个CNI 容器网络接口,专门用于设置和删除容器的网络连通性。
容器运行时通过CNI 调用网络插件来完成容器的网络设置。

==============

容器运行时在启动时会从CNI的配置目录中读取json格式的配置文件,文件后缀为 conf、conflist、json。
如果包含多个文件,就按照名字排序,选用第一个配置文件作为默认的网络配置,并加载获取其中指定的CNI插件名称和配置参数。

一个配置文件中可以指定多个插件,容器运行时会保存这些插件到“待执行插件” 列表中。
当需要为容器添加或者删除网络时,容器运行时会在CNI 的可执行目录中找到这些插件的可执行文件并逐一执行。

CNI 插件通过参数传入网络设置操作命令(ADD或者DEL)、容器的ID、被分配的网络命名空间等信息。

在这里插入图片描述

kubelet 内置的docker 作为容器运行时,是由kubelet 来查找CNI 插件的,通过运行插件来为容器设置网络,这两个参数应该配置在kubelet上:

  • cni-bin-dir:网络插件的可执行文件的目录,默认是/opt/cni/bin
  • cni-conf-dir:网络插件配置文件所在的目录,默认是/etc/cni/net.d

CNI 设计的时候要考虑一下几方面内容:

  • 容器运行时必须在调用任何插件之前为容器创建一个新的网络命名空间
  • 容器运行时必须决定这个容器属于哪些网络,针对每个网络,哪些插件必须要执行
  • 容器运行时必须加载配置文件,并确定设置网络时哪些插件必须执行
  • 网络配置采用json格式,可以方便存储在文件中
  • 容器运行时必须按顺序执行配置文件中的插件
  • 在完成容器生命周期后,容器运行时必须按照与添加容器相反的顺序执行插件,以便容器与网络断开连接。
  • 容器运行时被同一容器调用时不能并行操作,被不同容器调用时,允许并行操作。
  • 容器运行时针对一个容器必须按顺序执行ADD和DEL操作,ADD后面总是跟着相应的DEL。DEL可能额外跟着DEL,插件应该允许处理多个DEL。
  • 容器必须由ContainerID来唯一标识需要存储状态的插件,需要使用网络名称,容器ID和由网络接口组成的主KEY(用于索引)
  • 容器运行时针对同一个网络、同一个容器、同一个网络接口,不能连续调用两次ADD命令

除配置文件指定的CNI 插件外,kubernetes 还需要标准的CNI 插件lo,最低版本为0.2.0 版本。

网络插件除支持设置和清理Pod网络接口外,还需要支持iptables。
如果kube-proxy 工作在iptables 模式下,那么网络插件需求确保容器流量能使用 iptables转发。
例如,如果网络插件将容器连接到Linux网桥,则必须将 net/bridge/bridge-nf-call-iptables 参数 sysctl 设置为1,网桥上的数据包将遍历iptables规则。

如果插件不使用Linux 桥接器(而是类似Open vSwitch 或其他某种机制的插件)则应确保容器流量被设置了正确的路由。

ContainerNetwork 组维护了一些CNI 插件

  • 网络接口创建的 bridge、ipvlan、loopback、macvlan、ptp、host-device 等
  • IP 地址分配的:dhcp、host-local、static
  • 其他的Flannel、tunning、portmap、firewall

社区的还有第三方网络策略方面的插件,calico、Cilium、weave。

Flannel 是由CoreOS 开发的项目,是CNI 插件早期的入门产品,简单易用。
Flannel 使用k8s 集群中的etcd 存储数据信息,只需要在每个节点上运行 flanneld 来守护进程。

每个节点都被分配一个子网,为该节点上的pod 分配IP 地址。
同一个主机内的pod可以使用网桥进行通信。
不同主机上的pod 将通过flanneld 将其流量封装在UDP 数据包中,以路由到合适的目的地。
封装方式默认和推荐的方法是使用Vxlan,因为它具有良好的性能,并且比其他选项少一些人为干预。
虽然使用vxlan进行封装的解决方案效果很好,但使得流量跟踪变的困难。

在这里插入图片描述

Calico 是kubernetes 生态中另一个流行的网络插件。以性能、灵活、网络策略闻名。
不仅涉及在主机和pod之间提供网络连接,而且还涉及网络安全性和策略管理。
对于同网段通信,基于第三层,Calico 使用BGP 协议在主机之间路由数据包,使用BGP 路由协议也意味着数据包在主机之间移动时不需要包装在额外的封装层中。 这样当网络出问题的时候,允许使用常规的工具对网络就行故障诊断,定位问题更容易些。
对于跨网段通信,基于IPinIP 使用虚拟网卡设备tunlo,用一个IP数据包封装另一个IP数据包。外层数据包头的源地址为隧道入口的IP地址,目标地址为隧道出口设备的IP地址。

网络策略是Calico 最受欢迎的功能之一,它通过ACLs 协议和kube-proxy 来创建 iptables 规则,从而实现隔离容器网络的目的。
此外 Calico 还可以与服务网格Istio 集成,在服务网格层和网络基础结构层上解释和实施集群中工作负载的策略,这样就可以配置功能强大的规则。以描述pod 应该如何发送和接收流量、提高安全性、以及加强对网络环境的控制。
Calico 属于完全分布式的横向扩展结构,允许管理员快速和平稳的扩展部署规模。
对于性能和功能,网络策略这种要求高的可以使用Calico。

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DevOps 五大理念及其落地实践 研发运维一体(DevOps)成熟度模型 中国DevOps现状调查报告及解读 构建企业DevOps的度量体系 DevOps实践指南精要 分布式敏捷和DevOps实践案例 AWS DevOps 助力爱乐奇大规模业务扩展 AWS 云上的 DevOps 实践简介 多云环境下的 DevOps 实践 DevOps中如何系统开展微服务性能测试 “神兵”天降 - 揭秘平安 DevOps 的核心实践 大型Scrum实践银行产品敏捷转型与DevOps实践经验分享 如何基于 Jenkins 支撑腾讯上千产品的CICD SecDevOps工具链 券商DevOps转型—平安证券容器实践之路 招行如何基于 K8S 容器技术打造 DevOps 流水线 民生银行的DevOps实践之旅 以自动先行的 DevOps 落地实践经验 东方明珠集团基于 AWS 的 DevOps 实战分享 中小银行的DevOps 实践之路 让DevOps生产线加速的敏捷之道 云原生时代的 DevOps 新实践 新场景高效能快交付腾讯敏捷研发平台 DevOps 解决方案 中小金融企业如何开心玩DevOps DevOps 变革的剖析与实践 猎豹移动基于 AWS 构建 DevOps 实践分享 DevOps在联通IT系统的落地实施 DevOpsMadeByGoogle 流水线3.0打造DevOps落地工具链 混合云下的DevOps在vivo互联网的探索落地 大型企业实施 DevOps 的三个阶段 DevOps最佳实践之海量资源技术运营 诺基亚 DevOps 演进-大数据推动流程优与高效执行 苏宁 AIOps 实践之路 金融云业务网络 智能采集与一体分析实战 如何构建新一代智能运维平台 CMDB - 企业一体运维平台的基石 用友方法+之-YSDP 研发交付平台实践之路 顺丰云计算和运维自动团队从0到1的DevOps之旅 诺基亚的转身:数字时代的 DevOps 转型之路 大型主机核心银行系统的 DevOps 践行之路 DevOps标准认证评估权威指南及案例解读. 浙江移动的DevOps实践 携程持续交付与构建系统实践 每天万次触发的持续交付工具链实践 Android 超大型代码的快速集成之路 基于猪齿鱼构建企业研发体系 大型制造业实践DevOps团队之路

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值