学习笔记-剖析k8s之控制器模型-3月day16
Posted july7may
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习笔记-剖析k8s之控制器模型-3月day16相关的知识,希望对你有一定的参考价值。
文章目录
前言
Pod这个看似复杂的API对象,实际上就是对容器的进一步抽象和封装而已。“容器”镜像虽然好用,但是容器这样一个“沙盒”的概念,对于描述应用来说,还是太过简单了。所以,Pod对象,其实就是容器的升级版。它对容器进行了组合,添加了更多的属性和字段。使得Kubernetes可以更轻松地操作它。
Kubernetes操作这些Pod的逻辑,就是由控制器(Controller)完成的。
控制器(Controller)
回顾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被创建。
kube-controller-manager的组件,提供了k8s中一系列控制器的集合。可以查看一下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
以Deployment为例,简单描述一下它对控制器模型的实现:
- Deployment控制器从Etcd中获取到所有携带了“app: nginx”标签的Pod,然后统计它们的数量,这就是实际状态;
- Deployment对象的Replicas字段的值就是期望状态;
- Deployment控制器将两个状态做比较,然后根据比较结果,确定是创建Pod,还是删除已有的Pod;
可以看到,一个Kubernetes对象的主要编排逻辑,实际上是在第三步的“对比”阶段完成的。这个操作,通常被叫作调谐(Reconcile)。这个调谐的过程,则被称作“Reconcile Loop”(调谐循环)或者“Sync Loop”(同步循环)。调谐的最终结果,往往都是对被控制对象的某种写操作:增加Pod,删除已有的Pod,或者更新Pod的某个字段。这也是Kubernetes项目“面向API对象编程”的一个直观体现。
Deployment这种控制器的设计原理,体现在“用一种对象管理另一种对象”的“艺术”:
- 这个控制器对象本身,负责定义被管理对象的期望状态。
- 而被控制对象的定义,则来自于一个“模板”。比如,Deployment里的template字段,所有被这个Deployment管理的Pod实例,其实都是根据这个template字段的内容创建出来的。
像Deployment定义的template字段,在Kubernetes项目中有一个专有的名字,叫作PodTemplate(Pod模板)。这个概念非常重要,因为大多数控制器,都会使用PodTemplate来统一定义它所要管理的Pod。更有意思的是,我们还会看到其他类型的对象模板,比如Volume的模板。
类似Deployment这样的一个控制器,实际上都是由上半部分的控制器定义(包括期望状态),加上下半部分的被控制对象的模板组成的。(仅从代码书写角度上看,区分并不明显)
因此,在所有API对象的Metadata里,都有一个字段叫作ownerReference,用于保存当前这个API对象的拥有者(Owner)的信息。
小结
Kubernetes项目正是通过一个称作“控制器模式”(controller pattern)的设计方法,来统一地实现对各种不同的对象或者资源进行的编排操作。比如StatefulSet、DaemonSet等等,跟Deployment相似,这些控制循环最后的执行结果,要么就是创建、更新一些Pod(或者其他的API对象、资源),要么就是删除一些已经存在的Pod(或者其他的API对象、资源)。
但正是在这个统一的编排框架下,不同的控制器可以在具体执行过程中,设计不同的业务逻辑,从而达到不同的编排效果。这个实现思路,正是Kubernetes项目进行容器编排的核心原理。
附
此文章为3月Day16学习笔记,内容来源于极客时间《深入剖析Kubernetes》
《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制
原创文章,欢迎转载。转载请注明:关东升的博客
通知(Notification)机制是基于观察者(Observer)模式也叫发布/订阅(Publish/Subscribe)模式,是 MVC(模型-视图-控制器)模式的重要组成部分。
问题提出
天气一直是英国人喜欢讨论的话题,而最近几年天气的变化也成为中国人非常关注的话题。我会根据天气预报决定是坐地铁还是开车上班,我的女儿也会根据天气预报决定明天穿哪件衣服。于是我在移动公司为我的手机定制了天气预报短信通知服务,它的工作模型如图所示。
每天气象局将天气预报信息投送给移动运营商,移动运营商的短信中心负责把天气预报发送给定制过这项服务的手机。
在软件系统中,一个对象状态改变也会连带影响其他很多对象的状态发生改变。能够实现这一需求的设计方案有很多,但能够做到复用性强且对象之间匿名通信的,观察者模式是其中最为适合的一个。
解决方案
通知机制可以实现“一对多”的对象之间的通信。如图所示,在通知机制中对某个通知感兴趣的所有对象都可以成为接收者。首先,这些对象需要向通知中心(NSNotificationCenter)发出addObserver消息进行注册通知,在投送对象通过postNotificationName消息投送通知给通知中心,通知中心就会把通知广播给注册过的接收者。所有的接收者都不知道通知是谁投送的,更不关心它的细节。投送对象与接收者是一对多的关系。接收者如果对通知不再关注,会给通知中心发出removeObserver消息注销通知,以后不再接收通知。
欢迎关注关东升新浪微博@tony_关东升。
关注智捷课堂微信公共平台,了解最新技术文章、图书、教程信息
更多精品iOS、Cocos、移动设计课程请关注智捷课堂官方网站:http://www.zhijieketang.com
智捷课堂论坛网站:http://51work6.com/forum.php
本文出自 “关东升-iOS技术顾问” 博客,请务必保留此出处http://tonyguan.blog.51cto.com/701759/1749097
以上是关于学习笔记-剖析k8s之控制器模型-3月day16的主要内容,如果未能解决你的问题,请参考以下文章
《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制
《从零开始学Swift》学习笔记(Day67)——Cocoa Touch设计模式及应用之MVC模式
《从零开始学Swift》学习笔记(Day67)——Cocoa Touch设计模式及应用之MVC模式