Kubernetes(k8s) 核心概念

1. 简介

   容器相对于物理机和虚拟机而言是很轻量化的技术,在相同资源下容器能创建出更多的实例.一方面,一旦面对分布在多台主机上且拥有数百个容器的大规模应用时,传统的或单机的容器管理解决方案(比如docker-compose)就会变得"力不从心".另一方面,由于为微服务提供了越来越完善的原生支持,在一个容器集群中的容器粒度越来越小、数量越来越多,在这种情况下,容器或微服务都需要接受管理并有序介入外部环境,从而完成调度、负载均衡及分配等任务.简单且高效地管理快速增长的容器实例,是一个容器编排系统的主要任务.

  而Kubernetes就是容器编排和管理系统中的最佳选择.Kubernetes的核心是如何解决自动化部署,扩展和管理容器化应用程序.Kubernetes起源于Google内部的Borg系统,因为其具有丰富的功能而被多家公司使用,其发展路线注重规范的标准化和厂商"中立",支持rkt等不同的底层容器运行时和引擎,逐渐解除对Docker的依赖.

  Kubernetes又简称为k8s,设计初衷是在主机集群之间提供一个能够自动化部署、可扩展、应用容器可运营的平台.在整个k8s生态系统中,能够兼容大多数的容器技术实现,比如Docker与Rocket.

2. k8s 核心概念

  k8s属于主从的分布式集群架构,包含Master和Node:Master作为控制节点,调度并管理整个系统:Node是运行节点,运行业务容器.每个Node上运行着多个Pod,Pod可以运行多个容器,但是Pod无法直接对来自k8s集群外部的访问提供服务.

2.1. Master

  Master节点上面主要由4个组件:API Server、Scheduler、Controller Manager、etcd.

  • etcd 是 k8s 用于存储各个资源状态的分布式数据库
  • API Server(kub-apiserver) 主要提供认证与授权、管理API版本等功能,通过RESTful API向外部提供服务,对资源(Pod、Deployment、Service等)进行增加、删除、修改、查看等操作都要先交给API Server处理再提交给etcd.
  • Scheduler(kube-scheduler) 负责调度Pod到合适的Node上,根据集群的资源和状态选择合适的节点创建Pod.Kubernetes提供了调度算法的实现接口,用户可以根据自己的需求定义自己的调度算法。
  • Controller Manager, 每个资源一般都对应一个控制器,Controller Manager负责管理这些控制器.例如,我们通过API Server创建了一个Pod,当这个Pod创建成功后,API Server的任务就算完成了,而后面保证Pod的状态始终和我们预期的一样.这个工作是由Controller Manager完成的.

2.2. Pod

  k8s将容器归类到一起,形成"容器集合"(Pod).Pod是k8s的基本操作单元,也是应用运行的载体.整个k8s系统都是围绕Pod展开的,例如,如何部署、运行Pod,如何保证Pod的数量,如何访问Pod等.

   同一个Pod下的多个容器共用一个IP,所以不能出现重复的端口号.一个Pod下的多个容器可以使用localhost加端口号的方式来访问对方的端口.理论上就是创建了一系列独立的Linux Namespace,然后同一个Pod下的所有容器都使用这个Linux Namespace.
  如下图所示,每个圆圈代表一个Pod,圆圈中的正方体代表一个容器,圆柱体代表一个卷(Volume).Pod 4中包含了3个容器、两个卷,该Pod的IP地址为10.10.10.4.

2.3. Node

  Node指k8s中的工作机器,既可以是虚拟机也可以是物理机,由Master进行管理.每个Node上可以运行多个Pod,Master会根据集群中每个Node上的可用资源情况,自动调度Pod的部署.

  每个Node上都会运行以下内容

  • kubelet: Master在每个 Node 上的代理,负责Master和Node之间的通信,并管理Pod和容器.
  • kube-proxy: 实现了k8s中的服务发现和反向代理功能.在反向代理方面,kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与Service对应的一组后端Pod中.在服务发现方面,kube-proxy使用etcd的watch机制,监控集群中Service和Endpoint对象数据的动态变化,并且维护一个Service到Endpoint的应设管理,从而保证了后端Pod的IP地址发生变化时不会对访问者造成影响.
  • Docker或其他容器:负责从镜像仓库拉取容器镜像、解压缩容器及运行应用程序.

2.4. RC

  RC是k8s中的另一个核心概念,应用托管在k8s之后,k8s需要保证应用能够持续运行,这就是RC的工作内容,它会确保无论任何时间k8s中都有指定数量的Pod在运行.在此基础上,RC还提供了一些更高级的特性,比如弹性伸缩、滚动升级等.

  RC与Pod的关联是通过Label来实现的,Label是一系列的Key/Value对.Label机制是k8s中的一个重要设计,通过Label进行对象的关联,可以灵活地进行对象分类和选择.对Pod,需要设置其自身的Label来标识.

  对RC的弹性伸缩、滚动升级的特性描述如下.

  • 弹性伸缩
      弹性伸缩是指适应负载的变化,以弹性可伸缩的方式提供资源.反映到k8s中,使之可以根据负载的高低动态调整Pod的副本数量.例如在双十一将Pod数量调整为100,双十一结束后数量调整为10.
  • 滚动升级
      滚动升级是一种平滑过渡的升级方式,通过逐步替换的策略,来保证系统的整体稳定性,在初始升级的时候就可以及时发现问题并进行调整,以保证问题的影响程度不会被扩大.回退操作通过滚动升级的逆操作即可完成.

