我们通常使用 kubectl 来管理我们的 Kubernetes 集群。 当我们需要一个 Nginx 服务时,可以使用以下命令来创建:

kubectl create deployment nginx --image nginx

返回:

deployment.apps/nginx created

稍等片刻,一个包含 Nginx 容器的 Pod 就会启动成功。那么在我们执行在上述命令后,Kubernetes 内部发生了什么呢?

核心组件

在介绍内部发生了什么之前,我们首先需要了解一下以下 4 个核心组件在 Kubernetes 集群中的角色和作用:

  • kube-apiserver: Kubernetes API 服务器验证并配置 API 对象的数据, 这些对象包括 pods、services 等。 API 服务器为 REST 操作提供服务,并为集群的共享状态提供前端, 所有其他组件都通过该前端进行交互。

  • kube-controller-manager: 运行控制器进程的控制平面组件。 从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行,所以它会被称作为 manager。它包含 DeploymentController、ReplicaSetController、JobController 等一系列控制器。

  • kube-scheduler: 控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。 调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

  • kubelet: 一个在集群中每个节点(node)上运行的代理。 它保证容器(containers)都运行在 Pod 中。 kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。

简化的核心过程

在了解上述核心组件的角色后,我们来看一下 Kubernetes 内部到底发生了哪些事情:

  1. 用户通过 kubectl 向 kube-apiserver 发起一个创建 Deployment 对象的请求。

  2. kube-apiserver 在对上述请求进行认证(authn)、授权(authz)、准入控制(admission control)、验证(validation)等一系列操作后,会创建一个 Deployment 对象。

  3. 上述的 Deployment 创建事件,会被 DeploymentController 通过其内部的 DeploymentInformer 监听到,然后根据 DeploymentController 内部设定的逻辑,它将会创建一个 ReplicaSet 对象。源码 syncDeployment

  4. 上述的 ReplicaSet 创建事件,会被 ReplicaSetController 通过其内部的 ReplicaSetInformer 监听到,然后根据 ReplicaSetController 内部设定的逻辑,它将创建一个 Pod 对象,而此时 Pod 的 Spec.nodeName 字段的值为空;源码 syncReplicaSet

  5. 上述的 Pod 创建事件,会被 Scheduler 通过其内部的 PodInformer 监听到,Scheduler 会根据其内部的调度算法,选择一个合适的 Node 节点,例如 node-A,并更新 Pod 的 Spec.nodeName 字段。源码 Schedule

  6. 上述的 Pod 更新事件,会被 node-A 节点上 kubelet 感知到,它会发现自己的 nodeName 和 Pod 的 Spec.nodeName 相匹配,接着 kubelet 将按照一定的步骤顺序启动 Pod 中的容器,并将容器已启动的信息写入 Pod 的 Status 中。源码 syncPod

如上所述,DeploymentController、ReplicaSetController 等许多独立的控制循环都是通过监听 kube-apiserver 上对象的变化进行通信,而这些变化会通过各种 Informer 触发事件,执行其对应的业务逻辑。之所以这么设计,是为了减少对 apiserver 的压力。

kubelet 创建 Pod 的过程

Pod 的创建的过程大体上可以分为 4 个步骤(实际上为 7 步,这里省略了前置的 3 个步骤。源码 SyncPod):

  1. 为 Pod 创建沙盒,即基础设施容器 Infrastructure Container(镜像名称为 k8s.gcr.io/pause),它的主要作用是创建并共享进程命名空间。

  2. 创建 Pod 规格中指定的临时容器 Ephemeral Containers(Alpha 功能,默认不开启),临时容器是一种特殊的容器,该容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查。 你可以使用临时容器来检查服务,而不是用它来构建应用程序。

  3. 创建 Pod 规格中指定的初始化容器 Init Containers,初始化容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。

  4. 依次创建 Pod 规格中指定的常规容器 Containers。

参考

更多

更多经典示例请参考:https://github.com/jxlwqq/kubernetes-examples

