容器化技术

[容器化技术之十三] K8S核心概念及术语

2020-03-05  本文已影响0人  小胡_鸭

一、什么是Kubernetes

  Kubernetes,又成为k8s(首字母为k,首字母与尾字母之间有8个字符,尾字母为s,所以简称为k8s),或者简称为 “kube” ,是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。也就是说,你可以将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助你轻松高效地管理这些集群。而且,这些集群可跨公共云、私有云或混合云部署主机。因此。对于要求快速扩展的云原生而言(例如借助 Apache Kafka 进行的实时数据流处理),Kubernetes 是理想的托管平台。

  Kubernetes 最初由 Google 的工程师基于 go 语言开发和设计出来并于2014年6月开源。Google 是最早研发 Linux 容器技术的企业之一,曾公开分享介绍 Google 如何将一切都运行与容器之中(这时 Google 云服务背后的技术)。Google 每周会启用超过20亿个容器——全部都由内部平台 Borg 支撑,Borg 是 Kubernetes 的前身,多年来开发 Borg 的经验教训成了影响 Kubernetes 中许多技术的主要因素。

  红帽是第一批与 Google 合作研发 Kubernetes 的公司之一,作为 Kunernetes 上游项目的第二大贡献这,甚至在这个项目启动之前就已参与其中。2015年,Google 将 Kubernetes 项目捐赠给了新成立的云原生计算基金会。

二、为什么需要kubernetes

  在当下风靡的云计算生态中,Docker从发布开始就引领这容器化技术的潮流,Docker非常适合管理单个容器。但是如果我们的分布式应用系统是由多个容器组成的,随着系统地迭代演化,使用越来越多的容器和容器化应用程序,并处于高并发、高可用等考虑将其划分为数百个部分,很可能会导致管理和编排变得非常困难。我们迫切需要对容器实施分组,以便跨所有容器提供网络、存储、安全、遥测等服务,于是,Kubernetes 应运而生。



  真正的生产型应用会涉及多个容器,这些容器必须跨多个服务器主机进行部署。Kubernetes 可以提供所需的编排和管理功能,以便针对这些工作负载大规模部署容器。借助 Kubernetes 编排功能,我们可以构建跨多个容器的应用服务、跨集群调度、扩展这些容器,并长期持续管理这些容器的健康状况。

  Kubernetes 还需要与联网、存储、安全性、遥测和其他服务集成整合,以提供全面的容器基础架构。


  当然,这取决你如何在你的环境中使用容器。Linux 容器中的基本应用将它们视作高效、快速的虚拟机。一旦把它部署到生产环境或扩展为多个应用,显然需要许多托管在相同位置的容器来协同提供各种服务。随着这些容器的累积,运行环境中容器的数量会急剧增加,复杂度也随之增长。

  Kubernetes 通过将容器分类组成 “容器集”(pod),解决了容器增殖带来的许多常见问题。容器集为分组容器增加了一个抽象层,可帮助你调用工作负载,并未这些容器提供所需的联网和存储服务。Kubernetes 的其他部分可帮助你在这些容器集之间达成负载平衡,同时确保运行正确数量的容器,充分支持工作负载。

  如果能正确实施 Kubernetes,再辅以其他开源项目(例如 Atomic 注册表、Open vSwitch、heapster、OAuth 以及 SELinux),你就能够轻松编排容器基础架构的各个部分。

