ks8 核心组件、Pod分类、网络模型

Kubernetes核心组件

Kubernetes定义了一组构建块,它们可以共同提供部署、维护和扩展应用程序的机制。组成Kubernetes的组件设计为松耦合和可扩展的,这样可以满足多种不同的工作负载。可扩展性在很大程度上由Kubernetes API提供——它被作为扩展的内部组件以及Kubernetes上运行的容器等使用。

Kubernetes 主要由以下几个核心组件组成:
  • etcd 保存了整个集群的状态;
  • kube-apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • kubelet 负责维持容器的生命周期,同时也负责 Volume(CVI) 和网络 (CNI) 的管理;
  • Container runtime 负责镜像管理以及 Pod 和容器的真正运行 (CRI) ,默认的容器运行时为 Docker;
  • kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的 Add-ons:

  • kube-dns 负责为整个集群提供 DNS 服务
  • Ingress Controller 为服务提供外网入口
  • Heapster 提供资源监控
  • Dashboard 提供 GUI
  • Federation 提供跨可用区的集群
  • Fluentd-elasticsearch 提供集群日志采集、存储与查询
组件通信

Kubernetes 多组件之间的通信原理为:

  • API Server 负责 etcd 存储的所有操作,且只有 API Server 才直接操作 etcd 集群。
  • API Server 对内(集群中的其他组件) 和对外(用户) 提供统一的 REST API,其他组件均通过 API Server 进行通信,Controller Manager、Scheduler、Kube-proxy 和 Kubelet 等均通过 API - Serverwatch API 监测资源变化情况,并对资源作相应的操作。
    所有需要更新资源状态的操作均通过 API Server 的 REST API 进行
  • API Server 也会直接调用 Kubelet API(如 logs, exec, attach 等) ,默认不校验
  • Kubelet 证书,但可以通过 --kubelet-certificate-authority 开启(而 GKE通过 SSH 隧道保护它们之间的通信)
    比如典型的创建 Pod 的流程为:
    在这里插入图片描述
    1、用户通过 REST API 创建一个 Pod
    2、API Server 将其写入 etcd
    3、Scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定
    4、Kubelet 检测到有新的 Pod 调度过来,通过 Container Runtime 运行该 Pod
    5、Kubelet 通过 Container Runtime 取到 Pod 状态,并更新到 API Server 中

Pod的分类

Pod 是 kubernetes 系统的基础单元,是由用户创建或部署的最小组件,也是 kubernetes 系统上运行容器化应用的资源对象。Kubernetes 集群中其他资源对象都是为 pod 这个资源对象做支撑来实现 kubernetes 管理应用服务的目的。

  • 自主式pod

自我管理的pod,创建以后仍然需要提交给apiserver,由apiserver接收以后借助于调度器将其调度至指定的node节点,由node启动此pod
如果此pod出现故障,需要重启容器则由kubelet来完成
如果node节点故障了,那么此pod将会消失。其无法实现全局调度。所以不推荐使用此种pod

  • 控制器管理pod

常见的pod控制器

ReplicationController(副本控制器)
当启动一个pod时,这个pod如果不够用可以再启一个副本,而后由控制器来管理同一类pod的各种副本与对象。一旦副本少了就会自动增加。采取多退少补的规则,精确符合我们所定义的期望

支持滚动更新

ReplicaSet(复制集)
由一个名叫Deployment的声明式更新的控制器来管理

Deployment(部署)
Deployment只能管理无状态的应用

StateFulSet(状态集)
有状态副本集,可以管理有状态的应用

DaemonSet(守护程序)

如果需要在每个node上运行一个副本的时候可以用DaemonSet

job(任务)

Cronjob(定时任务)

以上每种控制器都是用来实现一钟独特的应用管理的

Kubernetes 集群组件主要包括主节点组件API Server、Controller Manager、Scheduler 以及子节点组件 kubelet、container Runtime(如docker)、kube-proxy 等。从与集群各组件交互角度讲述 pod 的创建、运行、销毁等生命周期,Pod 生命周期中的几种不同状态包括pending(待办)、running(正在运行)、succeeded(完成)、failed(失败)、Unknown(未知)。

与API Server交互

API Server 提供了集群与外部交互的接口,通过 kubectl 命令或者其他 API 客户端提交 pod spec 给 API Server 作为pod创建的起始。

Pod 与 API Server 交互的主要流程如下:

在这里插入图片描述

  • API Server 在接收到创建pod的请求之后,会根据用户提交的参数值来创建一个运行时的pod对象。
  • 根据 API Server 请求的上下文的元数据来验证两者的 namespace 是否匹配,如果不匹配则创建失败。
  • Namespace 匹配成功之后,会向 pod 对象注入一些系统数据,如果 pod 未提供 pod 的名字,则 API Server 会将 pod 的 uid 作为 pod 的名字。
  • API Server 接下来会检查 pod 对象的必需字段是否为空,如果为空,创建失败。
  • 上述准备工作完成之后会将在 etcd 中持久化这个对象,将异步调用返回结果封装成 restful.response,完成结果反馈。
  • 至此,API Server 创建过程完成,剩下的由 scheduler 和 kubelet 来完成,此时 pod 处于 pending(待办) 状态。
