【K8S系列】深入解析控制器

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 【K8S系列】深入解析控制器

1 基础介绍

1.1 前情提要

回忆一下,我和你详细介绍了 Pod 的用法,讲解了 Pod 这个 API 对象的各个字段。而接下来,我们就一起来看看“编排”这个 Kubernetes 项目最核心的功能吧。

实际上,你可能已经有所感悟:Pod 这个看似复杂的 API 对象,实际上就是对容器的进一步抽象和封装而已。

说得更形象些,“容器”镜像虽然好用,但是容器这样一个“沙盒”的概念,对于描述应用来说,还是太过简单了。

这就好比,集装箱固然好用,但是如果它四面都光秃秃的,吊车还怎么把这个集装箱吊起来并摆放好呢?

所以,Pod 对象,其实就是容器的升级版。它对容器进行了组合,添加了更多的属性和字段这就好比给集装箱四面安装了吊环,使得 Kubernetes 这架“吊车”,可以更轻松地操作它。

Kubernetes 操作这些“集装箱”的逻辑,都由控制器(Controller)完成

1.2  Kube-controller-manager介绍

Kube-controller-manager是Kubernetes中的一个控制器,是Kubernetes系统中的一个组件,负责运行一些后台控制循环(controller loop),并监视系统中的各个资源的状态

kube-controller-manager通常运行在Master节点上。kube-controller-manager包含了多个控制器,每个控制器都负责处理不同的资源。

1.3 控制器类型

以下是kube-controller-manager中的一些重要控制器:

  1. Deployment控制器:用于确保Deployment对象所管理的Pod副本数量符合预期,并且进行滚动更新(Rolling Update)。
  2. ReplicaSet控制器:用于确保ReplicaSet对象所管理的Pod副本数量符合预期。
  3. DaemonSet 控制器:DaemonSet 控制器用于在集群中的每个节点上启动一个 Pod 副本,以便运行一些系统级别的守护进程,如日志收集器和监控代理。如果有新的节点加入集群,DaemonSet 控制器会自动在新节点上启动相应的 Pod 副本。
  4. StatefulSet控制器:用于确保StatefulSet对象所管理的有状态应用程序的副本数量符合预期。
  5. Node控制器:用于确保所有Node对象的状态都是最新的,并管理Node的状态。
  6. Service控制器:用于确保Service对象的状态符合预期,并处理Service的创建、更新和删除等操作。
  7. Namespace控制器:用于确保Namespace对象的状态符合预期,并处理Namespace的创建、更新和删除等操作。
  8. Endpoint控制器:用于确保Endpoint对象的状态符合预期,并处理Endpoint的创建、更新和删除等操作。
  9. Job控制器:用于确保Job对象所管理的任务成功完成,并对失败的任务进行重试。
  10. CronJob控制器:用于确保CronJob对象所管理的定时任务按照预期执行。

在kube-controller-manager中,每个控制器都是一个独立的进程,它们之间相互独立,互不影响。同时,kube-controller-manager会自动监视资源对象的状态变化,并触发相应的控制器处理,以确保系统状态的一致性和稳定性。


2 使用介绍

2.1 控制循环

了解具体的使用之前,需要先看下“循环控制”这个概念

在 Kubernetes 中,控制循环(control loop)是一种通用的编排模式,用于监控和控制集群中的资源

控制循环通过对比当前状态和期望状态之间的差异来确保集群的期望状态得以实现

具体而言,控制循环包括以下几个步骤:

  1. 监控资源状态:控制循环会定期检查集群中的资源状态,例如 Pod、Service、Deployment 等。
  2. 计算期望状态:根据 Kubernetes 集群的配置文件和用户提交的操作,控制循环会计算出资源的期望状态。例如,用户可能会提交一个 Deployment 的 YAML 文件,其中指定了需要部署的 Pod 数量和镜像版本等信息,控制循环就会根据这些信息计算出 Deployment 的期望状态。
  3. 对比当前状态和期望状态:控制循环会将当前状态和期望状态进行对比,找出二者之间的差异。例如,如果一个 Deployment 的期望 Pod 数量为 3,但是当前只有 2 个 Pod 在运行,那么控制循环就会发现这个差异。
  4. 执行调整操作:控制循环会根据差异来执行调整操作,使得当前状态逐渐接近期望状态。例如,控制循环会自动创建新的 Pod,以便使得 Deployment 中的 Pod 数量达到期望值。
  5. 重复执行:控制循环会一直重复上述步骤,直到当前状态和期望状态完全一致。