三、kubernetes 有哪些用途

  在生产环境中使用 kubernetes 的主要优势在于,它提供了一个便捷有效的平台,让你可以在物理机和虚拟机集群上调度和运行容器。更广泛一点说,它可以帮助你在生产环境中,完全实施并依托基于容器的基础架构运行。由于 Kubernetes 的实质在于实现操作任务自动化,所以可以将其他应用平台或管理系统分配的许多相同任务交给容器来执行。

  利用 Kubernetes ,可以达成以下目标:

  • 跨多台主机进行容器编排。
  • 更加充分地利用硬件,最大程度获取运行企业应用所需的资源。
  • 有效地管控应用部署和更新,并实现自动化操作。
  • 挂载和增加存储,用于运行有状态的应用。
  • 快速、按需扩展容器化应用及其资源。
  • 对服务进行声明式管理,保证所部署的应用始终按照部署的方式运行。
  • 利用自动布局、自动重启、自动复制以及自动扩展功能,对应用实施状况检查和自我修复。



  但是,Kubernetes 需要依赖其他项目来全面提供这些经过编排的服务。因此,借助其他开源项目可以帮助我们将 kubernetes 的全部公用发挥出来,这些功能包括:

  • 注册表,通过 Atomic 注册表或 Docker 注册表等项目实现。
  • 联网,通过 OpenvSwitch 和智能边缘路由等项目实现。
  • 遥测,通过 heapsterkibanahawkularelastic 等项目实现。
  • 安全性,通过 LDAPSELinuxRBACOAUTH 等项目以及多租户层来实现。
  • 自动化,参照 Ansible 手册进行安装和集群生命周期管理。
  • 服务,可通过自带预建版常用应用模式的丰富内容目录来提供。


四、kubernetes 核心概念

  Kubernetes 有各类资源对象来描述整个集群的运行状态(NodePodReplication ControllerService 等都可以看作是一种 “资源对象”)。这些对象都需要通过调用 kubernetes api 来创建、修改、删除并将其保存在 etcd 中持久化存储,可以通过 kubectl 命令工具,也可以直接调用 k8s api,或者使用对象语言的客户端库(例如:golangpython).


  从这个角度来看,Kubernetes 其实是一个高度自动化的资源控制系统,它通过跟踪对比 etcd 库里保存的 “资源期望状态” 与当前环境中的 “实际资源状态” 的差异来实现自动控制和自动纠错的高级功能。

  每个 kunernetes 对象都会包含两个关键字段:Object Spec 和 Object Status。spec 描述了对象所期望达到的状态,status 描述了该对象的实际状态。

1、Master

  Kubernetes 里的 Master 指的是集群控制节点,每个 Kubernetes 集群里需要有一个 Master 节点来负责整个集群的管理和控制,基本上 Kubernetes 的所有控制命令都发给它,它来负责具体的执行过程。Master 节点通常会占据一个独立的服务器(高可用部署建议用3台服务器),其主要原因是它太重要了,是整个集群的 “首脑”,如果宕机或者不可用,name对集群内容器应用的管理都将失效。

  Master 节点上运行着以下一组关键进程:

  • Kubernetes API Server(kube-apiserver):提供了 HTTP Reset 接口的关键服务进程,是Kubernetes 里所有资源的增、删、查、改等操作的唯一入口,也是集群控制的入口进程。
  • Kubernetes Controller Manager(kube-controller-manager):Kubernetes 里所有资源对象的自动化> 控制中心,由一系列控制器组成:
      Replication Controller
      Node Controller
      CronJob Controller
      Daemon Controller
      Deployment Controller
      Endpoint Controller
      Garbage Collector
      Namespace Controller
      Job Controller
      Pod AutoScaler
      RelicaSet
      Service Controller
      ServiceAccount Controller
      StatefulSet Controller
      Volume Controller
      Resource quota Controller
  • Kubernetes Scheduler(kube-scheduler):负责资源调度(Pod)调度的进程,相当于公交公司的 “调度室”。

  另外,在Master 节点上还需要启动一个 etcd 服务,因为 Kubernetes 里的所有资源对象的数据全部是保存在 etcd 中的。

