Kubernetes系列02—Kubernetes设计架构和设计理念

原文: Kubernetes系列02—Kubernetes设计架构和设计理念

本文收录在容器技术学习系列文章总目录html

1Kubernetes设计架构

Kubernetes集群包含有节点代理kubeletMaster组件(APIs, scheduler, etc),一切都基于分布式的存储系统。下面这张图是Kubernetes的架构图。node

 

2Kubernetes节点

2.1 介绍

在这张系统架构图中,咱们把服务分为运行在工做节点上的服务组成集群级别控制板的服务git

② Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。github

 每次个节点上固然都要运行DockerDocker来负责全部具体的映像下载和容器运行。算法

④ Kubernetes主要由如下几个核心组件组成:数据库

  • etcd 保存了整个集群的状态;
  • apiserver 提供了资源操做的惟一入口,并提供认证、受权、访问控制、API注册和发现等机制;
  • controller manager 负责维护集群的状态,好比故障检测、自动扩展、滚动更新等;
  • scheduler 负责资源的调度,按照预约的调度策略将Pod调度到相应的机器上;
  • kubelet 负责维护容器的生命周期,同时也负责VolumeCVI)和网络(CNI)的管理;
  • Container runtime 负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的Add-ons后端

  • kube-dns 负责为整个集群提供DNS服务
  • Ingress Controller 为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

 

2.2 示意图

1kubernetes masterapi

 

2kubernetes node安全

 

3、分层架构

Kubernetes设计理念和功能其实就是一个相似Linux的分层架构,以下图所示服务器

  •  核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
  •  应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
  •  管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBACQuotaPSPNetworkPolicy等)
  •  接口层:kubectl命令行工具、客户端SDK以及集群联邦
  •  生态系统:在接口层之上的庞大容器集群管理调度的生态系统,能够划分为两个范畴
    •  Kubernetes外部:日志、监控、配置管理、CICDWorkflowFaaSOTS应用、ChatOps
    •  Kubernetes内部:CRICNICVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

 

4K8S相关名字解释

1kubelet

kubelet负责管理pods和它们上面的容器,images镜像、volumesetc

 

2kube-proxy

  每个节点也运行一个简单的网络代理和负载均衡(详见services FAQ )PS:官方 英文)。 正如Kubernetes API里面定义的这些服务(详见the services doc)(PS:官方 英文)也能够在各类终端中以轮询的方式作一些简单的TCPUDP传输。

  服务端点目前是经过DNS或者环境变量( Docker-links-compatible Kubernetes{FOO}_SERVICE_HOST  {FOO}_SERVICE_PORT 变量都支持)。这些变量由服务代理所管理的端口来解析。

 

3Kubernetes控制面板

  Kubernetes控制面板能够分为多个部分。目前它们都运行在一个master 节点,然而为了达到高可用性,这须要改变。不一样部分一块儿协做提供一个统一的关于集群的视图。

 

4etcd

  全部master的持续状态都存在etcd的一个实例中。这能够很好地存储配置数据。由于有watch(观察者)的支持,各部件协调中的改变能够很快被察觉。

 

5Kubernetes API Server

  API服务提供Kubernetes API PS:官方 英文)的服务。这个服务试图经过把全部或者大部分的业务逻辑放到不两只的部件中从而使其具备CRUD特性。它主要处理REST操做,在etcd中验证更新这些对象(并最终存储)。

 

6Scheduler

  调度器把未调度的pod经过binding api绑定到节点上。调度器是可插拔的,而且咱们期待支持多集群的调度,将来甚至但愿能够支持用户自定义的调度器。

 

7Kubernetes控制管理服务器

  全部其它的集群级别的功能目前都是由控制管理器所负责。例如,端点对象是被端点控制器来建立和更新。这些最终能够被分隔成不一样的部件来让它们独自的可插拔。

  replicationcontrollerPS:官方 英文)是一种创建于简单的 pod API之上的一种机制。一旦实现,咱们最终计划把这变成一种通用的插件机制。

 

5kubernetes设计理念