注意,控制循环并不是一个线性的过程,而是由多个控制器(Controller)组成的复杂系统。每个控制器都会负责监控和管理一个或多个资源,例如 Deployment、StatefulSet、DaemonSet 等。不同的控制器之间还可以相互协作,以实现更复杂的功能。


2.2 Deployment控制器

我们曾经使用过 Deployment 这个最基本的控制器对象。现在,我们一起来回顾一下这个名叫 nginx-deployment 的例子:

apiVersion: apps/v1
kind: Deployment #资源类型
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

这个 Deployment 定义的编排动作非常简单,即:确保携带了 app=nginx 标签的 Pod 的个数,永远等于 spec.replicas 指定的个数,即 2 个

这就意味着,如果在这个集群中,携带 app=nginx 标签的 Pod 的个数大于 2 的时候,就会有旧的 Pod 被删除;反之,就会有新的 Pod 被创建。

这时,你也许就会好奇:究竟是 Kubernetes 项目中的哪个组件,在执行这些操作呢?


没错,就是今天介绍  kube-controller-manager 的组件。


那他具体怎么控制的呢?我们以这个 Deployment 为例,分析一下:


实际上,这个组件,是一系列控制器的集合。可以查看一下 Kubernetes 项目pkg/controller 目录:

$ cd kubernetes/pkg/controller/
$ ls -d */              
deployment/             job/                    podautoscaler/          
cloud/                  disruption/             namespace/              
replicaset/             serviceaccount/         volume/
cronjob/                garbagecollector/       nodelifecycle/          replication/            statefulset/            daemon/
...

这个目录下面的每一个控制器,都以独有的方式负责某种编排功能。而我们的 Deployment,正是这些控制器中的一种。

实际上,这些控制器之所以被统一放在 pkg/controller 目录下,就是因为它们都遵循 Kubernetes 项目中的一个通用编排模式,即:控制循环(control loop)。就是上面说的那个控制循环

比如,现在有一种待编排的对象 X,它有一个对应的控制器。那么,用一段 Go 语言风格的伪代码,描述这个控制循环

for {
  实际状态 := 获取集群中对象 X 的实际状态(Actual State)
  期望状态 := 获取集群中对象 X 的期望状态(Desired State)
  if 实际状态 == 期望状态{
    什么都不做
  } else {
    执行编排动作,将实际状态调整为期望状态
  }
}

实际状态:

在具体实现中,实际状态往往来自于 Kubernetes 集群本身

比如,kubelet 通过心跳汇报的容器状态和节点状态,或者监控系统中保存的应用监控数据,或者控制器主动收集的它自己感兴趣的信息,这些都是常见的实际状态的来源。

期望状态:

而期望状态,一般来自于用户提交的 YAML 文件

比如,Deployment 对象中 Replicas 字段的值

很明显,这些信息往往都保存在 Etcd 中。接下来,以 Deployment 为例,简单描述一下它对控制器模型的实现:

  1. Deployment 控制器从 Etcd 中获取到所有携带了“app: nginx”标签的 Pod,然后统计它们的数量,这就是实际状态
  2. Deployment 对象的 Replicas 字段的值就是期望状态
  3. Deployment 控制器将两个状态做比较,然后根据比较结果,确定是创建 Pod,还是删除已有的 Pod

PodTemplate:

其实,像 Deployment 这种控制器的设计原理,就是“用一种对象管理另一种对象”的“艺术”。

其中,这个控制器对象本身,负责定义被管理对象的期望状态。比如,Deployment 里的 replicas=2 这个字段。

而被控制对象的定义,则来自于一个“模板”。比如,Deployment 里的 template 字段。


可以看到,Deployment 这个 template 字段里的内容,跟一个标准的 Pod 对象的 API 定义,丝毫不差。而所有被这个 Deployment 管理的 Pod 实例,其实都是根据这个 template 字段的内容创建出来的。


像 Deployment 定义的 template 字段,在 Kubernetes 项目中有一个专有的名字,叫作 PodTemplate(Pod 模板)。


