Kubernetes 系统化学习之 基本概念篇(一)

2,658 阅读16分钟

Kubernetes 系统化学习之 基本概念篇(一)
Kubernetes 系统化学习之 POD原理篇(二)
Kubernetes 系统化学习之 资源清单篇(三)
Kubernetes 系统化学习之 服务发现篇(四)
Kubernetes 系统化学习之 持久存储篇(五)
Kubernetes 系统化学习之 集群调度篇(六)
Kubernetes 系统化学习之 集群安全篇(七)

1. 从 Docker 到 Kubernetes

随着容器的火爆,越来越多的业务系统利用容器来搭建部署,像 Docker 之类的容器引擎,部署少量还可以,但随着业务的增多,服务越来越多,动辄就要使用成百上千的容器,要管理这么多容器,Docker 们就力不从心了。

  • 百上千的容器管理问题?
  • 分布式环境下容器如何通信?
  • 如何协调和调度这些容器?
  • 如何在升级应用程序时不会中断服务?
  • 如何监视应用程序的运行状况?
  • 如何批量重新启动容器里的程序?

虽然 Docker 已经很强大了,但是在实际使用上还是有诸多不便,比如集群管理、资源调度、文件管理等等。那么在这样一个百花齐放的容器时代涌现出了很多解决方案,比如 Mesos、Swarm、Kubernetes 等等,其中谷歌开源的 Kubernetes 是作为老大哥的存在。

Kubernetes(简称 K8s,其中8代指中间的8个字符),是一个全新的基于容器技术的分布式架构方案。K8S 最初是由 Google 开发的,后来捐赠给了 CNCF(云原生计算基金会,隶属 Linux 基金会)。K8S 是 Google 十几年来大规模应用容器技术的经验积累和升华的重要成果,确切的说是 Google 一个久负盛名的内部使用的大规模集群管理系统——Borg 的开源版本,其目的是实现资源管理的自动化以及跨数据中心的资源利用率最大化。

Kubernetes 具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建的智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多力度的资源配额管理能力。

同时,Kubernetes 提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节,不仅是一个全新的基于容器技术的分布式架构解决方案,还是一个一站式的完备分布式系统开发和支撑平台。

0423d49046d84beda60cafacc1390c55.png

Kubernetes 和 Docker 们不是替代关系,而是配合关系。K8S 仍然会使用 Docker 之类的容器引擎(Docker、Containerd、RKT、CRI-O 等),来对容器进行生命周期管理。Kubernetes 已经成为容器编排领域的王者,它是基于容器的集群编排引擎,具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。

Kubernetes 解决的核心问题

  1. 服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果到容器的流量很大,Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

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

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

  4. 自动二进制打包:Kubernetes 允许您指定每个容器所需 CPU 和内存(RAM)。当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。

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

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

Kubernetes 的出现不仅主宰了容器编排的市场,更改变了过去的运维方式,不仅将开发与运维之间边界变得更加模糊,而且让 DevOps 这一角色变得更加清晰,每一个软件工程师都可以通过 Kubernetes 来定义服务之间的拓扑关系、线上的节点个数、资源使用量并且能够快速实现水平扩容、蓝绿部署等在过去复杂的运维操作。

2. Kubernetes 组件结构

Kubernetes 遵循非常传统的 客户端/服务端 的架构模式,客户端可以通过 RESTful 接口或者直接使用 kubectl 与 Kubernetes 集群进行通信,这两者在实际上并没有太多的区别,后者也只是对 Kubernetes 提供的 RESTful API 进行封装并提供出来。

每一个 Kubernetes 集群都是由一组 Master 节点和一系列的 Worker 节点组成,其中 Master 节点主要负责存储集群的状态并为 Kubernetes 对象分配和调度资源。

src=http___5b0988e595225.cdn.sohucs.com_images_20180706_2cccb2314ff6484198580d08119cc78e.jpeg&refer=http___5b0988e595225.cdn.sohucs.webp