2、Node

  除了 Master,Kubernetes 集群中的其他机器被成为 Node 节点,最开始被称为minion。与Master 一样。一个Node可以是VM或物理机。Node 节点是Kubernetes 集群中的工作负载节点,每个Node(节点)具有运行pod的一些必要服务,由Master组件进行管理分配一些工作负载,Node节点上的服务包括Dockerkubeletkube-proxy

  每个Node 节点上都运行这以下一组关键进程:


  • kubelet:负责 Pod 对象的容器的创建、启停等任务,同时与 Master 节点密切协作,实现集群管理的基本功能。
  • kube-proxy:实现 Kubernetes Service 的通信与负载均衡机制的重要组件。
  • Docker Engine(docker):Docker 引擎,负责本机的容器创建和管理工作。

  Node 节点可以在运行期间动态增加到 Kubernetes 集群中,前提是这个节点上已经正确安装、配置和启动了上述关键进程,在默认情况下 kubelet 会向 Master 注册自己,这也是 Kubernetes 推荐的 Node管理方式。一旦 Node 被纳入集群管理范围,kubelet 进程就会定时向 Master 节点汇报自身的情报,例如操作系统、Docker 版本、机器的 CPU 和内存情况,以及当前有哪些 Pod 在运行等,这样 Master 可以获知每个 Node 的资源使用情况,并实现高效均衡等资源调度策略。而某个 Node 超过指定时间不上报信息时,会被 Master 判断为“失联”,Node 的状态被标记为不可用(Not Ready),随后 Master 会触发“工作负
载大转移”的自动流程。

3、Pod

  Pod 是 Kubernetes 的最重要也是最基本的概念,如下图所示是Pod的组成示意图,我们看到每个 Pod 都有一个特殊的被成为“根容器”的 Pause 容器。Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器。


为什么 Kubernetes 会设计出一个全新的 Pod 概念并且 Pod 有这样特殊的组成结构?

  • 原因之一:在一组容器作为一个单元的情况下,我们难以对“整体”简单地进行判断及有效地进行行动。比如,一个容器死亡了,此时算是整体死亡么?引入业务无关并且不易死亡的 Pause 容器作为 Pod的根容器,以它的状态代表整体容器组的状态,就简单、巧妙地解决了这个难题。

  • 原因之二:Pod 里的多个业务容器共享 Pause 容器的 IP,共享 Pause 容器挂接的 Volume,这样既简化了密切关联的业务容器之间的通信问题,也很好地解决了它们之间的文件共享问题。

  Kubernetes 为每个 Pod 都分配了唯一的 IP 地址,称之为 Pod IP,一个 Pod 里的多个容器共享 Pod IP 地址。Kubernetes 要求底层网络支持集群内任意两个 Pod 之间的 TCP/IP 直接通信,这通常采用虚拟低层网络技术来实现,例如 Flannel、Open vSwitch 等,因此我们需要牢记一点:在 Kubernetes 里,一个Pod 里的容器与另外主机上的 Pod 容器能够直接通信。

  Pod 其实有两种类型:普通的 Pod静态 Pod (Static Pod),后者比较特殊,它并不存放在 Kubernetes的 etcd 存储里,而是存放在某个具体的 Node 上的一个具体文件中,并且只在此 Node 上启动运行。而普通的 Pod 一旦被创建,就会被放入到 etcd 中存储,随后会被 Kubernetes Master 调度到某个具体的 Node上并进行绑定(Binding),随后该 Pod 被对应的 Node 上的 kubelet 进程实例化成一组相关的 Docker 容器并且启动起来。在默认情况下,当 Pod 里的某个容器停止时,Kubernetes 会自动检测到这个问题并且重新启动这个 Pod(重启 Pod 里的所有容器),如果 Pod 所在的 Node 宕机,则会将这个 Node 上的所有 Pod重新调度到其他节点上。Pod、容器与 Node 的关系图如下图所示。

Pod、容器与 Node 的关系

