+++
title = ‘K8S核心概念’
date = 2024-04-01T12:00:58+08:00
draft = true

+++

一、认识Kubernetes

1.1 什么是Kubernetes?

Kubernetes 是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes 提供了应用部署,规划,更新,维护的一种机制。

Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。

1.2 为什么需要Kubernetes?

1.2.1 应用部署的三大阶段

  • 传统部署: 程序员/运维工程师手动操作部署应用,直接将应用部署在目标机器上,由于资源不隔离,容易出现资源争抢、依赖冲突等各方面问题。

    请添加图片描述

  • 虚拟化部署: 利用 OpenStask / VMware 等虚拟化技术,将一台目标机器虚拟化为多个虚拟机器,按照需求将应用部署到不同的虚拟机中,对虚拟机进行动态的水平扩容等管理操作。

    相对传统部署自动化、资源隔离的能力提升了,带来的问题是虚拟化的逻辑过重,导致效率不高,且耗费资源较多。

    请添加图片描述

  • 容器化部署: 可以理解为轻量级的虚拟化,完美弥补虚拟化技术过重的问题,且由于直接共享主机硬件资源,只是通过系统提供的命名空间等技术实现资源隔离,损耗更小,且效率更高。

    请添加图片描述

1.2.2 K8S的特点

  • 自我修复
  • 弹性伸缩
  • 自动部署和回滚
  • 服务发现和负载均衡
  • 机密和配置管理
  • 存储编排
  • 批处理

1.3 企业级容器调度平台

1.3.1 Apache Mesos

基本概念

Mesos 是一个分布式调度系统内核,早于 Docker 产生,Mesos 作为资源管理器,从 DC/OS (数据中心操作系统)的角度提供资源视图。主/从结构工作模式,主节点分配任务,并用从节点上的 Executor 负责执行,通过 Zookeeper 给主节点提供服务注册、服务发现功能。通过 Framework Marathon 提供容器调度的能力。

优势

经过时间的检验,作为资源管理器的 Apache Mesos 在容器之前就已经出现很久了,支持运行容器化化和非容器化的工作负载。可以支持应用程序的健康检查,开放的架构。支持多个框架和多个调度器,通过不同的 Framework 可以运行 Haddop/Spark/MPI等多种不同的任务。

支持超大型规模的节点管理,模拟测试支持超过 5w+ 节点,在大规模上拥有较大优势。

1.3.2 Docker Swarm

基本概念

Docker Swarm 是一个由 Docker 开发的调度框架。由 Docker 自身开发的好处之一就是标准 Docker API 的使用,Swarm 由多个代理(Agent)组成,把这些代理称之为节点(Node)。这些节点就是主机,这些主机在启动 Docker Daemon 的时候就会打开相应的端口,以此支持 Docker 远程 API。这些机器会根据 Swarm 调度器分配给它们的任务,拉取和运行不同的镜像。

优势

从 Docker1.12 版本开始,Swarm 随 Docker 一起默认安装发布。由于随 Docker 引擎一起发布,无需额外安装,配置简单。支持服务注册、服务发现,内置 Overlay Network 以及 Load Balancer。与 Docker CLI 非常类似的操作命令,对熟悉 Docker 的人非常容易上手学习。

入门门槛、学习成本较低,使用更便捷,适用于中小型系统。

1.3.3 Google Kubernetes

基本概念

Kubernetes 是基于 Google 在过去十五年来大量生产环境中运行工作负载的经验。Kubernetes 的实现参考了 Google 内部的资源调度框架,但并不是 Borg 的内部容器编排系统的开源,而是借鉴 Google 从运行 Borg 获得的经验教训,形成了 Kubernetes 项目。

Borg的架构图:

请添加图片描述

它使用 Label 和 Pod 的概念来将容器划分为逻辑单元。Pods 是同地协作(co-located)容器的集合,这些容器被共同部署和调度,形成了一个服务,这是 Kubernetes 和其他两个框架的主要区别。相比于基于相似度的容器调度方式(就像 Swarm 和Mesos),这个方法简化了对集群的管理。

