Kubernetes(v1.21)简介

第一章:背景

1.1 部署方式的演变

file

传统部署时代:

  • ① 在物理机服务器上运行应用程序。

  • ② 无法为应用程序定义资源边界。

  • ③ 导致资源分配问题。

如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况下,会导致其它应用程序的性能下降。一种解决方案就是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展,并且维护许多物理服务器的成本也很高。

虚拟化部署时代:

  • ① 作为解决方案,引入了虚拟化。

  • ② 虚拟化技术允许在单个物理服务器的 CPU 上运行多个虚拟机(VM)。

  • ③ 虚拟化允许应用程序在 VM 之间隔离,并提供一定程序上的安全。

  • ④ 一个应用程序的信息不会被另一个应用程序随意访问。

  • ⑤ 虚拟化技术能够更好的利用物理服务器上的资源。

  • ⑥ 因为可以很轻松的添加或更新应用程序,所以可以实现更好的可伸缩性,并且可以降低硬件成本。

  • ⑦ 每个 VM 都是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括自己的操作系统等。

缺点:虚拟层冗余,导致资源浪费和性能下降。

容器化部署时代:

  • ① 容器类似于 VM ,但是可以在应用程序之间共享操作系统。

  • ② 容器被认为是轻量级的。

  • ③ 容器和 VM 类似,具有自己的文件系统、CPU 、内存、进程空间等。

  • ④ 由于容器和基础架构分离,因为可以很方便的进行跨云和跨 Linux 发行版进行移植。

  • ⑤ 参照 Docker 的隔离原理(namespace 6 项隔离和 cgroups 8 项资源限制)。

容器的优势:

  • 敏捷性:敏捷应用程序的创建和部署;和使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。

  • 及时性:持续开发、集成和部署;通过快速简单的回滚(由于镜像的不可变性),支持可靠且频繁的容器镜像的构建和部署。

  • 解耦性:关注开发和运维的分离;在构建、发布时创建应用程序的容器镜像,而不是在部署的时候,从而将应用程序和基础架构分离。

  • 可观测性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其它指标信号。

  • 跨平台:跨开发、测试和生产的环境一致性;在便捷式的计算机上和在云上相同的运行。

  • 可移植:跨云和 Linux 发行版本的可移植性;可以在 Ubuntu、CentOS、RedHat、本地、Google Kubernetes Engine 和其他任何地方运行。

  • 简易性:以应用程序为中心的管理;提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。

  • 大分布式:松散耦合、分布式、弹性、解放的微服务;应用程序被分解成较小的独立部分,并且可以动态的部署和管理 --- 而不是在一台大型单机上整体运行(垂直扩展是有上限的)。

  • 隔离性:资源隔离;可预测应用程序性能。

  • 高效性:资源利用;高效率和高密度。

1.2 容器化问题

  • ① 弹性的容器化应用管理。

  • ② 强大的故障转移能力。

  • ③ 高性能的负载均衡访问机制。

  • ④ 便捷的扩展。

  • ⑤ 自动化的资源监测。

  • ……

1.3 为什么使用 Kubernetes(简称:k8s)?

  • 容器是打包和运行应用程序的最佳方式,在生产环境中,我们需要管理运行应用程序的容器,并且确保这些容器不会停机。如果一个容器发生了故障,则需要手动启动另一个容器,太麻烦了;如果有一个系统能够帮助我们处理这些行为,是不是会很方便?
  • Kubernetes 就能解决上面提出的一系列的问题。Kubernetes 为我们提供了一个可弹性运行的分布式系统的框架,Kubernetes 可以满足我们的扩展要求、故障转移、部署模式等,如:Kubernetes 可以轻松管理系统的 Canary(金丝雀) 部署。
  • Kubernetes 为我们提供下面的功能:
    • 服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大,Kubernetes 可以负载均衡并分配网络流量,从而使得部署稳定。

    • 存储编排:Kubernetes 允许我们自动挂载自己选择的存储系统,如:本地存储、公有云提供商等。

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

    • 自动完成装箱计算:Kubernetes 允许我们指定每个容器所需要的 CPU 和内存(RAM)。当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。

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

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

    • ……

第二章:Kubernetes 简介

2.1 概述

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

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