与scheduler交互

当提交创建 pod 的请求与 API Server 的交互完成之后,接下来由 scheduler 进行工作,该组件主要是完成 pod 的调度来决定 pod 具体运行在集群的哪个节点上。注意,此处声明一点,API Server 完成任务之后,将信息写入到 etcd 中,此时 scheduler 通过 watch 机制监听到写入到 etcd 的信息然后再进行工作。

Scheduler 读取到写入到 etcd 中的 pod 信息,然后基于一系列规则从集群中挑选一个合适的节点来运行它,调度时主要通过三步来确定 pod 运行节点:

  • 节点预选:基于一系列预选规则(如 PodFitsResource 和 MatchNode-Selector 等)对每个节点进行检查,将不符合的节点过滤掉从而完成节点预选。
  • 节点优选:对预选出的节点进行优先级排序,以便选出最适合运行 pod 对象的节点。
  • 从优先级结果中挑选出优先级最高的节点来运行 pod 对象,当此类节点多个时则随机选择一个。

注意:如果有特殊 pod 资源需要运行在特殊节点上,此时可以通过组合节点标签以及 pod 标签和标签选择器等来实现高级调度,如 MatchInterPodAffinity、MatchNodeSelector 和 PodToleratesNodeTaints 等预选策略,他们为用户提供自定义 Pod 亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制。

预选策略

预选策略就是节点过滤器,例如 MathNodeSelector 实现的规则,以及 PodFitsResources 实现的规则等。执行预选操作时,如果不存在适合的节点,此时 pod 会一直处于 pending(待办) 状态,直到至少有一个可用节点。

启动pod流程分析

kubelet 通过 API Server 监听 etcd 目录,同步 pod 列表。如果发现有新的 pod 绑定到本节点,则按照 pod 清单要求创建 pod,如果是发现 pod 被更新,则做出相应更改。

读取到 pod 的信息之后,如果是创建和修改 pod 的任务,则做如下处理:

1.为该 pod 创建一个数据目录
2.从 API Server 读取该 pod 清单
3.为该 pod 挂载外部卷
4.下载 pod 所需的 Secret
5.检查已经运行在节点中 pod,如果该 pod 没有容器或者 Pause 容器没有启动,则先停止pod里所有的容器进程。
6.使用 pause 镜像为每个pod创建一个容器,该容器用于接管 Pod 中所有其他容器的网络。
7.为 pod 中的每个容器做如下处理:1.为容器计算一个 hash 值,然后用容器的名字去查询对于 docker 容器的 hash 值。若查找到容器,且两者的 hash 值不同,则停止 docker 中容器中进程,并停止与之关联的 pause 容器,若相同,则不做处理。若容器被终止了,且容器没有指定的重启策略,则不做任何处理调用 docker client 下载容器镜像,并启动容器。

此外,除了上述三个组件在创建 pod 过程中的交互,还有 controller-manager 来保证 pod 处于用户期望状态(即保证 pod 永远处于存活状态)等功能以及 proxy 用于集群内 pod 之间通信等。

Kubernetes网络模型

在Kubernetes网络中存在两种IP(Pod IP和Service Cluster IP),Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,Service Cluster IP它是一个虚拟IP,是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。下面讲讲Kubernetes Pod网络设计模型:

1、基本原则:

每个Pod都拥有一个独立的IP地址(IPper Pod),而且假定所有的pod都在一个可以直接连通的、扁平的网络空间中。

2、设计原因:

用户不需要额外考虑如何建立Pod之间的连接,也不需要考虑将容器端口映射到主机端口等问题。

3、网络要求:

所有的容器都可以在不用NAT的方式下同别的容器通讯;所有节点都可在不用NAT的方式下同所有容器通讯;容器的地址和别人看到的地址是同一个地址。

Docker网络基础

因为k8s现在是基于docker部署的,所有其内部的部分网络还是使用的是docker 的网络模型。

Linux网络名词解释:
1、网络的命名空间:

Linux在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命令空间中,彼此间无法通信;docker利用这一特性,实现不容器间的网络隔离。

2、Veth设备对:

Veth设备对的引入是为了实现在不同网络命名空间的通信。

3、Iptables/Netfilter:

Netfilter负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核 模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表;通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。

4、网桥:

网桥是一个二层网络设备,通过网桥可以将linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。

5、路由:

Linux系统包含一个完整的路由功能,当IP层在处理数据发送或转发的时候,会使用路由表来决定发往哪里。

Docker 技术栈结构

下图展示了Docker网络在整个Docker生态技术栈中的位置:
在这里插入图片描述

  • Docker网络实现
    单机网络模式:Bridge 、Host、Container、None。
    详细请阅读dockers网络配置

多机网络模式:一类是 Docker 在 1.9 版本中引入Libnetwork项目,对跨节点网络的原生支持;另一类是通过插件(plugin)方式引入的第三方实现方案,比如 Flannel,Calico 等等。

Kubernetes网络基础

容器间通信:

