什么是编排

Kubernetes中,我们总是在说一个概念:编排.

[Kubernetes]谈谈Kubernetes的本质这篇文章中,关于"编排"的概念介绍了一下:过去很多集群管理项目所擅长的都是把一个容器,按照某种规则,放置在某个最佳节点上运行起来,这种功能我们称为"调度".但Kubernetes项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化处理好容器之间的各种关系,这种功能,叫做编排.

这篇文章就尝试来讲一下,编排.

编排是如何实现的

不知道你对kube-controller-manager这个组件还有没有印象.这个组件实际上就是一系列控制器的集合.而Deployment,正是一系列控制器集合中的一种.

咱们来举个例子,来解释一下Deployment的作用.现在定义一个nginx的YAML文件,内容如下:

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标签的个数大于2的时候,就会有旧的Pod被删除;反之,则会有新的Pod被创建.

在这里,我们需要提到一个概念:控制循环.我先上一段伪代码,来描述一下控制循环概念:

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

应该能够看出,实际状态往往来自Kubernetes集群本身.而期望状态,一般来自于用户提交的YAML文件.基于上面的伪代码,来讲讲,Deployment是如何实现控制循环的.

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

通过以上,我们可以看到,主要编排逻辑,实际上是在第三步"对比"阶段完成的.这个操作,就是指:控制循环.
控制循环的结果就是,对被控制对象的某种写操作.比如,增加Pod,删除Pod,都是对对象的一些操作.也算是Kubernetes项目"面向API对象编排"的一个直观体现.

控制器的完整实现

上面只是一个概述.这一部分详细讲讲控制器的完整实现:Deployment.

Deployment看似简单,但实际上,它实现了Kubernetes项目中一个非常重要的功能:Pod的"水平扩展/收缩".

比较难以理解?没关系,咱们来举个例子.假设更新了Deployment的Pod模板(比如,修改了容器的镜像),那么Deployment就需要遵循一种叫做"滚动更新"的方式,来升级现有的容器,而这个能力的实现,依赖的是Kubernetes中一个非常重要的API对象:ReplicaSet.它的组成也很简单:副本数目的定义和一个Pod模板.

我们可以发现,所谓的ReplicaSet对象,其实是Deployment的一个子集.而实际上,Deployment控制器实际操纵的,正是这样的ReplicaSet对象,而不是Pod对象.

在这个基础上,咱们一起来分析一下下面的这个Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

从上面我们可以看到,这就是一个nginx-deployment,它定义的Pod副本个数是3(spec.replicas=3).具体实现是这样的:



这样我们就能很清楚的看到了,Deployment,ReplicaSet,Pod之间,是一种"层层控制"的关系.ReplicaSet负责通过"控制器模式",保证系统中Pod的个数永远等于指定的个数.这也是在Deployment中,为什么只允许容器的restartPolicy=Always的原因:只有在容器能保证自己始终是Running状态的前提下,ReplicaSet调整Pod的个数才有意义.

在此基础上,Deployment同样通过"控制器模式",来操作ReplicaSet的个数和属性,进而实现"水平扩展/收缩"和"滚动更新"这两个编排动作."水平扩展/收缩"非常容易实现,Deployment Controller只需要修改它所控制的ReplicaSet的Pod副本个数就可以了.而在"滚动更新"这个动作中,它有一个状态转换的过程:

  • DESIRED:用户期望的Pod副本数(spec.replicas的值);
  • CURRENT:当前处于Running状态的Pod的个数;
  • UP-TO-DATE:当前处于最新版本的Pod的个数,就是说,Pod的Spec部分与Deployment中Pod模板里定义的完全一致;
  • AVAILABLE:当前已经可用的Pod的个数,即:既是Running状态,又是最新版本,并且已经处于Ready(健康检查正确)状态的Pod的个数

我们可以看到,只有AVAILABLE字段,描述的才是用户所期望的最终状态.
在ReplicaSet的DESIRED,CURRENT和READY字段的含义,和Deployment中是一致的.相比Deployment和ReplicaSet,Deployment只是添加了UP-TO-DATE这个跟版本有关的状态字段.
也就是说,如果我们修改了Deployment的Pod模板,"滚动更新"就会被自动触发.
修改Deployment有很多方法,在这里就不说了.我想详细讲述一下"滚动更新"的过程.

滚动更新的详细过程

在这一部分,我详细讲述一下"滚动更新"这个过程.这样,会对"滚动更新"的好处,有一个比较好的理解.

来个小前提:假设我需要"滚动更新"3个Pod.

当我修改了Deployment里的Pod定义之后,Deployment Controller会使用这个修改后的Pod模板,创建一个新的ReplicaSet,此时这个ReplicaSet的初始Pod副本数是:0;

然后,Deployment Controller开始将这个新的ReplicaSet所控制的Pod副本数从0个变成1个,即:"水平扩展"出一个副本;

紧接着,Deployment Controller又将旧的ReplicaSet所控制的旧Pod副本数减少一个,即:“水平收缩"成两个副本.

如此交替进行,新ReplicaSet管理的Pod副本数,从0个变成1个,再变成2个,最后变成3个.与此同时,旧的ReplicaSet管理的Pod副本数则从3个变成2个,再变成1个,最后变成0个.