优势

最流行等容器编排解决方案框架,基于 Google 庞大的生态圈及社区产生的产品。通过 Pods 这一抽象的概念,解决 Container 之间的依赖于通信问题。Pods,Services,Deployments 是独立部署的部分,可以通过 Selector 提供更多的灵活性。内置服务注册表和负载平衡。

适用度更广,功能更强大,相较于 Mesos 来说节点规模较小。

二、集群架构与组件

2.1 相关组件

请添加图片描述

2.1.1 控制面板组件(Master)

请添加图片描述

api-server: API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。

Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。

kube-controller-manager: 控制器管理器:管理各个类型的控制器针对k8s中的各种资源进行管理。这些控制器包括:

  • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
  • 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
  • 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
  • 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。

cloud-controller-manager: 云控制器管理器:第三方云平台提供的控制器API对接管理功能。嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。

cloud-controller-manager 仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。

与 kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

kube-scheduler: 调度器:负责将Pod基于一定算法,将其调用到更合适的节点(服务器)上。

etcd: 理解为k8s的数据库,提供了基于Raft算法实现自主的集群高可用。一致且高度可用的键值存储,用作 Kubernetes 的所有集群数据的后台数据库。

如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。

你可以在官方文档中找到有关 etcd 的深入知识。

早期数据存放在内存,现在已经是持久化存储的了。

2.1.2 节点组件(Node)

kubelet: kubelet 负责维护Pod的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;

kube-proxy: 网络代理,负责为 Service 提供 cluster 内部的服务发现和负载均衡(4层负载,基于iptables)。

container-runtime: 负责镜像管理以及 Pod 和容器的真正运行(CRI);

Kubernetes 支持许多容器运行环境,例如 containerdCRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。

2.1.3 附加组件

kube-dns: 负责为整理集群提供DNS服务。

Ingress Controller: 为服务提供外网入口。

Heapster: 提供资源监控(可替换,如Prometheus)。

Dashboard: 控制台,提供GUI。

Federation: 提供跨可用区的集群。

Fluentd-elasticsearch: 提供集群日志采集、存储与查询。

2.2 分层架构

请添加图片描述

生态系统: 在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:

  • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等。

  • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

接口层: kubectl命令行工具、客户端SDK以及集群联邦。

管理层: 系统度量(如基础设施、容器和网络的度量),自动化(如自动化扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)。

应用层: 部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)。

核心层: Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境。

三、核心概念与专业术语

3.1 服务的分类

3.1.1 无状态

代表应用: Nginx、Apache。

优点: 对客户端透明,无依赖关系,可以高效实现扩容、迁移。

缺点: 不能存储数据,需要额外的数据服务支撑。

3.1.2 有状态

代表应用: MySQL、Redis。

优点: 可以独立存储数据,实现数据管理。

缺点: 集群环境下需要实现主从、数据同步、备份、水平扩容复杂。

3.2 资源和对象

Kubernetes 中的所有内容都被抽象为“资源”,如 Pod、Service、Node 等都是资源。“对象”就是“资源”的实例,是持久化的实体。如某个具体的 Pod、某个具体的 Node。Kubernetes 使用这些实体去表示整个集群的状态。

对象的创建、删除、修改都是通过 “Kubernetes API”,也就是 “Api Server” 组件提供的 API 接口,这些是 RESTful 风格的 Api,与 k8s 的“万物皆对象”理念相符。命令行工具 “kubectl”,实际上也是调用 kubernetes api。

K8s 中的资源类别有很多种,kubectl 可以通过配置文件来创建这些 “对象”,配置文件更像是描述对象“属性”的文件,配置文件格式可以是 “JSON” 或 “YAML”,常用 “YAML”。

3.2.1 资源的分类

3.2.1.1 元数据型

对于资源的元数据描述,每一个资源都可以适用元空间的数据(主要针对于Pod)。