2.5. Service

  互联网业务中,为了适应快速的业务需求,微服务架构已经逐渐成为主流.微服务架构的应用需要有非常好的服务编排的支持,k8s中的核心姚旭Service便提供了一套简化的服务代理和发现机制,天然适应微服务架构.
  在k8s中,受到RC调控时,Pod副本是变化的,对应的虚拟IP地址也是变化的,比如发生迁移或伸缩的时候,这对Pod的访问者来说是不可接受的.Service是服务的抽象,定义了一个Pod的逻辑分组和访问这些Pod的策略,执行相同任务的Pod可以组成一个Service,并以Service的IP地址提供服务.Service的目标是提供一个桥梁,它会为访问者提供一个固定的访问地址,用于在访问时重定向到相应的后端,这使得非k8s原生的应用程序,在无需为k8s编写特定代码的前提下,轻松访问后端.

  
  Service同RC一样,都是通过Label来关联Pod的.一组Pod能够被Service访问到,通常是通过Label Selector实现的.Service负责将外部的请求发送到k8是内部的Pod中,也将内部Pod的请求发送到外部,从而实现服务请求的转发.当Pod发生变化时(增加、减少、重建等),Service会及时更新.这样,Service就可以作为Pod的访问入口,起到代理服务器的作用,而对于访问者来说,通过Service进行访问,无需直接感知Pod.
  需要注意的是,Kubernetes分配给Service的固定IP地址是一个虚拟 IP地址,并不是一个真实的IP地址,在外部是无法寻址的。在真实的系 统实现上,Kubernetes通过kube-proxy来实现虚拟IP地址的路由及转发.所以正如前面所说的,每个Node上都需要部署Proxy组件,从而实现 Kubernetes层级的虚拟转发网络任务.

  

  • Service内部负载均衡
    当Service的Endpoint包含多个IP地址的时候,服务代理会存在多个后端,将进行请求的负载均衡.默认的负载均衡策略是轮询或随机(由 kube-proxy的模式决定).
  • 多个Service如何避免地址和端口冲突
    一方面,Kubernetes为每个Service分配一个唯一的ClusterIP,所以 当使用ClusterIP:port的组合访问一个Service的时候,不管端口是什么,这个组合是一定不会发生重复的.另一方面,kube-proxy为每个Service 真正打开的是一个绝对不会重复的随机端口,用户在Service描述文件中 指定的访问端口会被映射到这个随机端口上.这就是为什么用户在创建 Service时可以随意指定访问端口.
  • 新一代副本控制器RS
    这里所说的RS(Replica Set),可以被认为是“升级版”的RC.也就 是说,RS也是用于保证与Label Selector匹配的Pod数量维持在用户期望的状态.区别在于,RS引入了对基于子集的selector查询条件,而RC仅 支持基于值相等的selector查询条件.这是目前从用户角度看,两者唯一的显著差异.社区引入这一API的初衷是用于取代vl中的RC的,也就是说,当v1版本被废弃时,RC就完成了它的历史使命,而由RS来接管其工作.虽然RS可以被单独使用,但是目前它多数被Deployment用于进行Pod的创建、更新与删除.Deployment在滚动更新等方面提供了很多非常有用的功能.

2.6. Deployment

   k8s提供了一种更加简单的更新RC和Pod的机制,成为Deployment.通过在Deployment中描述所期望的集群状态,Deployment Controlloer会讲现在的集群状态在一个可控的速度下逐步更新成所期望的集群状态.Deployment的主要职责同样是保证Pod的数量和健康,继承了上面所述的RC的全部功能(90%的功能与RC完全一样),可以看做是新一代的RC.

2.7. Namespace

  对同一物理集群,k8s可以虚拟出多个虚拟集群,这些虚拟机群即称为Namespace.Kubernetes中的Namespace旨在解决的场景是:多个用户分 布在多个团队或项目中,但这些用户使用同一个Kubernetes集群. Kubernetes通过Namespace的方式将一个集群的资源分配给多个用户.   Namespace中包含的资源通常有:Pod、Service和RC等.但是一些较底层的资源并不属于任何一个Namespace,如Node、 PersistentVolume.同一个Namespace下的资源名称必须是唯一的,但是 不同Namespace下的资源名称可以重复.

2.8. Volume

  容器中的文件在磁盘上是临时存放的,这给容器中运行的较重要的应用程序带来一些问题。一是当容器崩溃时文件丢失。kubelet 会重新启动容器,但容器会以干净的状态重启.二是如何在同一 Pod 中运行多个容器并共享文件。k8s卷(Volume) 这一抽象概念能够解决这两个问题。
  k8s支持很多类型的卷。Pod 可以同时使用任意数目的卷类型.临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长.当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷.对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失.

卷的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据. 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容.

2.9. Persistent Volume(持久卷,PV) 和 Persistent Volume Claim(持久卷申领,PVC)

  持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者 使用存储类(Storage Class)来动态供应.持久卷是集群资源,就像节点也是集群资源一样.PV 持久卷和普通的 Volume 一样,也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期.此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统.

  持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求.概念上与 Pod 类似.Pod 会耗用 Node 资源,而 PVC 申领会耗用 PV 资源.Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式(例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载).

总结

  本文介绍了K8S的核心组件和概念,想要理解k8s,首先需要对容器有较为深入的认识.在K8S中可以简单认为是Pod.其他所有的功能都是来保证Pod可以正确的提供服务.k8s的概念和组件较多,可以先搭建一个k8s集群,然后从Pod开始,按顺序Deployment,PV,PVC,Service走一遍.这样子学习的效果更好,难度更底(但是动手能力不能太差奥).

引用

k8s 官方文档
英特尔亚太研发有限公司:Linux开源存储全栈详解:从Ceph到容器存储

posted @ 2022-04-20 17:20  哪吒young  阅读(405)  评论(0编辑  收藏  举报