4、Label

  Label 是 Kubernetes 系统中另外一个核心概念。一个 Label 是一个 key=value 的键值对,其中 key 与 vaue 由用户自己指定。Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。

  我们可以通过指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等管理工作。例如:部署不同版本的应用到不同的环境中;或者监控和分析应用(日志记录、监控、告警)等。一些常用等 label 示例如下。

  版本标签:"release" : "stable" , "release" : "canary"...
  环境标签:"environment" : "dev" , "environment" : "production"
  架构标签:"tier" : "frontend" , "tier" : "backend" , "tier" : "middleware"
  分区标签:"partition" : "customerA" , "partition" : "customerB"...
  质量管控标签:"track" : "daily" , "track" : "weekly"


  Label 相当于我们熟悉的“标签”,給某个资源对象定义一个 Label,就相当于給它打了一个标签,随后可以通过 Label Selector(标签选择器)查询和筛选拥有某些 Label 的资源对象,Kubernetes 通过
这种方式实现了类似 SQL 的简单又通用的对象查询机制。



5、Replication Controller

  RC 是 Kubernetes 系统中的核心概念之一,简单来说,它其实是定义了一个期望的场景,即声明某种 Pod 的副本数量在任意时刻都符合某个预期值,RC 的定义包括如下几个部分。

  • Pod 期待的副本数(replicas)。
  • 用于筛选目标 Pod 的 Label Selector。
  • 当 Pod 的副本数量小于预期数量时,用于创建新 Pod 的 Pod 模版(template)。

  在用户定义范围内,如果pod增多,则ReplicationController会终止额外的pod,如果减少,RC会创建新的pod,始终保持在定义范围。例如,RC会在Pod维护(例如内核升级)后在节点上重新创建新Pod。

6、Deployment

  Deployment 是 Kubernetes v1.2 引入的概念,引入的目的是为了更好地解决 Pod 的编排问题。为此,Deployment 在内部使用了 Replica Set 来实现目的,无论从 Deployment 的作用与目的,它的 YAML 定义,还是从它的具体命令行操作来看,我们都可以把它看作 RC 的一次升级,两者相似度超过 90%。

  Deployment 相对于 RC 的一个最大升级是我们随时知道当前 Pod“部署”的进度。实际上由于一个 Pod 的创建、调度、绑定节点及在目标 Node 上启动对应的容器这一完整过程需要一定的时间,所以我们期待系统启动 N 个 Pod 副本的目标状态,实际上是一个连续变化的“部署过程”导致的最终状态。

  Deployment 的典型使用场景有以下几个。

  • 创建一个 Deployment 对象来生成对应的 Replica Set 并完成 Pod 副本的创建过程。
  • 检查 Deployment 的状态来看部署动作是否完成(Pod 副本的数量是否达到预期的值)。
  • 更新 Deployment 以创建新的 Pod(比如镜像升级)。
  • 如果当前 Deployment 不稳定,则回滚到一个早先的 Deployment 版本。
  • 暂停 Deployment 以便 于一次性 修改多个 PodTemplateSpec 的配 置项,之 后再恢 复Deployment,进行新的发布。
  • 扩展 Deployment 以应对高负载。
  • 查看 Deployment 的状态,以此作为发布是否成功的指标。
  • 清理不再需要的旧版本 ReplicaSets。

