一、Kubernetes是什么?

1.1、Kubernetes 的简述

  • Kubernetes(简称“K8s”): 它是Google开源、由CNCF来维护的、用于管理云平台中多个主机上的容器化应用的容器集群管理系统。

  • Kubernetes 是一个分布式的、支持自动化部署、可伸缩、应用容器化管理平台,主要目标是让部署容器化的应用简单并且高效。

  • Kubernetes 核心特点就是:能够自主的管理容器,保证容器按照用户的期望状态运行着(用户无需关心,它会自动去监控、重启、新建,一直提供服务)。

1.2、Kubernetes的主要特征

  • 自动化容器编排:弹性伸缩,Kubernetes可以自动化地管理和编排容器,根据定义的规则或者策略来调度和部署容器应用。

  • 服务发现和负载均衡:提供内置的服务发现机制,自动为应用程序创建网络地址,并通过负载均衡将流量分发到不同的容器实例。

  • 自动扩展和弹性伸缩:Kubernetes可以根据负载情况自动调整容器的数量,实现应用程序的弹性伸缩,确保能够使用所需的资源。

  • 自我修复和健康检查:Kubernetes具有自我修复机制,可以监测容器的健康状态,并在出现故障或异常时自动进行恢复或重启。

  • 配置和存储管理:Kubernetes提供了集中化的配置管理工具,可以轻松管理应用程序的配置信息。支持外部存储系统的挂载,并对外部存储资源进行编排。无论是本地存储、公有云提供的存储服务还是网络存储,都可以作为集群资源使用,提高存储的灵活性。

  • 集中化配置管理和密钥管理:Kubernetes提供了集中化的配置管理工具,管理敏感数据和应用程序配置,提高数据安全性。同时支持密钥管理,用于安全地存储和使用敏感信息。

  • 声明式配置和版本控制:Kubernetes采用声明式配置的方式,通过定义期望的状态来管理应用程序,同时支持版本控制和回滚。

  • 滚动更新和回滚:Kubernetes支持滚动更新,可以逐步替换旧的版本,确保应用程序的平滑升级。出现问题可以回滚到之前的版本。

  • 多租户支持:Kubernetes支持多租户的部署模式,可以将不同的应用程序或团队隔离开来,确保安全性和资源隔离。

  • 跨平台和多云支持:Kubernetes可以在各种云平台和基础设施上运行,包括公有云、私有云和混合云环境。

  • 任务批处理运行:Kubernetes支持一次性任务和定时任务,适用于批量数据处理和分析的场景,满足批处理需求。

  • 可扩展性和插件机制:Kubernetes具有高度可扩展的架构,并提供了插件机制,可以根据需要添加自定义功能或集成其他工具。

二、为什么是 Kubernetes ?

2.1、容器使用出现的问题

随着容器技术的普及,Docker技术成为最主流的容器化应用工具。目前使用Docker容器打包和运行应用程序,已经是业界主流的一种方式。容器化部署方式给带来很多的便利,但是也会出现一些问题,比如:

  • 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器

  • 当并发访问量突然变得很大的时候,怎么样做到横向扩展容器数量

2.2、一系列的解决方案

这些容器管理的问题统称为容器编排问题,当一个容器发生故障,如果系统能自动进行处理并且保证其又能正常的运行,那么容器的管理和使用将会更加的容易。为了解决这些容器编排问题,就产生了一些容器编排的软件:

  • Swarm:Docker 自己的容器编排工具

  • Mesos:Apache 的一个资源统一管控的工具,需要和Marathon结合使用

  • Kubernetes:Google开源的的容器编排工具

2.3、其它编排工具比较

2.3.1、Swarm 与 Mesos

虽然 Docekr Swarm 和 Mesos也是容器编排工具,但它们在某些方面可能不如Kubernetes功能全面。

  • swarm虽然简单易用,集成在Docker引擎中,但对于已经熟悉Docker的用户来说上手容易,而Kubernetes提供了更多的功能和更高的可扩展性。
  • Mesos虽然是一个分布式系统内核,旨在提供高效的资源分配和任务调度,但它可能不如Kubernetes在容器编排和管理方面的集成度高和易用性。