主节点服务 - Master 架构

作为管理集群状态的 Master 节点,它主要负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移。Master 节点内部由下面几个组件构成:

  • API Server: 负责处理来自用户的请求,其主要作用就是对外提供 RESTful 的接口,包括用于查看集群状态的读请求以及改变集群状态的写请求,也是唯一一个与 etcd 集群通信的组件。
  • Etcd: 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
  • Scheduler: 主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
  • Controller Manager: 在主节点上运行控制器的组件,从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:节点控制器(负责在节点出现故障时进行通知和响应)、副本控制器(负责为系统中的每个副本控制器对象维护正确数量的 Pod)、端点控制器(填充端点 Endpoints 对象,即加入 Service 与 Pod))、服务帐户和令牌控制器(为新的命名空间创建默认帐户和 API 访问令牌)。

工作节点服务 - Node 架构

其他的 Worker 节点实现就相对比较简单了,它主要由 kubelet 和 kube-proxy 两部分组成。

  • Kubelet: 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等。
  • KuberProxy: 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上同一类标签的 Pod。kube-proxy 实质就是通过操作防火墙规则(iptables或者ipvs)来实现 Pod 的映射。
  • Container Runtime: 容器运行环境是负责运行容器的软件,Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI(容器运行环境接口)。

src=http___img.jbzj.deiniu.com_file_images_article_202204_202204060809578.jpg&refer=http___img.jbzj.deiniu.webp

ApiServer

ApiServer 提供了 k8s 各类资源对象(Pod, RC, Service等)的增删改查及 watch 等 HTTP Rest 接口,是整个系统的数据总线和数据中心。

  • 提供了集群管理的 REST API 接口(包括认证授权、数据校验以及集群状态变更);
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd);
  • 是资源配额控制的入口;
  • 拥有完备的集群安全机制。

f16ee3c84abf4bf3aa84d6b3443968ad.png

ControllerManager

Controller Manager 作为集群内部的管理控制中心,负责集群内的 Node、Pod、Endpoint、Namespace、ServiceAccount、ResourceQuota 的管理,每个 Controller 通过 API Server 提供的接口实时监控整个集群的每个资源对象的当前状态,当发生各种故障导致系统状态发生变化时,会尝试将系统状态修复到“期望状态”。例如:当某个 Node 意外宕机时,Controller Manager 会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。

几乎每种特定资源都有特定的 Controller 维护管理以保持预期状态,而 Controller Manager 的职责便是把所有的 Controller 聚合起来,提供基础设施降低 Controller 的实现复杂度,启动和维持 Controller 的正常运行。

image-20200725172912964.png

Scheduler

Scheduler 组件是 kubernetes 中的核心组件之一,主要负责 pod 资源对象的调度工作,具体来说,Scheduler 组件负责根据调度算法(包括预选算法和优选算法)将未调度的pod调度到合适的最优的node 节点上。

Scheduler 的大致组成和处理流程如下图,Scheduler 对 pod、node 等对象进行了 list/watch,根据informer 将未调度的 pod 放入待调度 pod 队列,并根据 informer 构建调度器 cache(用于快速获取需要的node等对象),然后 sched.scheduleOne 方法为 kube-scheduler 组件调度 pod 的核心处理逻辑所在,从未调度 pod 队列中取出一个 pod,经过预选与优选算法,最终选出一个最优 node,上述步骤都成功则更新 cache 并异步执行 bind 操作,也就是更新 pod 的 nodeName 字段,失败则进入抢占逻辑,至此一个 pod 的调度工作完成。

17b3c296414e44139ecaedc4c82ab4d4.png

Etcd

在 kubernetes 集群中,Etcd 用于保存集群所有的网络配置和对象的状态信息。

Etcd 是采用 Go 语言编写的一个分布式 key-value 存储,它通过 Raft 协议进行 leader 选举和数据备份,对外提供高可用的数据存储,能有效应对网络问题和机器故障带来的数据丢失问题。同时它还可以提供服务发现、分布式锁、分布式数据队列、分布式通知和协调、集群选举等功能。