5.1 Kubernetes设计理念与分布式系统

  分析和理解Kubernetes的设计理念可使咱们更深刻地了解Kubernetes系统,更好地利用它管理分布式部署的云原生应用,另外一方面也可让咱们借鉴其在分布式系统设计方面的经验。

 1API设计原则

  对于云计算系统,系统API实际上处于系统设计的统领地位,正如本文前面所说,K8s集群系统每支持一项新功能,引入一项新技术,必定会新引入对应的API对象,支持对该功能的管理操做,理解掌握的API,就比如抓住了K8s系统的牛鼻子。K8s系统API的设计有如下几条原则:

  •  全部API应该是声明式的。正如前文所说,声明式的操做,相对于命令式操做,对于重复操做的效果是稳定的,这对于容易出现数据丢失或重复的分布式环境来讲是很重要的。另外,声明式操做更容易被用户使用,可使系统向用户隐藏实现的细节,隐藏实现的细节的同时,也就保留了系统将来持续优化的可能性。此外,声明式的API,同时隐含了全部的API对象都是名词性质的,例如ServiceVolume这些API都是名词,这些名词描述了用户所指望获得的一个目标分布式对象。
  •  API对象是彼此互补并且可组合的。这里面实际是鼓励API对象尽可能实现面向对象设计时的要求,即高内聚,松耦合,对业务相关的概念有一个合适的分解,提升分解出来的对象的可重用性。事实上,K8s这种分布式系统管理平台,也是一种业务系统,只不过它的业务就是调度和管理容器服务。
  •  高层API以操做意图为基础设计。如何可以设计好API,跟如何能用面向对象的方法设计好应用系统有相通的地方,高层设计必定是从业务出发,而不是过早的从技术实现出发。所以,针对K8s的高层API设计,必定是以K8s的业务为基础出发,也就是以系统调度管理容器的操做意图为基础设计。
  •  低层API根据高层API的控制须要设计。设计实现低层API的目的,是为了被高层API使用,考虑减小冗余、提升重用性的目的,低层API的设计也要以需求为基础,要尽可能抵抗受技术实现影响的诱惑。
  •  尽可能避免简单封装,不要有在外部API没法显式知道的内部隐藏的机制。简单的封装,实际没有提供新的功能,反而增长了对所封装API的依赖性。内部隐藏的机制也是很是不利于系统维护的设计方式,例如PetSetReplicaSet,原本就是两种Pod集合,那么K8s就用不一样API对象来定义它们,而不会说只用同一个ReplicaSet,内部经过特殊的算法再来区分这个ReplicaSet是有状态的仍是无状态。
  •  API操做复杂度与对象数量成正比。这一条主要是从系统性能角度考虑,要保证整个系统随着系统规模的扩大,性能不会迅速变慢到没法使用,那么最低的限定就是API的操做复杂度不能超过O(N)N是对象的数量,不然系统就不具有水平伸缩性了。
  •  API对象状态不能依赖于网络链接状态。因为众所周知,在分布式环境下,网络链接断开是常常发生的事情,所以要保证API对象状态能应对网络的不稳定,API对象的状态就不能依赖于网络链接状态。
  •  尽可能避免让操做机制依赖于全局状态,由于在分布式系统中要保证全局状态的同步是很是困难的。

 

2)控制机制设计原则

  •  控制逻辑应该只依赖于当前状态。这是为了保证分布式系统的稳定可靠,对于常常出现局部错误的分布式系统,若是控制逻辑只依赖当前状态,那么就很是容易将一个暂时出现故障的系统恢复到正常状态,由于你只要将该系统重置到某个稳定状态,就能够自信的知道系统的全部控制逻辑会开始按照正常方式运行。
  •  假设任何错误的可能,并作容错处理。在一个分布式系统中出现局部和临时错误是大几率事件。错误可能来自于物理系统故障,外部系统故障也可能来自于系统自身的代码错误,依靠本身实现的代码不会出错来保证系统稳定其实也是难以实现的,所以要设计对任何可能错误的容错处理。
  •  尽可能避免复杂状态机,控制逻辑不要依赖没法监控的内部状态。由于分布式系统各个子系统都是不能严格经过程序内部保持同步的,因此若是两个子系统的控制逻辑若是互相有影响,那么子系统就必定要能互相访问到影响控制逻辑的状态,不然,就等同于系统里存在不肯定的控制逻辑。
  •  假设任何操做均可能被任何操做对象拒绝,甚至被错误解析。因为分布式系统的复杂性以及各子系统的相对独立性,不一样子系统常常来自不一样的开发团队,因此不能奢望任何操做被另外一个子系统以正确的方式处理,要保证出现错误的时候,操做级别的错误不会影响到系统稳定性。
  •  每一个模块均可以在出错后自动恢复。因为分布式系统中没法保证系统各个模块是始终链接的,所以每一个模块要有自我修复的能力,保证不会由于链接不到其余模块而自我崩溃。
  •  每一个模块均可以在必要时优雅地降级服务。所谓优雅地降级服务,是对系统鲁棒性的要求,即要求在设计实现模块时划分清楚基本功能和高级功能,保证基本功能不会依赖高级功能,这样同时就保证了不会由于高级功能出现故障而致使整个模块崩溃。根据这种理念实现的系统,也更容易快速地增长新的高级功能,觉得没必要担忧引入高级功能影响原有的基本功能。

 