同一个Pod的容器共享同一个网络命名空间,它们之间的访问可以用localhost地址 + 容器端口就可以访问。(同一个pod内的多个容器间的通信,通过lo即可实现;)
在这里插入图片描述

同一Node中Pod间通信:

同一Node中Pod的默认路由都是docker0的地址,由于它们关联在同一个docker0网桥上,地址网段相同,所有它们之间应当是能直接通信的。
(同一节点的pod之间通过cni网桥转发数据包)
在这里插入图片描述

不同Node中Pod间通信:

不同Node中Pod间通信要满足2个条件: Pod的IP不能冲突; 将Pod的IP和所在的Node的IP关联起来,通过这个关联让Pod可以互相访问(不同节点的pod之间的通信需要网络插件支持)。
在这里插入图片描述

Service介绍:

Service是一组Pod的服务抽象,相当于一组Pod的LB,负责将请求分发给对应的

Pod;Service会为这个LB提供一个IP,一般称为ClusterIP。
在这里插入图片描述
在这里插入图片描述
pod和service通信: 通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换。

Kube-proxy

Kube-proxy是一个简单的网络代理和负载均衡器,它的作用主要是负责Service的实现,具体来说,就是实现了内部从Pod到Service和外部的从NodePort向Service的访问。

实现方式:

  • userspace是在用户空间,通过kuber-proxy实现LB的代理服务,这个是kube-proxy的最初的版本,较为稳定,但是效率也自然不太高。
  • iptables是纯采用iptables来实现LB,是目前kube-proxy默认的方式。

下面是iptables模式下Kube-proxy的实现方式:
在这里插入图片描述

  • 在这种模式下,kube-proxy监视Kubernetes主服务器添加和删除服务和端点对象。对于每个服务,它安装iptables规则,捕获到服务的clusterIP(虚拟)和端口的流量,并将流量重定向到服务的后端集合之一。对于每个Endpoints对象,它安装选择后端Pod的iptables规则。

  • 默认情况下,后端的选择是随机的。可以通过将service.spec.sessionAffinity设置为“ClientIP”(默认为“无”)来选择基于客户端IP的会话关联。

  • 与用户空间代理一样,最终结果是绑定到服务的IP:端口的任何流量被代理到适当的后端,而客户端不知道关于Kubernetes或服务或Pod的任何信息。这应该比用户空间代理更快,更可靠。然而,与用户空间代理不同,如果最初选择的Pod不响应,则iptables代理不能自动重试另一个Pod,因此它取决于具有工作准备就绪探测。

Kubernetes网络开源组件
1、技术术语:

IPAM:IP地址管理;这个IP地址管理并不是容器所特有的,传统的网络比如说DHCP其实也是一种IPAM,到了容器时代我们谈IPAM,主流的两种方法: 基于CIDR的IP地址段分配地或者精确为每一个容器分配IP。但总之一旦形成一个容器主机集群之后,上面的容器都要给它分配一个全局唯一的IP地址,这就涉及到IPAM的话题。

Overlay:在现有二层或三层网络之上再构建起来一个独立的网络,这个网络通常会有自己独立的IP地址空间、交换或者路由的实现。

IPSesc:一个点对点的一个加密通信协议,一般会用到Overlay网络的数据通道里。

vxLAN:由VMware、Cisco、RedHat等联合提出的这么一个解决方案,这个解决方案最主要是解决VLAN支持虚拟网络数量(4096)过少的问题。因为在公有云上每一个租户都有不同的VPC,4096明显不够用。就有了vxLAN,它可以支持1600万个虚拟网络,基本上公有云是够用的。

网桥Bridge: 连接两个对等网络之间的网络设备,但在今天的语境里指的是Linux Bridge,就是大名鼎鼎的Docker0这个网桥。

BGP: 主干网自治网络的路由协议,今天有了互联网,互联网由很多小的自治网络构成的,自治网络之间的三层路由是由BGP实现的。

SDN、Openflow: 软件定义网络里面的一个术语,比如说我们经常听到的流表、控制平面,或者转发平面都是Openflow里的术语。

2、容器网络方案:
隧道方案( Overlay Networking )

隧道方案在IaaS层的网络中应用也比较多,大家共识是随着节点规模的增长复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个点。

  • Weave:UDP广播,本机建立新的BR,通过PCAP互通
  • Open vSwitch(OVS):基于VxLan和GRE协议,但是性能方面损失比较严重
  • Flannel:UDP广播,VxLan
  • Racher:IPsec
路由方案

路由方案一般是从3层或者2层实现隔离和跨主机容器互通的,出了问题也很容易排查。

  • Calico:基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。
  • Macvlan:从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。
Flannel容器网络:

Flannel之所以可以搭建kubernets依赖的底层网络,是因为它可以实现以下两点:

  • 它给每个node上的docker容器分配相互不想冲突的IP地址;
  • 它能给这些IP地址之间建立一个覆盖网络,同过覆盖网络,将数据包原封不动的传递到目标容器内。
Flannel介绍
  • Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。

  • 在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使这些容器之间能够之间通过IP地址相互找到,也就是相互ping通。

  • Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

  • Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发。
    在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值