2.3.2、Kubernetes 的优势

那为什么最终是选择 Kubernetes 而不是Swarm或者Memsos 呢?

主要是因为相比之下,Kubernetes提供了更强大和全面的容器编排和管理功能,以下是选择Kubernetes的主要原因:

  • 自动化的部署和伸缩‌:自动化功能可以轻松地部署和伸缩容器化应用,根据实际负载情况调整容器数量,实现弹性伸缩‌。

  • ‌服务发现和负载均衡‌:支持服务发现和负载均衡,通过服务名称访问容器自动分配到健康的容器实例,提高应用的可用性和稳定性‌。

  • ‌自愈性和故障处理‌:强大的自愈性能力,当容器出现故障或节点不可用时,自动重启或迁移容器,确保应用持续可用‌。

  • ‌声明式配置:Kubernetes集群使用声明式配置文件来定义应用程序的状态和部署要求,简化了应用程序的管理和操作‌。

  • ‌配置管理和密钥管理‌:集中化的配置管理工具,可以管理敏感数据和应用程序配置;密钥管理,用于安全地存储和使用敏感信息。

2.4、最终的结论

  • 要全面管理复杂容器化环境,Kubernetes是一个更优的选择。它提供了一个强大的平台,用于自动化容器的部署、扩展和管理,确保应用程序的高可用性和稳定性‌。

  • 虽然Docekr Swaim 和 Mesos 功能不如Kubernetes全面,但是不能说明他们就不能够使用,在实际的情况在,还是有一部分公司在使用这两种编排工具的,特别是早期很多公司就有一些swarm部署的集群应用。

三、Kubernetes 集群架构和组件

3.1、Kubernetes 的集群架构

Kubernetes集群需要建立在多个主机(物理机或者虚拟机)上,它将多个主机的资源抽象出来,组织成一个平台,而后进行统一管理,遵循主从架构模式。

一个集群由至少一个主节点和多个工作节点组成。在Kubernetes集群内部,这些节点又被划分成了两类角色:

  • 主节点 (Master节点) 是集群的控制管理节点,作为整个k8s集群的大脑,负责集群的管理和调度。

  • 从节点 (Node节点) 是实际的工作节点,工作节点则运行应用容器,负责集群的实际容器应用的运行。

3.2、Kubernetes 的核心组件

3.2.1、Master节点核心组件
  • kube-apiserver: 集群管理和资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制
  • kube-controller-manager: 负责管理控制器的核心组件,管理集群各种资源,保证资源处于预期的状态
  • kube-scheduler: 主要负责资源的调度,根据集群调度算法或用户需求限制将Pod分配到对应的节点上
  • etcd: 存储和同步配置数据的分布式键值存储系统,负责存储集群的所有配置信息和保存当前的集群状态
3.2.2、Node节点核心组件
  • kubelet: 运行在节点上的代理程序,用于管理节点上的容器,与 Master通信以接收指令并汇报节点状态。
  • kube-proxy: 集群中节点上的网络代理,用于快速转发和代理请求,实现集群内部的服务发现和负载均衡
  • container runtime: 容器运行时,下载镜像和运行容器,为容器分配和隔离资源,以及管理容器的整个生命周期
3.2.3、集群的其它插件
  • CoreDNS: 为集群提供DNS解析,使得在集群内部可以使用容器名称或者SVC别名的方式,访问集群中的应用程序和服务
  • CNI: 集群的网络插件接口,用于实现容器之间的通信和网络连接。它支持多种网络插件,如 Calico、Flannel 、Weave 和 Canal等
  • Dashboard (可选): 集群的WEB界面管理工具,让用户可以不用令行操作就能轻松地监控和管理集群中的资源对象和应用程序

四、Kubernetes 的工作流程