5.2 Kubernetes的核心技术概念和API对象

  API对象是K8s集群中的管理操做单元K8s集群系统每支持一项新功能,引入一项新技术,必定会新引入对应的API对象,支持对该功能的管理操做。例如副本集Replica Set对应的API对象是RS

  每一个API对象都有3大类属性:元数据metadata、规范spec和状态status。元数据是用来标识API对象的,每一个对象都至少有3个元数据:namespacenameuid;除此之外还有各类各样的标签labels用来标识和匹配不一样的对象,例如用户能够用标签env来标识区分不一样的服务部署环境,分别用env=devenv=testingenv=production来标识开发、测试、生产的不一样服务。规范描述了用户指望K8s集群中的分布式系统达到的理想状态(Desired State),例如用户能够经过复制控制器Replication Controller设置指望的Pod副本数为3status描述了系统实际当前达到的状态(Status),例如系统当前实际的Pod副本数为2;那么复制控制器当前的程序逻辑就是自动启动新的Pod,争取达到副本数为3

  K8s中全部的配置都是经过API对象的spec去设置的,也就是用户经过配置系统的理想状态来改变系统,这是k8s重要设计理念之一,即全部的操做都是声明式(Declarative)的而不是命令式Imperative)的。声明式操做在分布式系统中的好处是稳定,不怕丢操做或运行屡次,例如设置副本数为3的操做运行屡次也仍是一个结果,而给副本数加1的操做就不是声明式的,运行屡次结果就错了。

 

1Pod

  K8s有不少技术概念,同时对应不少API对象,最重要的也是最基础的是微服务PodPod是在K8s集群中运行部署应用或服务的最小单元,它是能够支持多容器的Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,能够经过进程间通讯和文件共享这种简单高效的方式组合完成服务。Pod对多容器的支持是K8s最基础的设计理念。好比你运行一个操做系统发行版的软件仓库,一个Nginx容器用来发布软件,另外一个容器专门用来从源仓库作同步,这两个容器的镜像不太多是一个团队开发的,可是他们一起工做才能提供一个微服务;这种状况下,不一样的团队各自开发构建本身的容器镜像,在部署的时候组合成一个微服务对外提供服务。

  PodK8s集群中全部业务类型的基础,能够看做运行在K8s集群中的小机器人,不一样类型的业务就须要不一样类型的小机器人去执行。目前K8s中的业务主要能够分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人控制器为DeploymentJobDaemonSetPetSet,本文后面会一一介绍。

 

2)复制控制器(Replication ControllerRC

  RCK8s集群中最先的保证Pod高可用的API对象。经过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目能够是多个也能够是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。即便在指定数目为1的状况下,经过RC运行Pod也比直接运行Pod更明智,由于RC也能够发挥它高可用的能力,保证永远有1Pod在运行。RCK8s较早期的技术概念,只适用于长期伺服型的业务类型,好比控制小机器人提供高可用的Web服务。

 

3)副本集(Replica SetRS

  RS是新一代RC,提供一样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象通常不单独使用,而是做为Deployment的理想状态参数使用。

 

4)部署(Deployment)

  部署表示用户对K8s集群的一次更新操做。部署是一个比RS应用模式更广的API对象,能够是建立一个新的服务,更新一个新的服务,也能够是滚动升级一个服务。滚动升级一个服务,实际是建立一个新的RS,而后逐渐将新RS中副本数增长到理想状态,将旧RS中的副本数减少到0的复合操做;这样一个复合操做用一个RS是不太好描述的,因此用一个更通用的Deployment来描述。以K8s的发展方向,将来对全部长期伺服型的的业务的管理,都会经过Deployment来管理。

 