Horizontal Pod Autoscaler(HPA): Pod 自动扩容:可以根据 CPU 使用率或自定义指标(metrics)自动对 Pod 进行扩/缩容。

  • 控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况。

  • 支持三种metrics类型:

    1. 预定义metrics(比如Pod的CPU)以利用率的方式计算。
    2. 自定义的Pod metrics,以原始值(raw value)的方式计算。
    3. 自定义的object metrics。
  • 支持两种metrics查询方式:Heapster和自定义的REST API。

  • 支持多metrics。

PodTemplate: Pod Template 是关于 Pod 的定义,但是被包含在其他的 Kubernetes 对象中(例如 Deployment、StatefulSet、DaemonSet 等控制器)。控制器通过 Pod Template 信息来创建 Pod。

LimitRange: 可以对集群内 Request 和 Limits 的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的 Pod 的资源使用限制。

3.2.1.2 集群级

请添加图片描述

Namespace: Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群,这些虚拟集群被称为命名空间。

作用是用于实现多团队/环境的资源隔离。

命名空间 namespace 是 k8s 集群级别的资源,可以给不同的用户、租户、环境或项目创建对应的命名空间。

默认 namespace:

  • kube-system 主要用于运行系统级资源,存放 k8s 自身的组件
  • kube-public 此命名空间是自动创建的,并且可供所有用户(包括未经过身份验证的用户)读取。此命名空间主要用于集群使用,关联的一些资源在集群中是可见的并且可以公开读取。此命名空间的公共方面知识一个约定,但不是非要这么要求。
  • default 未指定名称空间的资源就是 default,即你在创建pod 时如果没有指定 namespace,则会默认使用 default

Node: 不像其他的资源(如 Pod 和 Namespace),Node 本质上不是Kubernetes 来创建的,Kubernetes 只是管理 Node 上的资源。虽然可以通过 Manifest 创建一个Node对象(如下 json 所示),但 Kubernetes 也只是去检查是否真的是有这么一个 Node,如果检查失败,也不会往上调度 Pod。

ClusterRole: ClusterRole 是一组权限的集合,但与 Role 不同的是,ClusterRole 可以在包括所有 Namespace 和集群级别的资源或非资源类型进行鉴权。

ClusterRoleBinding: 将 Subject 绑定到 ClusterRole,ClusterRoleBinding 将使规则在所有命名空间中生效。

3.2.1.3 命名空间级(重点)
工作负载型
Pod

Pod(容器组)是 Kubernetes 中最小的可部署单元。一个 Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络 IP 地址、以及一些确定容器该如何运行的选项。Pod 容器组代表了 Kubernetes 中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。

Docker 是 Kubernetes Pod 中使用最广泛的容器引擎;Kubernetes Pod 同时也支持其他类型的容器引擎。
Kubernetes 集群中的 Pod 存在如下两种使用途径:

  • 一个 Pod 中只运行一个容器。“one-container-per-pod” 是 Kubernetes 中最常见的使用方式。此时,您可以认为 Pod 容器组是该容器的 wrapper,Kubernetes 通过 Pod 管理容器,而不是直接管理容器。

  • 一个 Pod 中运行多个需要互相协作的容器。您可以将多个紧密耦合、共享资源且始终在一起运行的容器编排在同一个 Pod 中。同一个Pod中的资源是通过pause容器进行的,pause容器负责共享同一Pod中的网络、文件系统等资源。

    请添加图片描述

副本(replicas): 先引入“副本”的概念——一个 Pod 可以被复制成多份,每一份可被称之为一个“副本”,这些“副本”除了一些描述性的信息(Pod 的名字、uid 等)不一样以外,其它信息都是一样的,譬如 Pod 内部的容器、容器数量、容器里面运行的应用等的这些信息都是一样的,这些副本提供同样的功能。