2.2 Kubernetes 不是什么?

  • Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。
  • 由于 Kubernetes 在容器级别而不是在硬件级别运行,它提供了 PaaS 产品共有的一些普遍适用的功能, 例如部署、扩展、负载均衡、日志记录和监视。
  • 但是,Kubernetes 不是单体系统,默认解决方案都是可选和可插拔的。 Kubernetes 提供了构建开发人员平台的基础,但是在重要的地方保留了用户的选择和灵活性。
  • Kubernetes:
    • 不限制支持的应用程序类型:Kubernetes 旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。 如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上很好地运行。

    • 不部署源代码,也不构建你的应用程序:持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。

    • 不提供应用程序级别的服务作为内置服务,例如中间件(例如,消息中间件)、 数据处理框架(例如,Spark)、数据库(例如,mysql)、缓存、集群存储系统 (例如,Ceph)。这样的组件可以在 Kubernetes 上运行,并且/或者可以由运行在 Kubernetes 上的应用程序通过可移植机制(例如, 开放服务代理)来访问。

    • 不要求日志记录、监视或警报解决方案。 它提供了一些集成作为概念证明,并提供了收集和导出指标的机制。

    • 不提供或不要求配置语言/系统(例如 jsonnet),它提供了声明性 API, 该声明性 API 可以由任意形式的声明性规范所构成。

    • 不提供也不采用任何全面的机器配置、维护、管理或自我修复系统。

    • 此外,Kubernetes 不仅仅是一个编排系统,实际上它消除了编排的需要。 编排的技术定义是执行已定义的工作流程:首先执行 A,然后执行 B,再执行 C。 相比之下,Kubernetes 包含一组独立的、可组合的控制过程, 这些过程连续地将当前状态驱动到所提供的所需状态。 如何从 A 到 C 的方式无关紧要,也不需要集中控制,这使得系统更易于使用 且功能更强大、系统更健壮、更为弹性和可扩展。

第三章:Kubernetes 集群原理

2.1 工作原理

file

  • Master 节点(Control Plane【控制面板】):Master 节点控制整个集群。
    • Controller Manager:控制管理器。

    • etcd:键值数据库,类似于 Redis。

    • scheduler:调度器。

    • api-server:api网关(所有的控制都需要通过api-server)。

    • Node 节点(worker工作节点):

    • kubelet(监工):每一个 Node 节点上必须安装的组件,负责交互 master 的 api-server 以及当前机器的应用启停等,在 master 机器就是 master 的小助手。每一台机器真正干活的都是这个 Kubelet 。

    • kube-proxy:代理网络。

  • Pod:
    • docker run 启动的是一个 container(容器),容器是 Docker 的基本单位,一个应用就是一个容器。
    • kubectl run 启动的是一个应用称为一个 Pod ,Pod 是 Kubernetes 的基本单位。
    • Pod 是对容器的再一次封装。
    • Pod 类似于 Java 日志体系中的 Slf4j ,而 Docker 中的容器类似于 Java 日志体系中的 Logback 等日志实现。
    • 一个容器往往代表不了一个基本应用,如:博客系统(WordPress,PHP + MySQL);但是一个 Pod 可以包含多个 Container,一个 Pod 可以代表一个基本的应用。

2.2 组件交互原理

file

  • 如何让 Kubernetes 部署是一个 Tomcat 应用?

  • 0 :开机默认所有节点的 kubelet 、master 节点的s cheduler(调度器)、controller-manager(控制管理器)一直监听 master 的 api-server 发来的事件变化。

  • 1 :程序员使用命令行工具: kubectl ; kubectl create deploy tomcat --image=tomcat8(告诉 master 让集群使用 tomcat8 镜像,部署一个 tomcat 应用)。

  • 2 :kubectl 命令行内容发给 api-server,api-server 保存此次创建信息到 etcd 。

  • 3 :etcd 给 api-server 上报事件,说刚才有人给我里面保存一个信息。(部署Tomcat[deploy])

  • 4:controller-manager 监听到 api-server 的事件,是 (部署Tomcat[deploy])。

  • 5:controller-manager 处理这个 (部署Tomcat[deploy])的事件。controller-manager 会生成 Pod 的部署信息【pod信息】。

  • 6:controller-manager 把 Pod 的信息交给 api-server ,再保存到 etcd 。

  • 7:etcd 上报事件【pod信息】给 api-server 。

  • 8:scheduler 专门监听 【pod信息】 ,拿到 【pod信息】的内容,计算,看哪个节点合适部署这个 Pod【pod 调度过后的信息(node: node-02)】。

  • 9:scheduler 把 【pod 调度过后的信息(node: node-02)】交给 api-server 保存给 etcd 。

  • 10:etcd 上报事件【pod调度过后的信息(node: node-02)】,给 api-server 。

  • 11:其他节点的 kubelet 专门监听 【pod 调度过后的信息(node: node-02)】 事件,集群所有节点 kubelet 从 api-server 就拿到了 【pod调度过后的信息(node: node-02)】 事件。

  • 12:每个节点的 kubelet 判断是否属于自己的事情;node-02 的 kubelet 发现是他的事情。

  • 13:node-02 的 kubelet 启动这个 pod。汇报给 master 当前启动好的所有信息。

质量拉满,涵盖高质量开源项目,欢迎来访,博主个人开源博客地址: https://www.chengke.net