4.1、创建应用的工作流程

  • 用户通过客户端发送请求给集群的 API Server,API Server 先将用户的请求信息写入到 Etcd 存储中,再去找Controller Manager 创建对应的 Pod

  • Controller Manager 通过 API Server 去读取 Etcd 里的用户请求信息,根据请求去预设的模板,并模板写入到 Etcd 中,再根据模板创建 Pod

  • Controller Manager 通过 API Server 去找到 Scheduler 调度 Pod,为新创建的 Pod 选择 Node 节点

  • Scheduler 通过API Server 在 Etcd 存储中读取 Node 节点的资源信息,通过预算策略和优选策略,挑选最优的 Node 节点,并把 Pod 调度到这个节点运行

  • Scheduler 确定了调度的节点后,通过 API Server 去找到对应 Node 节点上的 Kublet,由 Kublet 创建 Pod

  • Kublet 和容器引擎交互,管理着容器的生命周期,还监控 Node 节点上的资源信息、Pod状态等,将这些通过 API Server 存储到 Etcd 中

  • Kube-Proxy 创建网络规则,制定转发规则。创建 Service,把用户的请求负载均衡转发到关联的 Pod 上

4.2、关于节点的选取策略

  • 预算策略:将所有node节点的剩余资源和pod所需的资源对比,找出符合pod资源需求的node节点

  • 优选策略:预算策略筛选后的node节点被交给优选策略。通过cpu负载,内存剩余等因素,找出最合适的node节点

4.3、终止应用的工作过程

  • 用户向 API Server发送删除Pod对象的命令, API Server中的Pod对象信息随着时间的退役而更新
  • 在宽限期内(默认30秒),Pod被视为Dead,将Pod标记为Terminating状态
  • Kubelet在监控到Pod对象转为Terminating状态的同时启动Pod关闭过程,
  • 端点控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的Service资源的端点列表中移除
  • 如果当前Pod对象定义了PreStop钩子处理器,则在其标记为Terminating后即会以同步的方式启动执行,
  • Pod对象的容器进程收到停止信号,宽限期结束后,若Pod中还存在仍在运行的进程,那么Pod对象会收到吉利终止的信号
  • Kubelet请求API Server将此Pod资源的款限制设置为0从而完成删除操作,此时Pod对于用户已不可见

五、Kubernetes 的核心概念

5.1、Kubernetes 的资源对象

  • Kubernetes 包含多种类型的资源对象:Pod、 Label、Selector 、Replication Controller、Service 等等

  • Kubernetes 的资源对象都可以通过 kubectl工具进行增、删、改、查等操作,并将其保存在etcd中持久化存储

  • Kubernets 通过对比 Etcd 存储里保存的资源期望状态与当前的实际资源状态的差异,来实现自动控制和自动纠错

5.2、主要核心的概念

5.2.1、Pod

Pod是集群创建或部署的最小的基本单位,一个Pod 代表集群上正在运行的一个进程

  • 一个Pod由一个或多个容器组成,Pod中容器共享网络、存储和计算资源,在同一台Docker主机上运行

  • 一个Pod里可以运行多个容器,即边车模式(sideCar)。在生产环境中一般都是单个容器或者具有强关联互补的多个容器组成一个Pod

  • 同一个Pod之间的容器可以通过localhost 互相访问,并且可以挂载Pod内所有的数据卷

  • 但是不同的Pod之间的容器不能用localhost访问,也不能挂载其他Pod的数据卷

5.2.2、Pod Controller
  • Pod控制器是用来保证在K8S里启动的Pod,应始终按照用户的预期运行(副本数、生命周期、健康状态检查等)

  • K8S内提供了众多的Pod 控制器,常用的有以下几种:

    • Deployment:无状态应用部署。Deployment 的作用是管理和控制Pod和Replicaset, 管控它们运行在用户期望的状
    • Replicaset:确保预期的 Pod 副本数量。ReplicaSet 的作用就是管理和控制 Pod,但是,ReplicaSet 受控于 Deployment
    • Daemonset:确保所有节点运行同一类 Pod,保证每个节点上都有一个此类 Pod 运行,通常用于实现系统级后台任务
    • Statefulset:有状态应用部署。本质上是Deployment的一种变体,适用于需要持久化存储、唯一标识和有序部署的场景
    • Job: 一次性的任务。根据用户的设置,Job管理的Pod把任务成功完成就自动退出了
    • CronJob: 是一种用于定期执行任务的资源对象,用来完成周期性计划性任务
