什么是编排

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

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

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

编排是如何实现的

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

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

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deployment
  5. spec:
  6. selector:
  7. matchLabels:
  8. app: nginx
  9. replicas: 2
  10. template:
  11. metadata:
  12. labels:
  13. app: nginx
  14. spec:
  15. containers:
  16. - name: nginx
  17. image: nginx:1.7.9
  18. ports:
  19. - containerPort: 80

我们可以看到,这个Deployment定义的编排动作非常简单,要做的就是:确保携带了app=nginx标签的Pod的个数,永远等于spec.replicas指定的个数,即2个.

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

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

  1. for {
  2. 实际状态 = 获取集群中对象 X 的实际状态(Actual State
  3. 期望状态 = 获取集群中对象 X 的期望状态(Desired State
  4. if 实际状态 == 期望状态{
  5. 什么都不做
  6. } else {
  7. 执行编排动作,将实际状态调整为期望状态
  8. }
  9. }

应该能够看出,实际状态往往来自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:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deployment
  5. labels:
  6. app: nginx
  7. spec:
  8. replicas: 3
  9. selector:
  10. matchLabels:
  11. app: nginx
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx
  16. spec:
  17. containers:
  18. - name: nginx
  19. image: nginx:1.7.9
  20. ports:
  21. - 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. zookeeper的分布式锁

    实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...

  2. AI deeplab

    参考链接: https://arxiv.org/pdf/1412.7062v3.pdf

  3. UOJ188 Sanrd Min_25筛

    传送门 省选之前做数论题会不会有Debuff啊 这道题显然是要求\(1\)到\(x\)中所有数第二大质因子的大小之和,如果不存在第二大质因子就是\(0\) 线性筛似乎可以做,但是\(10^{11}\) ...

  4. PostgreSql扩展Sql-动态加载共享库(C函数)

    基于 psql (PostgreSQL) 10.4 pg_language表定义了函数实现所使用的语言.主要支持了C语言和SQL语句.一些可选的语言包括pl/pgsql.tcl和perl. ligan ...

  5. 安装appium桌面版和命令行版

    一 桌面版(打开很慢,常用于辅助元素定位) 1.官网下载window版本: 2.直接点击紫色图标即可打开   3.启动server 二  命令行版(打开很快,常用于执行脚本) 1.jdk 安装jdk并 ...

  6. 【转】Python爬虫:抓取新浪新闻数据

    案例一 抓取对象: 新浪国内新闻(http://news.sina.com.cn/china/),该列表中的标题名称.时间.链接. 完整代码: from bs4 import BeautifulSou ...

  7. Tomcat服务器下载、安装、配置环境变量教程(超详细)

    请先配置安装好Java的环境,若没有安装,请参照我以下的步骤进行安装! 请先配置安装好Java的环境,若没有安装,请参照我以下的步骤进行安装! 请先配置安装好Java的环境,若没有安装,请参照我以下上 ...

  8. git安装和GitHub使用

    一.git安装 1.git下载 https://github.com/git-for-windows/git/releases/tag/v2.17.1.windows.2 在如上地址下载git,并安装 ...

  9. BZOJ4269再见Xor——高斯消元解线性基

    题目描述 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. 输入 第一行一个正整数N. 接下来一行N个非负整数. 输出 一行,包含两 ...

  10. nginx的location配置root、alias用法和区别

    root & alias区别root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上root的处理结果是:root路径 ...