基本知识
在Kubernetes中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征:
唯一指定的名称(如mysql-server)
一个虚拟IP和端口号
能提供某种远程服务能力
被映射到提供这种服务能力的一组容器应用上
Pod简介
首先,Pod运行在一个被称为节点(Node)的环境中,节点可以是物理机,也可以是私有云或公有云中的虚拟机,通常在一个节点上运行几百个Pod。
其次,每个Pod中都存在一个特殊的叫做Pause的容器,其他容器为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷。
集群管理
k8s将集群中的机器划分为一个Master和一些Node。
Master上运行着集群管理相关的一组进程kube-apiserver、kube0controller-manager和kubescheduler,这些实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,且都是自动完成的。
Node上运行着kubelet、kube-proxy服务进程负责Pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。
服务扩容和服务升级的全新解决方案
在传统IT系统中,这两个难题基本靠人工操作才能解决,费时费力且难以保证实施质量
在k8s中,则只需为需要扩容的Service关联的Pod创建一个RC(Replication Controller),服务扩容和服务升级问题即可迎刃而解。有了RC,服务扩容和服务升级就变成一个纯粹的简单数字游戏了,只需修改RC中的副本数量即可。
Kubernetes的基本概念和术语
思想: k8s中大部分的概念都可以被看作一种资源对象,几乎都可以通过kubectl工具执行增删改查操作并将其持久化存储在etcd中。k8s通过跟踪对比etcd中保存的“资源期待状态”和当前环境中的“实际资源状态”的差异来实现自动控制和自动纠错的高级功能。
Master
集群控制节点,负责整个Kubernetes集群的管理和控制,通常需要单独占据一个服务器(高可用部署建议用3台服务器),因为Master非常的重要。万一Master节点发生宕机或不可用,整个集群的容器内应用将全部失效。
执行在Master上的关键进程:
Kubernetes API Server(kube-apiserver):提供HTTP Rest接口的关键服务进程,所有资源增删改查操作的唯一入口,也是集群控制的入口进程。
Kubernetes Controller Manager(kube-controller-manager):k8s中所有资源对象的自动化控制中心。
Kubernetes Scheduler(kube-scheduler):负责资源调度(Pod 调度)的进程。
此外,Master节点还需要部署etcd服务,因为所有的资源对象的数据都要被保存在etcd中。
Node
kubernetes中除了Master外的其他机器都被称为Node。Node是k8s集群中的负载节点,被Master分配一些工作负载(Docker容器),当某个Node发生宕机时,其上的工作负载会被Master自动转移到其他节点上。
Node上的关键进程:
kubelet:负责Pod对应容器的创建、启停等任务,同时与Master节点密切协作,实现集群管理的基本功能。
kube-proxy:实现Kubenetes Service的通信和负载均衡机制的重要组件。
Docker Engine(docker):Docker引擎,负责本机容器的创建和管理。
一旦Node被纳入集群,kubelet进程会定时向Master节点汇报自身的情况,如操作系统、Docker版本、机器的CPU和内存情况,以及当前有哪些Pod在运行等,这样Master就可以获知每个Node的资源使用情况来实现高效均衡等资源调度策略。
如果某个Node在指定时间内没有上报信息,则会被Master判定了“失联”状态,将被标记为不可用(Not Ready)状态,随后Master会自动触发“工作负载转移流程”。
Pod
Pod是K8S中最重要的基本概念。
Pod的组成结构:
为什么设计成这样?
Pod作为一组容器的单位,在这种情况下,就比较难的对整体进行判断及有效的行动。而引入业务无关且不易死亡的Pause容器作为Pod的根容器,就能够以它的状态来代表整个容器组的状态,从而简单、巧妙的解决了这个难题。
Pod中多个业务容器共享Pause容器的IP和挂载的Volume,这样不仅解决了密切关联的业务容器之间的通信问题,而且解决了它们之间的文件共享问题。
Pod、容器与Node的关系:
普通的Pod一旦被创建,就会被放入到etcd中,然后被Master节点调度到某个具体的Node上并进行绑定,最后Node上的kubelet进程将把Pod实例化成一组相关的Docker容器并启动。
异常处理:
当Pod中的某个容器停止时,k8s可以自动检测到这个问题,让重新启动这个Pod(重启Pod中的所有容器)。
当Node发生宕机时,该Node上所有的Pod将会被重新调度到其他节点上。
Label
一个key=value的键值对,由用户自己指定。
Label可被附加在各种资源对象上,一个资源对象可以被定义任意数量的Label。Label就相当于我们熟悉的“标签”,给资源对象定义一个Label就是给它打了一个标签,而之后呢就可以通过标签选择器来查询和筛选拥有某些Label的资源对象。
在Pod,Label被定义在metadata中。
在RC和Service中,则被定义在Seletor字段来关联Pod。
使用场景:
kube-controller进程通过在RC上定义的Label Selector来筛选需要监控的Pod副本数量。
kube-proxy进程利用Service定义的Lable Selector,来自动建立每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制。
在Pod定义文件中使用NodeSelector标签,可以实现Pod的定向调度。
总之,使用Label可以给对象创建多组标签,Label和Label Selector共同构成了K8S系统中核心的应用模型,使得被管理对象能够被精细地分组管理,同时实现了整个集群的高可用性。
Replication Controller(RC)
RC定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,因此RC的定义包含如下:
Pod的期待数量
筛选目标Pod的Label Selector
当Pod数量小于预期值时,用于创建新Pod的Pod模版
特性与作用:
包括完整的Pod定义模版
通过Label Selector机制实现对Pod副本的自动控制
改变RC里Pod副本数量,实现Pod的扩容和缩容
改变RC里Pod模版中的镜像版本,实现Pod的滚动升级
Deployment
相当于升级版的RC,用于更好地解决Pod的编排问题。最大的一个升级就是我们可以随时知道当前Pod“部署”的进度。
使用场景:
创建一个Deployment对象来生成对应的Replica Set,并完成Pod副本的创建
检查Deployment的状态来看部署动作是否完成
更新Deployment来创建新的Pod(镜像升级)
回滚到早先一个Deployment版本
暂停Deployment以便于一次性修改多个PodTemplateSpec配置,之后再恢复D,进行新的发布
扩展Deployment以应对高负载
查看Deployment状态,以此作为发布是否成功的指标
清理不再需要的旧版本ReplicaSets
Horizontal Pod Autoscaler
Pod横向自动扩容(HPA),根据应用自定义的指标进行自动扩容和缩容。
HPA有以下两种方式作为Pod负载的度量指标:
CPUUtilizationPercentage:目标Pod所有副本自身的CPU利用率的平均值。
应用自定义的度量指标,如QPS
StatefulSet
面向有状态服务的Pod管理对象。
特点:
StatefulSet里每个Pod都有稳定、唯一的网络标识,这样可以用来发现集群内的其他成员
Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
Pod采用稳定的持久化存储卷,删除Pod时默认是不会删除与StatefulSet相关的存储卷的,这样可以保证数据安全
Service
等价于微服务架构中的一个微服务
Pod、RC、Service的逻辑关系
Service 定义了一个服务的访问入口地址,前端的Pod通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,Service与其后端Pod副本集群之间则是通过Label Selector来实现无缝对接的。
k8s如何实现负载均衡?
运行在Node上的kube-proxy进程就是一个智能的软件负载均衡器,负责把对Service的请求转发到后端的某个Pod实例上,并在内部实现了服务的负载均衡与会话保持机制。
Job
批处理任务
特点:
Job控制的Pod副本是短暂运行的,所有Pod副本运行结束之后,对应的Job也就结束了。
多实例并行计算
Volume
Pod中能被多个容器访问的共享目录
特点:
被定义在Pod上,被一个Pod中的多个容器共享
生命周期与Pod相同,和容器生命周期不相关,容器终止或重启也不会丢失Volume的数据
Persistent Volume
PV可以被理解成Kubernetes集群中的某个网络存储对应的一块存储,和Volume类似,但有以下区别:
PV只能是网络存储,不属于任何Node,但可以在每个Node上访问
PV不是被定义在Pod上的,而是独立于Pod之外定义的
Namespace
Namespace通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,来实现多租户的资源隔离。
注:如果不特别指明Namespace,则用户创建的Pod、RC、Service都将被系统创建到这个默认的名为default的Namespace中。
Annotation
kv形式的定义,为用户任意定义的附加信息,以便于外部工具查找。
ConfigMap
解决配置文件中的参数在应用运行期如何修改的问题。分布式系统中最简单且对应用无侵入对配置中心。
设计实现:
首先,所有配置都当作kv字符串,这些配置项作为Map表中的一个项,并持久化在etcd中,上述专门用来保存配置参数的Map就是ConfigMap资源对象。
接下来,ConfigMap通过Volumn映射的方式编程目标Pod内的配置文件,这样不管目标Pod被调度到哪台服务器上,都能完成自动映射。如果ConfigMap中的kv被修改,Pod中的“配置文件”也会自动更新。