这个概念非常重要,因为后面讲解到的大多数控制器,都会使用 PodTemplate 来统一定义它所要管理的 Pod。更有意思的是,我们还会看到其他类型的对象模板,比如 Volume 的模板。


至此,对 Deployment 以及其他类似的控制器,做一个简单总结了:

如上图所示,类似 Deployment 这样的一个控制器,实际上都是由

  • 上半部分的控制器定义(包括期望状态)
  • 下半部分的被控制对象的模板组成的


3 总结

在这篇文章中,以 Deployment 为例,详细分享了 Kubernetes 项目如何通过一个称作“控制器模式”(controller pattern)的设计方法,来统一地实现对各种不同的对象或者资源进行的编排操作。


这个实现思路,正是 Kubernetes 项目进行容器编排的核心原理。

在此后讲解 Kubernetes 编排功能的文章中,我都会遵循这个逻辑展开,并且带你逐步领悟控制器模式在不同的容器化作业中的实现方式。


4 投票

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7天前
|
Kubernetes 监控 调度
【赵渝强老师】K8s的DaemonSet控制器
DaemonSet控制器确保每个节点上运行一个Pod副本,适用于监控、日志收集等场景。通过示例创建DaemonSet并查看Pod信息,展示了其自动扩展和回收的能力。视频讲解和代码示例详细说明了DaemonSet的使用方法和调度机制。
|
7天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Job控制器单工作队列的串行方式
Kubernetes中的Job控制器用于管理一次性任务,确保任务完成后不再重启。本文介绍了Job的工作原理、运行方式及示例,包括创建Job、查看Job和Pod信息等步骤,并附有视频讲解。
|
7天前
|
Kubernetes 双11 容器
【赵渝强老师】Kubernetes中的控制器
Kubernetes通过控制器管理Pod的生命周期,以应对不同场景需求,如Deployment、DaemonSet、Job等。控制器可自动调整Pod数量和重启故障Pod,确保系统稳定运行。视频讲解和详细内容见下文。
|
3月前
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
320 0
|
7天前
|
Kubernetes 应用服务中间件 nginx
【赵渝强老师】K8s中的Deployment控制器
Kubernetes中的Deployment用于部署无状态应用程序,管理Pod的数量、更新方式和资源限制。通过创建和管理ReplicaSet,Deployment可以实现Pod的自动扩缩容、滚动更新和回滚。本文介绍了Deployment的基本概念,并通过一个具体的示例演示了如何使用Deployment创建、更新和管理Pod。
|
9天前
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
7天前
|
存储 Kubernetes 调度
【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别
K8s中的Deployment控制器用于管理无状态应用程序,关注Pod数量、更新方式等;而StatefulSets控制器则管理有状态应用程序,提供持久存储和唯一标识符,适用于需要稳定网络标识符和持久化存储的场景。两者的主要区别在于是否维护状态和顺序。
|
7天前
|
存储 Kubernetes 调度
【赵渝强老师】K8s的有状态控制器StatefulSet
在Kubernetes中,StatefulSets用于部署有状态应用程序,提供持久存储和唯一标识符。与Deployment不同,StatefulSets确保Pod的标识符在重新调度后保持不变,适用于需要稳定网络标识符和持久存储的场景。本文介绍了StatefulSets的创建、扩容与缩容、更新与回滚等操作,并提供了具体示例和视频讲解。
|
7天前
|
Kubernetes Linux 调度
【赵渝强老师】K8s的周期性任务控制器CronJob
本文介绍了K8s中的CronJob控制器,它类似于Linux的crontab命令,用于管理和调度定时作业。CronJob可以设置在未来某一时间运行作业一次或在指定时间点重复运行作业。文章通过一个示例展示了如何创建和使用CronJob控制器,包括创建配置文件、应用配置、查看Pod信息和日志等步骤。同时,还解释了CronJob的时间表示方式及其限制。
|
7天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s的Job控制器多工作队列的并行方式
Kubernetes Job 是一次性任务控制器,用于控制 Pod 中的容器执行特定任务。本文介绍了 Job 控制器的工作原理、运行方式及多工作队列并行执行的示例。示例中创建了 5 个作业,以 3 个队列并行执行,整个过程需 2 分钟。文中还提供了详细的 YAML 文件配置和执行命令。