Pod 的***“控制器”***通常包含一个名为 “replicas” 的属性。“replicas”属性则指定了特定 Pod 的副本的数量,当当前集群中该 Pod 的数量与该属性指定的值不一致时,k8s 会采取一些策略去使得当前状态满足配置的要求。

控制器: 当 Pod 被创建出来,Pod 会被调度到集群中的节点上运行,Pod 会在该节点上一直保持运行状态,直到进程终止、Pod 对象被删除、Pod 因节点资源不足而被驱逐或者节点失效为止。Pod 并不会自愈,当节点失效,或者调度 Pod 的这一操作失败了,Pod 就该被删除。如此,单单用 Pod 来部署应用,是不稳定不安全的。

Kubernetes 使用更高级的资源对象 “控制器” 来实现对Pod的管理。控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。 例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。

  1. 适用无状态服务

    • ReplicationController(RC): Replication Controller 简称 RC,RC 是 Kubernetes 系统中的核心概念之一,简单来说,RC 可以保证在任意时间运行 Pod 的副本数量,能够保证 Pod 总是可用的。如果实际 Pod 数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些Pod,当 Pod 失败、被删除或者挂掉后,RC 都会去自动创建新的 Pod 来保证副本数量,所以即使只有一个 Pod,我们也应该使用 RC 来管理我们的 Pod。可以说,通过 ReplicationController,Kubernetes 实现了 Pod 的高可用性。

    • ReplicaSet(RS): RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收(已经成为过去时),在 v1.11 版本废弃。

      Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有本质的不同,只是名字不一样,并且 RS 支持集合式的 selector。

      1. Label和Selector: label (标签)是附加到 Kubernetes 对象(比如 Pods)上的键值对,用于区分对象(比如Pod、Service)。 label 旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 label 可以用于组织和选择对象的子集。label 可以在创建时附加到对象,随后可以随时添加和修改。可以像 namespace 一样,使用 label 来获取某类对象,但 label 可以与 selector 一起配合使用,用表达式对条件加以限制,实现更精确、更灵活的资源查找。

        label 与 selector 配合,可以实现对象的“关联”,“Pod 控制器” 与 Pod 是相关联的 —— “Pod 控制器”依赖于 Pod,可以给 Pod 设置 label,然后给“控制器”设置对应的 selector,这就实现了对象的关联。

    • Deployment: 针对RS(RS帮助我们动态更新Pod的副本数,可以通过selector来选择对哪些Pod生效,RS仅支持对Pod的扩容与缩容。)的更高层次的封装,提供了更丰富的部署相关的功能。

      1. 创建ReplicaSet/Pod
      2. 滚动升级/回滚
      3. 平滑扩容和缩容
      4. 暂停与恢复Deployment
  2. 适用有状态服务

    StatefulSet: StatefulSet 中每个 Pod 的 DNS 格式为 statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local

    • serviceName 为 Headless Service 的名字
    • 0…N-1 为 Pod 所在的序号,从 0 开始到 N-1
    • statefulSetName 为 StatefulSet 的名字
    • namespace 为服务所在的 namespace,Headless Servic 和 StatefulSet 必须在相同的 namespace
    • .cluster.local 为 Cluster Domain

    主要特点:

    • 稳定的持久化存储:即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
    • 稳定的网络标志:稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现
    • 有序部署,有序扩展:有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从 0到 N-1,在下一个Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现
    • 有序收缩,有序删除:即从 N-1 到 0

    组成:

    • Headless Service:

      用于定义网络标志(DNS domain)

      Domain Name Server:域名服务
      将域名与 ip 绑定映射关系

      服务名 => 访问路径(域名) => ip

    • volumeClaimTemplate:用于创建 PersistentVolumes

    注意事项:

    • kubernetes v1.5版本以上才支持
    • 所有Pod的Volume必须使用PersistentVolume或者是管理员事先创建好
    • 为了保证数据安全,删除StatefulSet时不会删除Volume
    • StatefulSet需要一个Headless Service来定义DNS domin,需要在StatefulSet之前创建好
  3. 守护进程

    DeamonSet: DaemonSet 保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:

    • 日志收集,比如 fluentd,logstash 等
    • 系统监控,比如 Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond 等
    • 系统程序,比如 kube-proxy, kube-dns, glusterd, ceph 等
  4. 任务/定时任务

    Job: 一次性任务,运行完成后Pod销毁,不再重新启动新容器。

    CronJob: CronJob 是在 Job 基础上加上了定时功能。