5)服务(Service

  RCRSDeployment只是保证了支撑服务的微服务Pod的数量,可是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上中止,在另外一个节点以一个新的IP启动一个新的Pod,所以不能以肯定的IP和端口号提供服务。要稳定地提供服务须要服务发现和负载均衡能力。服务发现完成的工做,是针对客户端访问的服务,找到对应的的后端服务实例。在K8s集群中,客户端须要访问的服务就是Service对象。每一个Service会对应一个集群内部有效的虚拟IP,集群内部经过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由Kube-proxy实现的Kube-proxyK8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每一个节点上都有一个;这一设计体现了它的伸缩性优点,须要访问服务的节点越多,提供负载均衡能力的Kube-proxy就越多,高可用节点也随之增多。与之相比,咱们平时在服务器端作个反向代理作负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。

 

6)任务(Job

  JobK8s用来控制批处理型任务的API对象。批处理业务与长期伺服业务的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不中止的状况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不一样的spec.completions策略而不一样:单Pod型任务有一个Pod成功就标志完成;定数成功型任务保证有N个任务所有成功;工做队列型任务根据应用确认的全局成功而标志成功。

 

7)后台支撑服务集(DaemonSet

  长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类Pod运行;然后台支撑型服务的核心关注点在K8s集群中的节点(物理机或虚拟机),要保证每一个节点上都有一个此类Pod运行。节点多是全部集群节点也多是经过nodeSelector选定的一些特定节点。典型的后台支撑型服务包括,存储,日志和监控等在每一个节点上支持K8s集群运行的服务

 

8)有状态服务集(PetSet

  K8s1.3版本里发布了Alpha版的PetSet功能。在云原生应用的体系里,有下面两组近义词;第一组是无状态(stateless)、牲畜(cattle)、无名(nameless)、可丢弃(disposable);第二组是有状态(stateful)、宠物(pet)、有名(having name)、不可丢弃(non-disposable)。RCRS主要是控制提供无状态服务的,其所控制的Pod的名字是随机设置的,一个Pod出故障了就被丢弃掉,在另外一个地方重启一个新的Pod,名字变了、名字和启动在哪儿都不重要,重要的只是Pod总数;而PetSet是用来控制有状态服务,PetSet中的每一个Pod的名字都是事先肯定的,不能更改。PetSetPod的名字的做用,并非《千与千寻》的人性缘由,而是关联与该Pod对应的状态。

  对于RCRS中的Pod,通常不挂载存储或者挂载共享存储,保存的是全部Pod共享的状态,Pod像牲畜同样没有分别(这彷佛也确实意味着失去了人性特征);对于PetSet中的Pod,每一个Pod挂载本身独立的存储,若是一个Pod出现故障,从其余节点启动一个一样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。

  适合于PetSet的业务包括数据库服务MySQLPostgreSQL,集群化管理服务Zookeeperetcd等有状态服务。PetSet的另外一种典型应用场景是做为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员须要不断地维护它,容器刚开始流行时,咱们用容器来模拟虚拟机使用,全部状态都保存在容器里,而这已被证实是很是不安全、不可靠的。使用PetSetPod仍然能够经过漂移到不一样节点提供高可用,而存储也能够经过外挂的存储来提供高可靠性,PetSet作的只是将肯定的Pod与肯定的存储关联起来保证状态的连续性。PetSet还只在Alpha阶段,后面的设计如何演变,咱们还要继续观察。

 

9)集群联邦(Federation

  K8s1.3版本里发布了beta版的Federation功能。在云计算环境中,服务的做用距离范围从近到远通常能够有:同主机(HostNode)、跨主机同可用区(Available Zone)、跨可用区同地区(Region)、跨地区同服务商(Cloud Service Provider)、跨云平台。K8s的设计定位是单一集群在同一个地域内,由于同一个地区的网络性能才能知足K8s的调度和计算存储链接要求。而联合集群服务就是为提供跨Region跨服务商K8s集群服务而设计的。

  每一个K8s Federation有本身的分布式存储、API ServerController Manager。用户能够经过FederationAPI Server注册该Federation的成员K8s Cluster。当用户经过FederationAPI Server建立、更改API对象时,Federation API Server会在本身全部注册的子K8s Cluster都建立一份对应的API对象。在提供业务请求服务时,K8s Federation会先在本身的各个子Cluster之间作负载均衡,而对于发送到某个具体K8s Cluster的业务请求,会依照这个K8s Cluster独立提供服务时同样的调度模式去作K8s Cluster内部的负载均衡。而Cluster之间的负载均衡是经过域名服务的负载均衡来实现的。

  全部的设计都尽可能不影响K8s Cluster现有的工做机制,这样对于每一个子K8s集群来讲,并不须要更外层的有一个K8s Federation,也就是意味着全部现有的K8s代码和机制不须要由于Federation功能有任何变化。

 

10)存储卷(Volume

  K8s集群中的存储卷跟Docker的存储卷有些相似,只不过Docker的存储卷做用范围为一个容器,而K8s的存储卷的生命周期和做用范围是一个Pod。每一个Pod中声明的存储卷由Pod中的全部容器共享。K8s支持很是多的存储卷类型,特别的,支持多种公有云平台的存储,包括AWSGoogleAzure云;支持多种分布式存储包括GlusterFSCeph;也支持较容易使用的主机本地目录hostPathNFSK8s还支持使用Persistent Volume ClaimPVC这种逻辑存储,使用这种存储,使得存储的使用者能够忽略后台的实际存储技术(例如AWSGoogleGlusterFSCeph),而将有关存储实际技术的配置交给存储管理员经过Persistent Volume来配置。

 

11)持久存储卷(Persistent VolumePV)和持久存储卷声明(Persistent Volume ClaimPVC

  PVPVC使得K8s集群具有了存储的逻辑抽象能力,使得在配置Pod的逻辑里能够忽略对实际后台存储技术的配置,而把这项配置的工做交给PV的配置者,即集群的管理者。存储的PVPVC的这种关系,跟计算的NodePod的关系是很是相似的;PVNode是资源的提供者,根据集群的基础设施变化而变化,由K8s集群管理员配置;而PVCPod是资源的使用者,根据业务服务的需求变化而变化,有K8s集群的使用者即服务的管理员来配置。

 

12)节点(Node

  K8s集群中的计算能力由Node提供,最初Node称为服务节点Minion,后来更名为NodeK8s集群中的Node也就等同于Mesos集群中的Slave节点,是全部Pod运行所在的工做主机,能够是物理机也能够是虚拟机。不管是物理机仍是虚拟机,工做主机的统一特征是上面要运行kubelet管理节点上运行的容器。

 

13)密钥对象(Secret

  Secret是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。使用Secret的好处是能够避免把敏感信息明文写在配置文件里。在K8s集群中配置和使用服务不可避免的要用到各类敏感信息实现登陆、认证等功能,例如访问AWS存储的用户名密码。为了不将相似的敏感信息明文写在全部须要使用的配置文件中,能够将这些信息存入一个Secret对象,而在配置文件中经过Secret对象引用这些敏感信息。这种方式的好处包括:意图明确,避免重复,减小暴漏机会。

 

14)用户账户(User Account)和服务账户(Service Account

  顾名思义,用户账户为人提供帐户标识,而服务帐户为计算机进程和K8s集群中运行的Pod提供帐户标识。用户账户和服务账户的一个区别是做用范围;用户账户对应的是人的身份,人的身份与服务的namespace无关,因此用户帐户是跨namespace的;而服务账户对应的是一个运行中程序的身份,与特定namespace是相关的。

 

15)名称空间(Namespace

  名称空间为K8s集群提供虚拟的隔离做用K8s集群初始有两个名字空间,分别是默认名称空间default和系统名称空间kube-system,除此之外,管理员能够能够建立新的名字空间知足须要。

 

16RBAC访问受权

  K8s1.3版本中发布了alpha版的基于角色的访问控制(Role-based Access ControlRBAC)的受权模式。相对于基于属性的访问控制(Attribute-based Access ControlABAC),RBAC主要是引入了角色(Role)和角色绑定(RoleBinding)的抽象概念。在ABAC中,K8s集群中的访问策略只能跟用户直接关联;而在RBAC中,访问策略能够跟某个角色关联,具体的用户在跟一个或多个角色相关联。显然,RBAC像其余新功能同样,每次引入新功能,都会引入新的API对象,从而引入新的概念抽象,而这一新的概念抽象必定会使集群服务管理和使用更容易扩展和重用。

 

5.3 总结

  从K8s的系统架构、技术概念和设计理念,咱们能够看到K8s系统最核心的两个设计理念:一个是容错性,一个是易扩展性。容错性实际是保证K8s系统稳定性和安全性的基础,易扩展性是保证K8s对变动友好,能够快速迭代增长新功能的基础。

  本文设计的全部知识点只是在本篇总结说起;后续会有多篇文章详细介绍K8S的各个知识点。

相关文章
相关标签/搜索