Kubernetes那点事儿——初识K8s

K8s核心概念

  • 前言
  • 一、Kubernetes 是什么
  • 二、Kubernetes 能做什么
  • 三、k8s集群及组件
    • master组件
    • node组件
    • etcd数据库
  • 四、资源概念
  • 五、番外
    • kubelet
    • K8s设计思想
    • Kubernetes 项目核心功能全景图
    • 声明式 API
    • K8s本质


前言

了解K8s,讲述K8s核心概念


一、Kubernetes 是什么

https://kubernetes.io/zh-cn/docs/concepts/overview/what-is-kubernetes/

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。

Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。

二、Kubernetes 能做什么

大家都知道容器取代了vm,首次让我们实现了跨云跨平台甚至是跨OS的迁移(部署、发布)。避免了开发到测试到预产到上线这个过程中因环境因素而出现的种种问题。下面是容器带给我们的好处:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
  • 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度

那么问题来了,容器已经为我们带来那么多好处,为什么还要K8s呢?

容器是打包和运行应用程序的好方式,但不是管理服务最好的方式。为了满足服务的连续性、扩容需求、故障转移及多容器管理等需求,就出现了k8s

  • 服务发现和负载均衡

    Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  • 存储编排

    Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚

    你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  • 自动完成装箱计算

    Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来为容器分配资源。

  • 自我修复

    Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理

    Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

Kubernetes那点事儿——初识K8s_第1张图片

三、k8s集群及组件

Kubernetes那点事儿——初识K8s_第2张图片

master组件

  • kube-apiserver

    Kubernetes API,集群的统一入口,各组件协调者,以RESTful API提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储

  • kube-controller-manager

    kube-controller-manager 负责运行控制器进程。一个资源对应一个控制器,而

    ControllerManager就是负责管理这些控制器的。包括
      - 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
      - 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
      - 端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即加入 Service 与 Pod)
      - 服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌

  • kube-scheduler

    根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上

  • etcd

    分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息

node组件

  • kubelet

    运行在每个node上,kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器

  • kube-proxy

    运行在每个node上,在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作

  • Container Runtime

    容器运行环境是负责运行容器的软件。目前使用比较流行的容器docker、containerd

etcd数据库

etcd是兼顾一致性与高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库

四、资源概念

大家都听说过一句话,在Java中一切皆对象,而在K8s中一切皆资源。在k8s中所有能被操作的东西都是K8s的资源。

  • Master(管理节点) :主要负责资源调度,控制副本,和提供统一访问集群的入口。
  • Node(应用节点):业务Pod运行节点,由Master管理,并汇报容器状态给Master,同时根据Master要求管理容器生命周期。
  • Node IP:Node节点物理ip,也就是主机ip,真实存在的物理网络。
  • Pod:Pod直译是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod)。在k8s中我们不会直接操作容器,而是把容器包装成Pod再进行管理 Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通信。Pod是k8s进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。
  • pause容器:每个Pod中都有一个pause容器,pause容器做为Pod的网络接入点,Pod中其他的容器会使用容器映射模式启动并接入到这个pause容器。属于同一个Pod的所有容器共享网络的namespace。
  • Pod Volume:类似Docker Volume
  • Event:事件记录,记录了事件最早产生的时间、最后重复时间、重复次数、发起者、类型,以及导致此事件的原因等信息。Event通常关联到具体资源对象上,是排查故障的重要参考信息。
  • Pod IP:Pod的ip,根据CNI网络插件配置的网络,是虚拟ip
  • Namespace:命名空间将资源对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户。
  • Replica Set:真正实现保证副本数量一致性功能的一个组件,确保任何给定时间指定的Pod副本数量
  • Deployment:最常用的无状态应用控制器,是一个更高层次的API对象,它管理ReplicaSets和Pod
  • Service:为Pod提供统一访问入口,Service定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解后台Pod是如何运行
  • Cluster IP:仅仅作用于Kubernetes Servcie这个对象,并由Kubernetes管理和分配IP地址; 无法被Ping,因为没有一个"实体网络对象"来响应,只能结合Service Port组成一个具体的通信端口。
  • Label:对K8s资源做标记。Kubernetes中的任意API对象都是通过Label进行标识,Label的实质是一系列的K/V键值对。Label是Replication Controller和Service运行的基础,二者通过Label来进行关联Node上运行的Pod
  • Endpoint:ip+port,应用监听的真实ip及port
  • StatefulSet:主要用来部署有状态应用,能够保证 Pod 的每个副本在整个生命周期中名称是不变的,同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除
  • PV/PVC:对存储资源创建和使用的抽象,使得存储作为集群中的资源管理。让用户不需要关心具体的Volume实现细节
  • configmap:主要用于应用配置存储,数据实际会存储在K8s中(Etcd)Etcd,然后通过创建Pod时引用该数据
  • Secret:主要用于敏感数据存储如docker仓库秘钥,所有的数据要经过base64编码
  • DaemonSet:确保全部(或者某些)节点上运行一个 Pod 的副本。如网络插件、监控Agent

