Kubernetes设计的4个原则

Stella981
• 阅读 889

Kubernetes设计的4个原则

Kubernetes设计的4个原则

转载本文需注明出处:微信公众号EAWorld,违者必究。

引言:

今天我要带给大家的是2018年底,在西雅图举办的Kubecon的一场分享,来自谷歌K8s团队的工程师Saad Ali分享的《Kubernetes设计原则》。这场会议虽然已经过去一年多了,但是我觉得本会议的内容非常值得学习,我们大都知道K8s是如何工作的,但是本文带我们了解k8s背后的设计原则,以及为什么要这样设计。

对于跨云和本地环境在分布式系统上管理和部署工作负载,Kubernetes很快变得不可或缺。

虽然现在大多数人都熟悉如何使用Kubernetes,但很少有人知道其背后的“为什么”?为什么Kubernetes API看起来是这样的?为什么Kubernetes组件仅通过Kubernetes API相互交互?当您可以轻松地直接从pod引用卷时,为什么会有PersistentVolumeClaim对象?

为了回答这些问题并帮助您对Kubernetes进行更深入的了解,本讲座将揭示支撑Kubernetes设计的原理。

原则1. Kubernetes APIs

是声明性的而非命令性的

我们从最简单的一个例子开始,要如何在一台节点上启动需要运行的任务。

Kubernetes设计的4个原则

最简单的方式就是发送一个命令,启动容器。

Kubernetes设计的4个原则

但是这样做的话,如果容器,节点崩溃,或者节点临时不可访问的时候,用户就必须监控和存储每一个节点和容器的状态,捕获所有的异常,并做异常处理。也就是说把所有的复杂的异常处理的逻辑交给客户端来做。

这就引入了Kubernetes的第一个设计原则:

Kubernetes APIs 是声明性的而非命令性的 ( Kubernetes APIs are declarative rather then imperative )

命令式:

  • 用户:提供一系列的指令来驱动系统达到制定状态。

  • 系统:执行指令

  • 用户:监控系统,根据系统状态,提供进一步的指令

声明式:

  • 用户:定义期望的状态

  • 系统:向着指定的状态工作

下图是一个声明式API的例子:

1、用户创建一个API对象

Kubernetes设计的4个原则

2、所用的组件并行工作来达到该状态。

Kubernetes设计的4个原则

声明式的API支持自动恢复。例如:

1、节点B挂了

Kubernetes设计的4个原则

2、系统自主地把Pod移动到健康的节点A上

Kubernetes设计的4个原则

这里需要注意主节点只是存储了Pod的定义声明,而不会向节点B发送命令,如果那样做,主节点就会变得和我们之前提到的客户端一样,复杂而脆弱,且难以扩展。这就引入了K8s的第二个设计原则:

Kubernetes控制平面是透明的,没有隐藏的内部API ( The Kubernetes control plane is transparent. There are no hidden internal APIs. )

原则2.  Kubernetes控制平面

是透明的,没有隐藏的内部API

之前:

  • 主节点:提供一系列的指令来驱动节点达到制定状态。

  • 节点:执行主节点发来的指令

  • 主节点:监控每一个节点,根据节点状态,提供进一步的指令

现在:

  • 主节点:定义想要达到的状态

  • 节点:独立工作以达到主节点定义的状态

我们来看一个Pod创建的例子:

如下图所示,所有的组件都监视Kubernetes API,然后决定自己应该怎么做。

Kubernetes设计的4个原则

用户调用API声明要创建的Pod

Kubernetes设计的4个原则

主节点创建Pod的定义

Kubernetes设计的4个原则

Scheduler通过API观察到Pod A的定义,通过调度运算,决定要在Node B上创建Pod A,并通过API更新主节点上的Pod A的定义。

Kubernetes设计的4个原则

Node B观察到Pod A的定义是在自己的管辖范围,启动Pod A

Kubernetes设计的4个原则

用户通过API删除 Pod A

Kubernetes设计的4个原则

节点B发现 Pod A被删除

Kubernetes设计的4个原则

节点B删除Pod A

Kubernetes设计的4个原则