Etcd 主要解决的是分布式系统中数据一致性的问题,而分布式系统中的数据分为控制数据和应用数据,Etcd 处理的数据类型为控制数据,对于很少量的应用数据也可以进行处理。

src=http___static001.infoq.cn_resource_image_fd_0f_fd17db8d2165fb60009b77bd4810410f.jpg&refer=http___static001.infoq.webp

Kubectl

Kubectl 是官方的 CLI 命令行工具,用于与 ApiServer 进行通信,将用户在命令行输入的命令,组织并转化为 ApiServer 能识别的信息,进而实现管理 k8s 各种资源的一种有效途径。

kubectl version

6dc29cae13274e5590c6579fe03cd902.png

KuberProxy

KuberProxy 是 Kubernetes 的核心组件,部署在每个 Node 节点上,它是实现 Kubernetes Service 的通信与负载均衡机制的重要组件; KuberProxy 负责为 Pod 创建代理服务,从 ApiServer 获取所有 server 信息,并根据 server 信息创建代理服务,实现 server 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络。

KuberProxy 有三种模式:

  • Userspace 模式(k8s版本为1.2之前默认模式):KuberProxy 在用户空间监听一个端口,所有服务通过 iptables 转发到这个端口,然后在其内部负载均衡到实际的 Pod。该方式最主要的问题是效率低,有明显的性能瓶颈。
  • 使用 Iptables 模式(k8s版本为1.2之后默认模式):iptables 的方式则是利用了 linux 的 iptables 的 nat 转发进行实现,利用 iptables 的 DNAT 模块,实现了 Service 入到 Pod 实际地址的转换。 该方式最主要的问题是在服务多的时候产生太多的 iptables 规则,非增量式更新会引入一定的时延,大规模情况下有明显的性能问题。
  • IPVS:v1.11 新增了 ipvs 模式(v1.8 开始支持测试版,并在 v1.11 GA)。 IPVS 是 LVS 的负载均衡模块,亦基于 netfilter,但比 iptables 性能更高,具备更好的可扩展性,采用增量式更新,并可以保证 service 更新期间连接保持不断开。

26273155-a7c975551a8124bf.png

CoreDNS

CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS,在 Kubernetes1.12 版本之后成为了默认的 DNS 服务。 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。

CoreDNS 在 K8S 中的用途,主要是用作服务发现,也就是服务(应用)之间相互定位的过程。在 K8S 中,用 Service 资源代理 pod,通过暴露 Service 资源的固定地址(集群IP),来解决以上 POD 资源变化产生的 IP 变动问题,但是针对 Service 还存在以下问题:

  • Service IP 地址难以记忆;
  • Service 资源可能也会被销毁和创建;
  • POD IP 本身也有需要暴漏的需求。

为了解决以上问题,引入了 CoreDNS,在 K8S,其主要用于服务发现,也就是服务(应用)之间相互定位的过程。

src=http___img2018.cnblogs.com_blog_680719_201912_680719-20191203172410385-2020427500.png&refer=http___img2018.cnblogs.webp

Dashboard

Dashboard 是基于网页的 Kubernetes 用户界面。

可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群本身及其附属资源。可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如Deployment,Job,DaemonSet 等等)。可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。

u=1495267661,3904868219&fm=253&fmt=auto&app=138&f=GIF.gif

IngressController

Ingress 是自 kubernetes1.1 版本后引入的资源类型,在这个资源中我们可以去配置我们的服务路由规则,但是要真正去实现识别这个 Ingress 并提供代理路由功能,还需要安装一个对应的控制器 Ingress Controller 才能实现。