5.2.3、Label

标签,是K8S 便于分类管理资源对象,通过给指定的资源对象捆绑一个或多个不同的 Label,来实现多维度的资源分组管理

  • Label 可以附加到各种资源对象上,例如Node、Pod、Service、 RC等,用于关联对象、查询和筛选

  • 一个 Label 是一个 Key-Value 的键值对,其中 Key 与 Value 由用户自己指定

  • 一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象中除

5.2.4、Label selector

Label selector --- 标签选择器

  • 给资源对象定义一个Label, 就相当于给它打了一个标签,而后可以通过Label selector 查询和筛选拥有某些 Label的资源对象
  • 标签选择器目前有两种:基于等值关系(等于、不等于)和基于集合关系(属于、不属于、存在)
5.2.5、Service

K8S虽然每个Pod会被分配一个单独的IP地址,但由于Pod是有生命周期的,随时可能会因为业务的变更,导致这个IP地址也会随着Pod 的销毁而消失

Service就是用来解决这个问题:

  • K8S中的Service 并不是我们常说的“服务”的含义,而更像是网关层,可以看作一组提供相同服务的Pod的对外访问接口、流量均衡器,Service作用于哪些Pod 是通过标签选择器来定义的。

  • 在K8S集群中,Service 可以看作一组提供相同服务的Pod 的对外访问接口。客户端需要访问的服务就是Service 对象。每个Service都有一个固定的虚拟IP (这个IP也被称为Cluster IP) ,自动并且动态地绑定后端的Pod, 所有的网络请求直接访问Service 的虚拟IP,Service会自动向后端做转发。

  • Service除了提供稳定的对外访问方式之外,还能起到负载均衡(Load Balance) 的功能,自动把请求流量分布到后端所有的服务上,service可以做到对客户透明地进行水平扩展(scale)。

  • Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口, 真正做到了“微服务”。比如我们的一个服务A,部署了3个副本,也就是3个Pod;对于用户来说,只需要关注一个Service 的入口就可以,而不需要操心究竞应该请求哪一个Pod。

  • 优势非常明显:一方面外部用户不需要感知因为Pod上服务的意外崩溃、 K8S 重新拉起Pod 而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化。EndPoint 自动发现这些Pod IP Service再把IP地址加入到配置当中进行动态转发

5.2.6、Ingress
  • Service主要负责K8S 集群内部的网络拓扑,那么集群外部访问集群内部就需要Ingress了。
  • Ingress是整个K8S集群的接入层,负责集群内外通讯
    • Ingress是K8S 集群里工作在OSI网络参考模型下,第7层的应用,对外暴露的接口,典型的访问方式是 http/https
    • Service只能进行第四层的流量调度,表现形式是ip+port。Ingress则可以调度不同业务域、不同URL访问路径的业务流量
5.2.7、Volume

数据卷,为Pod内的容器提供存储

  • Volume是抽象出来的对象,它被定义在Pod上,然后被一个Pod容器挂载到具体的文件目录下
  • kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储
  • Volume的生命周期和Pod中容器的生命周期无关,当容器终止时,Volume中的数据也不会丢失
  • kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷
  • k8s中常见的Volume类型:
    • 常规存储: Empty、HostPath
    • 高级存储:PV、PVC
    • 配置存储:ConfigMap、Secret
    • 其它存储:NFS、CIFS、CEPH 等
5.2.8、Namespace

对集群进行逻辑上隔离K8S 内各种“资源"的方法,这就是 NameSpace --- 命名空间

  • NameSpace是为了把一个K8S集群划分为若千个资源不可共享的虚拟集群组而诞生的

  • 不同NameSpace 内的“资源”名称可以相同,相同NameSpace 内的同种“资源”, “名称”不能相同

  • 集群默认的NameSpace : default、 kube-system、 kube-public ,查询特定“资源”要带上相应的 NameSpace