这样做的能促成一个更简单,更健壮的系统设计,并很容易从故障状态中恢复。系统没有单点故障,主节点的职责非常简单。

这样做的另一个好处是,系统更容易扩展和组合。因为没有内部隐藏的API,用户可以很容易的用自定的组件替代已有组件,或者增加自定义的功能。

K8s还有很对对象对业务是很重要的,例如存储密码的密匙文件secret,配置configmap,或者下行API提供Pod的基本信息。那么应用程序必须修改为调用KubeAPI来或者这些信息么?

这就引入了Kubernetes的第三个设计原则:

满足用户的需求 ( Meet the user where they are )

原则3.  满足用户的需求

之前:

  • 应用程序必须被修改为知道K8s的存在,调用KubeAPI

现在:

  • 应用程序可以从环境变量加载配置文件或者密匙文件,所以不需要修改

Kubernetes设计的4个原则

我们可以举一个例子,是关于远程存储的。

Kubernetes设计的4个原则

如上图所示,Pod可以直接引用一个远程的存储卷(GCE PD,AWS EBS,NFS等),kubernetes会自动使得该卷被用于Pod。但是这样做的话,有一个问题,如果你要迁移到一个新的基础架构上,那么它就不工作了。于是这就引入了kubernetes设计的第四个原则:

可移植的工作负载 ( Workload portability )

原则4. 可移植的工作负载

持久卷(PersistentVolumn,PV)和持久卷声明(PersistenVolumnClaim, PVC)就是这样一个例子。

Kubernetes设计的4个原则

Kubernetes设计的4个原则

如上图所示,通过PVC的抽象,用户Pod并不直接引用GCE PD或者EBS,这样就使得该Pod可以在不同的基础架构中互相迁移,做到可移植。就像操作系统一样,该设计使得系统应用和底层的硬件或者架构实现分离解耦。

总结

本文总结了Kubecon 2018的一场由谷歌高级软件工程师、kubernete开发人员Saad Ali分享的《Kubernetes设计原则》。其中的四个设计原则分别是:

  1. Kubernetes APIs 是声明性的而非命令性的

  2. Kubernetes控制平面是透明的,没有隐藏的内部API

  3. 满足用户的需求

  4. 可移植的工作负载

通过该分享,我们可以发现,K8s的背后设计原则的原因,其实它软件设计的一些一般性原则是一致的,虽然面向对象已经不在是什么流行的术语,但是本文中的设计原则和面向对象的设计原则高度一致。

  • 对象要对自己负责。在设计对象的时候,对象应该尽可能的封装内部的状态,对自己负责,我们设计一辆可行驶的车。一种设计是两个对象,driver和car,然后diver.run(car)。而更好的设计是 不需要driver,或者把dirver看成Car的一个属性,这样就是Car.run()。第二种设计更符合面向对象的设计原则。这正是声明式API背后的原则,组件对自己负责

  • Kube API类似对象的接口,对象对修改封闭,对扩展开放。通过开放的API,用户可以很容易的实现功能扩展,但是你无法修改已有的组件,你可以开发自定义的组件来替换已有的组件

  • 可移植性的设计利用了类似面向对象的多态,同多定义抽象接口PVC,隐藏具体的实现细节。

希望本文的分享能帮助你理解K8s背后的设计原则。

参考:

推荐阅读

结合Kubernetes解读微服务的12要素

Kubernetes中Pod间共享内存方案

自动机器学习简述(AutoML)

Kubernetes设计的4个原则 关于作者:陶刚,Splunk资深软件工程师,架构师,毕业于北京邮电大学,现在在温哥华负责Splunk机器学习云平台的开发,曾经就职于SAP,EMC,Lucent等企业,拥有丰富的企业应用软件开发经验,熟悉软件开发的各种技术,平台和开发过程,在商务智能,机器学习,数据可视化,数据采集,网络管理等领域都有涉及。

Kubernetes设计的4个原则 关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!

Kubernetes设计的4个原则

在看点这里

Kubernetes设计的4个原则

本文分享自微信公众号 - EAWorld(eaworld)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
2个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
8个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这