Ingress Controller 是以一种插件的形式提供,有多种实现,例如官方维护的 Ingress NGINX。Ingress controller 是部署在 Kubernetes 之上的 Docker 容器。它的 Docker 镜像包含一个像 Nginx 或 HAProxy 的负载均衡器和一个控制器守护进程。控制器守护程序从 Kubernetes 接收所需的 Ingress 配置。它会生成一个 Nginx 或 HAProxy 配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress Controller 是由 Kubernetes 管理的负载均衡器。

Ingress Controller 是一个七层负载均衡调度器,客户端的请求先到达这个七层负载均衡调度器,由七层负载均衡器在反向代理到后端 pod,常见的七层负载均衡器有 nginx、traefik,以我们熟悉的 nginx 为例,假如请求到达 nginx,会通过 upstream 反向代理到后端 pod 应用,但是后端 pod 的 ip 地址是一直在变化的,因此在后端 pod 前需要加一个 service,这个 service 只是起到分组的作用,那么我们 upstream 只需要填写 service 地址即可。

src=http___ask.qcloudimg.com_http-save_4405893_qu9k2fdc33.png&refer=http___ask.qcloudimg.webp

Federation

Federation 是为提供跨 Region 跨服务商 K8s 集群服务而设计(K8s 的设计定位是单一集群在同一个地域内)。每个 K8s Federation 有自己的分布式存储、API Server 和 Controller Manager, 用户通过 Federation API Server 注册该 Federation 的成员 K8s Cluster, 当用户通过 Federation 的 API Server 创建、更改 API 对象时,Federation API Server 会在自己所有注册的子 K8s Cluster 都创建一份对应的 API 对象。

提供服务时,K8s Federation 先在自己的各个子 Cluster 之间做负载均衡, 发送到某个具体 K8s Cluser 的业务请求,会按照这个 K8s Cluster 独立提供服务时一样的调度模式去做 K8s Cluster 内部的负载均衡,Cluster 之间的负载均衡通过域名服务的负载均衡完成。

src=http___img-blog.csdnimg.cn_img_convert_df1b8e2aebb897246185edb7fa5146ed.png&refer=http___img-blog.csdnimg.webp

Prometheus

Prometheus(普罗米修斯)是一个最初在 SoundCloud 上构建的监控系统。自2012年成为社区开源项目,拥有非常活跃的开发人员和用户社区。为强调开源及独立维护,Prometheus 于2016年加入云原生云计算基金会(CNCF),成为继Kubernetes之后的第二个托管项目。

Prometheus 是第一个开发了 Kubernetes 自定义资源指标适配器的监控系统,该适配器名为 Kubernetes Custom Metrics Adapter,由托管在 GitHub 上的 k8s-prometheus-adapter 项目提供。它负责以聚合 API Server 的形式服务于 custom.metrics.k8s.io 这一 API 群组,并将对自定义指标的查询请求转发至后端的 Prometheus Server。

Prometheus 是一个开源的服务监控系统和时序数据库。Prometheus 系统的整体工作架构,其中 Prometheus Server 基于服务发现机制或静态配置获取要监视的目标,并通过每个目标上的指标暴露器 Exporter 来采集指标数据。Prometheus Server 内置了一个基于文件的时间序列存储来持久化存储指标数据,用户可使用 PromDash 或 PromQL 接口来检索数据,也可按需将告警需求发往 Alertmanager 完成告警内容发送。另外,一些短期运行的作业的生命周期过短,难以有效地将必要的指标数据传递到 Server 端,它们一般会采用推送方式输出指标数据,Prometheus 借助 Pushgateway 接收这些推送的数据,进而由 Server 端进行抓取。

1507553-20211112112224791-717619566.png

Kubernetes 系统化学习之 基本概念篇(一)
Kubernetes 系统化学习之 POD原理篇(二)
Kubernetes 系统化学习之 资源清单篇(三)
Kubernetes 系统化学习之 服务发现篇(四)
Kubernetes 系统化学习之 持久存储篇(五)
Kubernetes 系统化学习之 集群调度篇(六)
Kubernetes 系统化学习之 集群安全篇(七)