当你创建了一个 Deployment 时,Kubernetes 内部发生了什么?的更多相关文章

  1. 使用ArrayList时代码内部发生了什么(jdk1.7)?

    前言 ArrayList(这里的ArrayList是基于jdk1.7)是在项目中经常使用的集合类,例如我们从数据库中查询出一组数据.这篇文章不去剖析它的继承和实现,只是让我们知道实例化及增删改查时它的 ...

  2. 当一个 Pod 被调度时,Kubernetes 内部发生了什么?

    在 Kubernetes 中,调度是指将 Pod 放置到合适的 Node 上,然后对应 Node 上的 Kubelet 才能够运行这些 Pod . kube-scheduler 是集群控制平面的主要组 ...

  3. 一个web项目在myeclipse中add deployment时无法被识别出来的原因

    当我们一个web项目,在myeclipse中,add deployment时,可能发现,根本无法被识别成web项目,可能的原因有:   1. 项目的properties ->Myeclipse ...

  4. 第一次通过AVD Manager创建了一个虚拟设备,但是在Android Studio运行程序时却无设备可选

    第一次通过AVD Manager创建了一个虚拟设备,但是在Android Studio运行程序时却无设备可选 原因是adb.exe未运行起来 至于adb.exe未正常运行起来的原因多半是5037端口被 ...

  5. 在Kubernetes上运行SAP UI5应用(下): 一个例子体会Kubernetes内容器的高可用性和弹性伸缩

    上一篇文章 在Kubernetes上运行SAP UI5应用(上),我介绍了如何在Docker里运行一个简单的SAP UI5应用,并且已经成功地将一个包含了这个UI5应用的docker镜像上传到Dock ...

  6. Kubernetes — 从0到1:搭建一个完整的Kubernetes集群

    准备工作 首先,准备机器.最直接的办法,自然是到公有云上申请几个虚拟机.当然,如果条件允许的话,拿几台本地的物理服务器来组集群是最好不过了.这些机器只要满足如下几个条件即可: 满足安装 Docker ...

  7. 手动部署一个单节点kubernetes

    目录 简要说明 安装环境说明 部署 生成相关证书 证书类型说明 安装cfssl证书生成工具 生成CA证书 生成Kubernetes master节点使用的证书 生成kubectl证书 生成kube-p ...

  8. 创建第一个Maven项目

    -----------------------siwuxie095                                     创建第一个 Maven 项目         1.打开 Ec ...

  9. 使用Visual Studio Code创建第一个ASP.NET Core应用程序

    全文翻译自:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 这篇文章将向你展示如何在Mac上写出你的第一个A ...

随机推荐

  1. JAVA集合类(代码手写实现,全面梳理)

    参考网址:https://blog.csdn.net/weixin_41231928/article/details/103413167 目录 一.集合类关系图 二.Iterator 三.ListIt ...

  2. [ASP.NET MVC]@RenderSection,@RenderBody(),@RenderPage

    1.@RenderBody()  作用和母版页中的服务器控件类似,当创建基于此布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过布局页面的@RenderBody()方法呈现在标签之 ...

  3. Spring系列.Environment接口

    Environment 接口介绍 在 Spring 中,Environment 接口主要管理应用程序两个方面的内容:profile 和 properties. profile 可以简单的等同于环境,比 ...

  4. 20210816 你相信引力吗,marshland,party?,半夜

    考场 第一眼都不可做 T1 长得就像单调栈/单调队列,推了推性质发现优弧.劣弧都合法的点对很好处理,其他情况只在一种情况合法,那么开两个单调队列分别统计距离 \(\le\frac2n,>\fra ...

  5. noip模拟44

    A. Emotional Flutter 直接将所有黑块平移到 \([1-k,0]\) 的区间即可,然后找有没有没被覆盖过的整点 注意特判 \(1-k\) 以及 \(0\) 的可行性,考场这里写挂成 ...

  6. Python常见问题 - 写入数据到 excel 报 ValueError: invalid literal for int() with base 10 错误

    背景 在上写入数据到excel中,报了以下错误 出现原因 对于写入excel场景下出现该错误的话,很大概率是写入数据的单元格原本的数据格式有问题 解决方法 清理掉单元格的旧数据,然后再写入就可以了

  7. redis存取数据Hash

    一.概念 二.存取散列Hash值 1. 2.JSON字符串存取,没有更新值的字段资源浪费 使用散列Hash存取,可以单独到一个或多个字段: 3.hsetnx,属性不存在就新增并赋值,属性已存在啥也不干 ...

  8. Spring表达式

    一.SpEL 其中,直接写也可以赋值,' ' 单引号引起来后成为一个字符串对象,可以调用String的方法: 二.引用另外一个bean 装配这个类的bean: 1.第一种方法,property标签中使 ...

  9. Activiti 学习(四)—— Activiti 结合实际业务

    流程实例 流程实例(ProcessInstance)代表流程定义的执行实例.一个流程实例包括了所有的运行节点.我们可以利用这个对象来了解当前流程实例的进度等信息.例如:用户或程序按照流程定义内容发起一 ...

  10. Python - poetry(3)配置项详解

    config 命令 poetry 通过 config 命令进行配置 也可以直接在 config.toml 文件中进行配置,该文件将在首次运行该命令时自动创建 文件目录 macOS:~/Library/ ...