五、番外

kubelet

kubelet 主要负责同容器运行时(比如 Docker 项目)打交道。这个交互依赖的是 CRI(Container Runtime Interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作,比如:启动一个容器需要的所有参数。 k8s 项目并不关心你部署的是什么容器运行时、使用的什么技术实现,只要你的这个容器运行时能够运行标准的容器镜像,它就可以通过实现 CRI 接入到 k8s 项目当中。

  OCI:
  具体的容器运行时,比如 Docker 项目,一般通过 OCI 这个容器运行时规范同底层的 Linux 操作系统进行交互,即:把 CRI 请求翻译成对 Linux 操作系统的调用(操作 Linux Namespace 和 Cgroups 等)

  Device Plugin
  kubelet 通过 gRPC 协议同一个叫作 Device Plugin 的插件进行交互。这个插件是 Kubernetes 项目用来管理 GPU 等宿主机物理设备的主要组件,也是基于 Kubernetes 项目进行机器学习训练、高性能作业支持等工作必须关注的功能。

  CNI CSI
  kubelet 的另一个重要功能是调用网络插件和存储插件为容器配置网络和持久化存储。这两个插件与 kubelet 进行交互的接口,分别是 CNI(Container Networking Interface)和 CSI(Container Storage Interface)

K8s设计思想

k8s 项目最主要的设计思想是从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地。

比如,k8s 项目对容器间的"访问"进行了分类,首先总结出了一类非常常见的"紧密交互"的关系,即:这些应用之间需要非常频繁的交互和访问;又或者,它们会直接通过本地文件进行信息交换。

在常规环境下,这些应用往往会被直接部署在同一台机器上,通过 Localhost 通信,通过本地磁盘目录交换文件。而在 Kubernetes 项目中,这些容器则会被划分为一个"Pod",Pod 里的容器共享同一个 Network Namespace、同一组数据卷,从而达到高效率交换信息的目的。

而对于另外一种更为常见的需求,比如 Web 应用与数据库之间的访问关系,Kubernetes 项目则提供了一种叫作"Service"的服务。像这样的两个应用,往往故意不部署在同一台机器上,这样即使 Web 应用所在的机器宕机了,数据库也完全不受影响。可是,对于一个容器来说,它的 IP 地址等信息不是固定的,那么 Web 应用又怎么找到数据库容器的 Pod 呢?

所以,Kubernetes 项目的做法是给 Pod 绑定一个 Service 服务,而 Service 服务声明的 IP 地址等信息是"终生不变"的。这个Service 服务的主要作用,就是作为 Pod 的代理入口,从而代替 Pod 对外暴露一个固定的网络地址。

这样,对于 Web 应用的 Pod 来说,它需要关心的就是数据库 Pod 的 Service 信息。Service 后端真正代理的 Pod 的 IP 地址、端口等信息的自动更新、维护,则是 Kubernetes 项目的职责。

Kubernetes 项目核心功能全景图

Kubernetes那点事儿——初识K8s_第3张图片

声明式 API

声明式API是Kubernetes 最核心的设计理念。

Kubernetes 项目并没有像其他项目那样,为每一个管理功能创建一个指令,然后在项目中实现其中的逻辑。这种做法,的确可以解决当前的问题,但是在更多的问题来临之后,往往会力不从心。

相比之下,在 Kubernetes 项目中所推崇的使用方法是:

  首先,通过一个"编排对象",比如 Pod、Job、CronJob 等,来描述你试图管理的应用;

  然后,再为它定义一些"服务对象",比如 Service、Secret、Horizontal Pod Autoscaler(自动水平扩展器)等。这些对象,会负责具体的平台级功能。

这种使用方法,就是"声明式 API"。这种 API 对应的"编排对象"和"服务对象",都是Kubernetes 项目中的 API 对象(API Object)。

K8s本质

K8s编排能力很强。可以按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。但Kubernetes 项目的本质,不仅限于为用户提供一个具有普遍意义的容器编排工具。真正的价值,在于提供了一套基于容器构建分布式系统的基础依赖。

你可能感兴趣的:(Kubernetes,kubernetes,docker,容器)