7、StatefulSet

  在 Kubernetes 系统中,Pod 的管理对象 RC、Deployment、DaemonSet 和 Job 都是面向无状态的服务。但现实中有很多服务是有状态的,特别是一些复杂的中间件集群,例如 MySQL 集群、MongoDB 集群、Kafka 集群、Zookeeper 集群等,这些应用集群有以下一些共同点。

  • 每个节点都有固定的身份 ID,通过这个 ID,集群中的成员可以相互发现并且通信。
  • 集群的规模是比较固定的,集群规模不能随意变动。
  • 集群里的每个节点都是有状态的,通常会持久化数据到永久存储中。
  • 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。

  StatefulSet 是为了解决有状态服务问题(对应 Deployment 和 ReplicaSets 是为无状态服务而设计),从本质上来说,可以看作 Deployment/RC 的一个特殊变种,它有如下一些特性:

  • 稳定性,唯一的网络标识符。

  可以用来发现集群内的其他成员。假设StatefulSet 的名字叫 kafka,那么第一个 Pod 叫 kafak-0,
  第二个 Pod 叫 kafak-1,以此类推。

  • 稳定性,持久化存储。

  通过 PV/PVC 来实现,删除 Pod 时默认不会删除与StatefulSet 相关的存储卷(为了保证数据的安全)。

  • 有序的部署和扩展。

  操作第 n 个 Pod 时,前 n-1 个 Pod 已经时运行且准备好的状态。

  • 有序的删除和终止。
  • 有序的自动滚动更新。

  Pod调度运行时,如果应用不需要任何稳定的标示、有序的部署、删除和扩展,则应该使用一组无状态副本的控制器来部署应用,例如 DeploymentReplicaSet 更适合无状态服务需求。

  StatefulSet 除了要与 PV 卷捆绑使用以存储 Pod 的状态数据,还要与 Headless Service 配合使用,即在每个 StatefulSet 的定义中要声明它属于哪个 Headless Service。Headless Service 与普通 Service 的关键区别在于,它没有 Cluster IP,如果解析 Headless Service 的 DNS 域名,则返回的是该 Service对应的全部 Pod 的 Endpoint 列表。StatefulSet 在 Headless Service 的基础上又为 StatefulSet 控制的每个 Pod 实例创建了一个 DNS 域名,这个域名的格式为:

$(podname).$(headless service name)

  比如一个 3 节点的 Kafka 的 StatefulSet 集群,对应的 Headless Service 的名字为 kafka,StatefulSet 的名字为 kafka,则 StatefulSet 里面的 3 个 Pod 的 DNS 名称分别为 kafka-0.kafka、kafka-1.kafka、kafka-3.kafka,这些 DNS 名称可以直接在集群的配置文件中固定下来。

8、Service

  Service 也是 kubernetes 里的最核心的资源对象之一,Kubernetes 里的每个 Service 其实就是我们经常提起的微服务架构中的一个 “微服务”,下图显示了 Pod、RC 与 Service 的逻辑关系:


  从图中可以看到,Kubernetes 的 Service 定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例,Service 与后端 Pod 副本集群之间则是通过 Label Selector 来实现 “无缝对接” 的。而 RC 的作用实际上是保证 Service 的服务能力和服务质量始终处于预期的标准。

9、Volume

  容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题,第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态,第二,当很多容器在同一 Pod 中运行的时候,很多时候需要数据文件的共享。Kubernete Volume 解决了这个问题。


  Volume是Pod中能够被多个容器访问的共享目录。Kubernetes 的 Volume 概念、用途和目的与 Docker 的 Volume 比较类似,但两者不能等价。首先,Kubernetes 中的 Volume 定义在 Pod 上,然后被一个 Pod 里的多个容器挂载到具体的文件目录下;其次,Kubernetes 中的 Volume 中的数据也不会丢失。最后,Kubernetes 支持多种类型的 Volume,例如 Gluster、Ceph 等先进的分布式文件系统。

10、Annotation

  Annotation 与 Label 类似,也使用 key/value 键值对的形式进行定义。不同的是 Label 具有严格的命名规则,它定义的是 Kubernetes 对象的元数据(Metadata),并且用于 Label Selector。而 Annotation 则是用户任意定义的“附加”信息,以便于外部工具进行查找,很多时候,Kubernetes 的模块自身会通过 Annotation 的方式标记资源对象的特殊信息。

  通常来说,用 Annotation 来记录的信息如下。

  • build 信息、release 信息、Docker 镜像信息等,例如时间戳、release id 号、PR 号、镜像hash 值、docker registry 地址等。
  • 日志库、监控库、分析库等资源库的地址信息。
  • 程序调试工具信息,例如工具、版本号等。
  • 团队等联系信息,例如电话号码、负责人名称、网址等。

11、kubelet

  kubelet 是主要的节点代理,它会监视已分配给节点的pod,具体功能:

12、kubectl

  kubectl 用于运行 Kubernetes 集群命令的管理工具。

上一篇下一篇

猜你喜欢

热点阅读