服务发现

Service: “Service” 简写 “svc”。Pod 不能直接提供给外网访问,而是应该使用 service。Service 就是把 Pod 暴露出来提供服务,Service 才是真正的“服务”,它的中文名就叫“服务”。

可以说 Service 是一个应用服务的抽象,定义了 Pod 逻辑集合和访问这个 Pod 集合的策略。Service 代理 Pod 集合,对外表现为一个访问入口,访问该入口的请求将经过负载均衡,转发到后端 Pod 中的容器。

Service实现K8S集群内部的网络调用,包括负载均衡(四层负载)(横向流量/东西流量)。

Ingress: Ingress 可以提供外网访问 Service 的能力。可以把某个请求地址映射、路由到特定的 service。

ingress 需要配合 ingress controller 一起使用才能发挥作用,ingress 只是相当于路由规则的集合而已,真正实现路由功能的,是 Ingress Controller,ingress controller 和其它 k8s 组件一样,也是在 Pod 中运行。

Ingress实现将K8S内部服务暴露给外网访问的服务,Ingress-nginx,实现反向代理,负载均衡(七层负载)(纵向流量/南北流量)。

请添加图片描述

存储

Volume: 数据卷,共享 Pod 中容器使用的数据。用来放持久化的数据,比如数据库数据。

CSI: Container Storage Interface 是由来自 Kubernetes、Mesos、Docker 等社区成员联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序。

CSI 规范定义了存储提供商实现 CSI 兼容的 Volume Plugin 的最小操作集和部署建议。CSI 规范的主要焦点是声明 Volume Plugin 必须实现的接口。

特殊类型配置

ConfigMap: 用来放配置,与 Secret 是类似的,只是 ConfigMap 放的是明文的数据,Secret 是密文存放。

Secret: Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。

Secret 有三种类型:

  • Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
  • Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;
  • kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。

DownwardAPI: downwardAPI 这个模式和其他模式不一样的地方在于它不是为了存放容器的数据也不是用来进行容器和宿主机的数据交换的,而是让 pod 里的容器能够直接获取到这个 pod 对象本身的一些信息。

downwardAPI 提供了两种方式用于将 pod 的信息注入到容器内部:

环境变量:用于单个变量,可以将 pod 信息和容器信息直接注入容器内部

volume 挂载:将 pod 信息生成为文件,直接挂载到容器内部中去

其他

Role: Role 是一组权限的集合,例如 Role 可以包含列出 Pod 权限及列出 Deployment 权限,Role 用于给某个 Namespace 中的资源进行鉴权。

RoleBinding: RoleBinding :将 Subject 绑定到 Role,RoleBinding 使规则在命名空间内生效。

3.2.2 资源清单

创建 k8s 的对象都是通过 yaml 文件的形式进行配置的。

3.3 对象规约和状态

对象是用来完成一些任务的,是持久的,是有目的性的,因此 kubernetes 创建一个对象后,将持续地工作以确保对象存在。当然,kubernetes 并不只是维持对象的存在这么简单,kubernetes 还管理着对象的方方面面。每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置,他们分别是 “spec” 和 “status” 。

3.2.1 规约(Spec)

“spec” 是 “规约”、“规格” 的意思,spec 是必需的,它描述了对象的期望状态(Desired State)—— 希望对象所具有的特征。当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。

3.2.2 状态(Status)

表示对象的实际状态,该属性由 k8s 自己维护,k8s 会通过一系列的控制器对对应对象进行管理,让对象尽可能的让实际状态与期望状态重合。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