像这样,将一个集群中正在运行的多个Pod版本,交替地逐一升级过程,就是"滚动更新”

在你详细了解"滚动更新"的过程之后,你就会对它所带来的好处,有一个好的了解.

比如,在升级刚开始的时候,集群里只有1个新版本的Pod,如果这个时候,新版本Pod有问题启动不起来,那么"滚动更新"就会停止,允许开发和运维人员介入解决问题,而这个应用本身还有两个旧版本的Pod在线,所以服务不会受到太大的影响.

想和大家分享的内容,讲的差不多了

以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.

感谢您的阅读~

[Kubernetes]编排其实很简单的更多相关文章

  1. Unity3D入门其实很简单

    在上次发布拙作后,有不少童鞋询问本人如何学习Unity3D.本人自知作为一名刚入门的菜鸟,实在没有资格谈论这么高大上的话题,生怕误导了各位.不过思来想去,决定还是写一些自己的经验,如果能给想要入门U3 ...

  2. [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office

    打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...

  3. MVC其实很简单(Django框架)

    Django框架MVC其实很简单 让我们来研究一个简单的例子,通过该实例,你可以分辨出,通过Web框架来实现的功能与之前的方式有何不同. 下面就是通过使用Django来完成以上功能的例子: 首先,我们 ...

  4. 【结果很简单,过程很艰辛】记阿里云Ons消息队列服务.NET接口填坑过程

    Maybe 这个问题很简单,因为解决方法是非常简单,但填坑过程会把人逼疯,在阿里云ONS工作人员.同事和朋友的协助下,经过一天的调试和瞎捣鼓,终于解决了这个坑,把问题记下来,也许更多人在碰到类似问题的 ...

  5. 自定义View其实很简单系列1-12

    作者: AigeStudio  http://blog.csdn.net/aigestudio 说明:文中的1/12表示12篇中的第1篇, 1/6=2/12表示12篇中的第2篇,其它类似. 自定义控件 ...

  6. 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)

    1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...

  7. java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊

    java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...

  8. Crumpet – 使用很简单的响应式前端开发框架

    Crumpet 是一个简单的响应式的基于 SASS/SCSS 的响应式前端框架,保持你的 HTML 代码简洁.内置尽量使用占位符选择器,以减少你的 HTML 标记的大小,没有凌乱的 HTML 代码.快 ...

  9. 其实Unix很简单

    很多编程的朋友都在网上问我这样的几个问题,Unix怎么学?Unix怎么这么难?如何才能学好?并且让我给他们一些学好Unix的经验.在绝大多数时候,我发现问这些问题的朋友都有两个特点: 1)对Unix有 ...

随机推荐

  1. C语言随机点名程序

    #include "stdio.h"#include "stdlib.h"#include "time.h"#include "w ...

  2. PS调出唯美紫蓝色天空背景女生照片

    教你学会用PS给照片叠加素材,达到想要的效果. 首先,作为摄影在拍摄前,我们要明白自己拍摄主题与目的,希望后期达到的效果,尤其是当我们需要后期叠加素材时,脑海中自然而然会有大致画面,就以“夏日”这组为 ...

  3. C#中字符串的字面值(转义序列)

    在程序开发中,经常会碰到在字符串中字面值中使用转义序列,下面表格收集了下转义序列的完整列表,以便大家查看引用: 转义序列列表 转义序列 产生的字符 字符的Unicode值 \' 单引号 0x0027 ...

  4. 怎么使Richedit中光标始终指到最后一行的最后面?

    Richedit中数据会不断增加.要始终能看到当前的数据.该怎么做? SendMessage(Memo->Handle, WM_VSCROLL, SB_BOTTOM, 0); SendMessa ...

  5. MD 的常用语法格式

    参考资料:MarkDown 语言常用语法 注意:vscode 中,可以使用 ctrl + shift + v 进行预览: 一.标题 一般使用 # 来进行层级标识.共 6 个层级,再多不识别. #  = ...

  6. ElasticSsarch汇总

    用途: 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索: 实时分析的分布式搜索引擎: 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据. 点击查看安装.基本增删改查操作REST ...

  7. ESXI 6.5安装详细步骤

    网址:http://blog.51cto.com/laotang6/2044861 ESXi是专为运行虚拟机.最大限度降低配置要求和简化部署而设计.只需几分钟时间,客户便可完成从安装到运行虚拟机的全过 ...

  8. MySQL——修改数据库远程权限

    语句 赋予权限 ON *.*前一个*代表库后一个代表表 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'xxxxx' WITH GRA ...

  9. [HDU5969] 最大的位或

    题目类型:位运算 传送门:>Here< 题意:给出\(l\)和\(r\),求最大的\(x|y\),其中\(x,y\)在\([l,r]\)范围内 解题思路 首先让我想到了前面那题\(Bits ...

  10. Ceph分布式存储(luminous)部署文档-ubuntu18-04

    Ceph分布式存储(luminous)部署文档 环境 ubuntu18.04 ceph version 12.2.7 luminous (stable) 三节点 配置如下 node1:1U,1G me ...