k8s架构及核心组件介绍
Kubernetes(K8s)
一、Kubernetes
1、borg系统
Google的Borg系统运行几十万个以上的任务,来自几千个不同的应用,跨多个集群,每个集群(cell)有上万个机器。它通过管理控制、高效的任务包装、超售、和进程级别性能隔离实现了高利用率。它支持高可用性应用程序与运行时功能,最大限度地减少故障恢复时间,减少相关故障概率的调度策略。以下就是Borg的系统架构图。其中Scheduler负责任务的调度。
2、k8s基本介绍
就在Docker容器技术被炒得热火朝天之时,大家发现,如果想要将Docker应用于具体的业务实现,是存在困难的——编排、管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统,对Docker及容器进行更高级更灵活的管理。就在这个时候,K8S出现了。
K8S,就是基于容器的集群管理平台,它的全称,是kubernetes
由上图,
-
kubectl 客户端指令或者浏览器(可视化方式:rancher,dashboard..)发送请求;
-
Master节点: scheduler 调度器 ,负责计算该把pod调度到哪一个node节点;
-
Controllers : 控制器 ,负责维护node节点资源对象(deployment,rs,pod);
-
apiServer : 网关,所有请求都必须要经过网关;
-
etcd: 服务发现,注册,集群状态信息,调度信息;
-
node节点: 每一个node节点都运行一个kubelet进程,此进程负责本机服务的pod的创建维护;
-
Regitry: 镜像仓库—阿里镜像仓库—harbor构建一套自己的私有仓库;
3、k8s主要功能
Kubernetes是docker容器用来编排和管理的工具,它是基于Docker构建一个容器的调度服务,提供资源调度、均衡容灾、服务注册、动态扩缩容等功能套件。Kubernetes提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能如下:
-
数据卷: Pod中容器之间共享数据,可以使用数据卷。
-
应用程序健康检查: 容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。
-
复制应用程序实例: 控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用。
-
弹性伸缩: 根据设定的指标(CPU利用率)自动缩放Pod副本数。
-
服务发现: 使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。
-
负载均衡: 一组Pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。
-
滚动更新: 更新服务不中断,一次更新一个Pod,而不是同时删除整个服务。
-
服务编排: 通过文件描述部署服务,使得应用程序部署变得更高效。
-
资源监控: Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示。
-
提供认证和授权: 支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略。
4、k8s集群
这个集群主要包括两个部分:
-
一个Master节点(主节点)
-
一群Node节点(计算节点)
一看就明白:Master节点主要还是负责管理和控制。Node节点是工作负载节点,里面是具体的容器。
Kubernetes集群架构(高可用集群:多个master,每一个对应一群node节点)
1、一个master对应一群node节点,node节点负责存储pod;
2、node内部可以有一个pod,或者是多个pod,具体情况看pod所消耗的资源(cpu,内存),同时也必须看硬件资源;
3、pod是k8s操作最小单元,pod内部运行的是一个,或者多个容器。
问题: k8s是什么???
K8s是一个容器编排(管理)工具,但是k8s不直接管理docker容器,而是间接通过管理pod的管理(编排)容器。
4.1、Master 节点
Master节点包括API Server、Scheduler、Controller manager、etcd。
API Server 是整个系统的对外接口,供客户端和其它组件调用,相当于“营业厅”。
Scheduler 负责对集群内部的资源进行调度,相当于“调度室”。
Controller manager 负责管理控制器,相当于“大总管”。
4.2、node节点
Node节点包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可选),还有就是Pod
5、k8s master
5.1、api server
Kubernetes API Server: 所有的请求指令都必须经过 ApiServer 转发,集群的统一入口,各组件协调者,以HTTP API提供接口服务,所有对象资源的增删改查和监听操作都 交给APIServer处理后再提交给Etcd存储。
5.2、managerController
Kubernetes Controller: 处理集群中常规后台任务,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的各个资源控制器对于如下:
1)Replication Controller: 管理维护 Replication Controller,关联Replication Controller和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。
2)Node Controller: 管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点。
3)Namespace Controller: 管理维护Namespace,定期清理无效的Namespace,包括Namesapce下的API对象,比如Pod、Service等。
4)Service Controller: 管理维护Service,提供负载以及服务代理。
5)EndPoints Controller: 管理维护Endpoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints (即Pod Ip + Container Port)。
6)Service Account Controller: 管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret。
7)Persistent Volume Controller: 管理维护Persistent Volume和Persistent Volume Claim,为新的Persistent Volume Claim分配Persistent Volume进行绑定,为释放的Persistent Volume执行清理回收。
8)Daemon Set Controller: 管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node上正常的运行Daemon Pod。
9)Deployment Controller: 管理维护Deployment,关联Deployment和Replication Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication Controller和 Pod的更新。
10)Job Controller: 管理维护Job,为Jod创建一次性任务Pod,保证完成Job指定完成的任务数目
11)Pod Autoscaler Controller: 实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作
5.3、etcd
etcd 是一个分布式的、可靠的 key-value 存储系统,它用于存储分布式系统中的关键数据,这个定义非常重要。
etcd是一个第三方服务,分布式键值存储系统。用于保持集群状态,比如Pod、Service等对象信息
etcd是一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是:
1)网络插件flannel、对于其它网络插件也需要用到etcd存储网络的配置信息
2)kubernetes本身,包括各种对象的状态和元信息配置
5.4、scheduler
根据调度算法为新创建的Pod选择一个Node节点。 scheduler在整个系统中承担了承上启下的重要功能,承上是指它负责接收controller manager创建新的Pod,为其安排一个落脚的目标Node,启下是指安置工作完成后,目标Node上的kubelet服务进程接管后继工作。
也就是说scheduler的作用是通过调度算法为待调度Pod列表上的每一个Pod从Node列表中选择一个最合适的Node。
创建pod的流程:
1、kubeclt 发送创建的pod的指令,此时这个指令被apiserver拦截,把创建的pod存储在etcd;
2、schduler 发起调用请求,此时这个指令被apiserver拦截,获取etcd中 podQueue/NodeList
使用调度算法:
1)预选调度, 判断pod是否存在冲突/pod名称是否重复
2)优选策略, 找最优节点(cpu利用率最小的节点)
选择出一个合适的node节点
3、把选择合适的node,pod存储在etcd;
4、node节点上有一个kubelet进程,发送请求获取pod,node对应创建资源;
5、此时如果kubelet发现pod是本机节点需要创建的,kubelet就开始创建pod;
6、k8s node
6.1、kubelet
kubelet是Master在Node节点上的Agent,每个节点都会启动 kubelet进程,用来处理 Master 节点下发到本节点的任务,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、 下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器。
1、kubelet 默认监听四个端口,分别为 10250 、10255、10248、4194
-
10250(kubelet API):kubelet server 与 apiserver 通信的端口,定期请求 apiserver 获取自己所应当处理的任务,通过该端口可以访问获取 node 资源以及状态。
-
10248(健康检查端口):通过访问该端口可以判断 kubelet 是否正常工作, 通过 kubelet 的启动参数 --healthz-port 和 --healthz-bind-address 来指定监听的地址和端口。
-
4194(cAdvisor 监听):kublet 通过该端口可以获取到该节点的环境信息以及 node 上运行的容器状态等内容,访问 http://localhost:4194 可以看到 cAdvisor 的管理界面,通过 kubelet 的启动参数
--cadvisor-port
可以指定启动的端口。 -
10255 (readonly API):提供了 pod 和 node 的信息,接口以只读形式暴露出去,访问该端口不需要认证和鉴权。
6.2、kube-proxy
在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作,kube-proxy 本质上,类似一个反向代理. 我们可以把每个节点上运行的 kube-proxy 看作 service 的透明代理兼LB.
kube-proxy 监听 apiserver 中service 与Endpoint 的信息, 配置iptables 规则,请求通过iptables 直接转发给 pod
6.3、docker
运行容器的引擎。
6.4、pod
Pod是最小部署单元,一个Pod有一个或多个容器组成(一般情况下,pod内部只允许一个容器运行,便于管理),Pod中容器共享存储和网络,在同一台Docker主机上运行
Pod的特点:容器
1、有自己的IP地址
2、有自己的hostname
Pod实际上也相当于是一个独立的容器(虚拟机器),而这个pod容器内部封装的是由docker引擎所创建的容器,可以理解为pod就是一个虚拟化分组,pod内存可以存储一个或者多个容器。
Pod作用
Pod内部封装的是容器,容器内部运行是开发的应用程序。Pod管理上线的运行的应用程序
定义:在通常情况下,在服务上线部署的时候,pod通常被用来部署一组相关的服务。(什么一组相关的服务?)
一组相关服务: 在一个请求链路上的服务,叫做一组相关服务。通常情况下,这一组相关的服务在调用链路上处于上下游的关系。
经验来说(可维护的角度): 建议一个pod内部只允许部署一个容器(一个服务)。
问题:服务集群该如何部署????(pod内部运行就是容器,容器中运行的就是服务)
使用kubernetes构建服务集群,只需要创建多个部署了相同服务的pod即可。也就是说k8s可以实现一键式部署,一键式扩容
pod基本结构
Pause的作用:
我们看下在node节点上都会起很多pause容器,和pod是一一对应的。
每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中。同一个Pod里的容器之间仅需通过localhost就能互相通信。
kubernetes中的pause容器主要为每个业务容器提供以下功能:
PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
UTS命名空间:Pod中的多个容器共享一个主机名;
Volumes(共享存储卷):Pod中的各个容器可以访问在Pod级别定义的Volumes。
问题:假如一个Pod部署多个服务(如下图,nginx、web项目、MYSQL),它们如何通信?
在使用了pause容器创建共享网卡后,pod内部容器之间访问就使用localhost访问,就相当于本地访问一样,因此性能非常高。
注意: 一个pod不能分裂存储在多个node节点,但是多个pod副本可以随机分配到不同的node节点进行存储。
7、 Other组件
CoreDNS:可以为集群中的SVC创建一个域名IP的对应关系解析
DasHBoard:给 K8S 集群提供一个 B/S 结构访问体系
Ingress Controller:官方只能实现四层代理,INGRESS 可以实现七层代理
Federation:提供一个可以跨集群中心多K8S统一管理功能
Prometheus:提供K8S集群的监控能力
ELK:提供 K8S 集群日志统一分析介入平台
二、核心组件介绍
ReplicationController
用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代,而如果异常多出的容器也会自动回收。
副本控制器作用:永远保证服务数量和预期的数量保持一致。也就是说服务永远不会宕机,服务永不停机,服务永远处于高可用状态。
如果pod全部宕机则会全部重新创建。
注意:在新版本的 Kubernetes 中建议使用ReplicaSet 来取代ReplicationController
ReplicaSet
ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector
控制器和pod控制架构---副本控制器是如何控制pod副本的??
RS 和 RC 副本控制器到底有和区别? 为什么要是有RS,不使用RC呢?
1、RC只支持单个标签的选择器
2、RS不仅支持单个标签选择器,还支持复合选择器。
Labels: 标签,是用来唯一标识一个组件的,k8s中所有的资源对象都可以被标签类进行标识。通过标签标识后,方便,灵活的查询到这个组件。
查询一组相同业务pod:
app = MyAPP 此标签可以查询出下面4个pod.这4个pod是一组相关副本的pod. 标签相同,说明是同一个服务部署了多个副本。
标签选择器:
根据标签 key=value 查询与之对应的匹配的资源对象(pod,rs, deployment……)
标签选择器 – 标签 – 选择资源对象 (唯一定位一个资源对象)
复合选择器:支持多个标签选择器
Selector:
app = MyApp
release = stable
注意: 如果单独使用rs,就不支持滚动更新。要支持滚动更新还需要 Deployment。
Deployment
虽然ReplicaSet可以独立使用,但一般还是建议使用 Deployment 来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如 ReplicaSet 不支持 rolling-update 但 Deployment支持)
Deployment为Pod和ReplicaSet 提供了一个 声明式定义方法,用来替代以前的 ReplicationController 来方便的管理应用。
典型的应用场景:
(1)、定义Deployment 来创建 Pod 和 ReplicaSet
(2)、滚动升级和回滚应用
(3)、扩容和索容
(4)、暂停和继续 Deployment
Deployment不仅仅可以滚动更新,而且可以进行回滚,如果发现升级到V2版本后,发现服务不可用,可以回滚到V1版本。
资源对象组成关系:
1、deployment部署资源对象,管理rs ,支持滚动更新,更新模式就是新创建一个新的rs,然后由rs创建新的版本的pod.
2、rs副本控制器,控制pod的数量与预期的数量保持一致,rs副本控制器就是来管理pod.
注意:rs通过标签选择器选择受rs所管理的资源对象。
HPA(HorizontalPodAutoScale)
Horizontal Pod Autoscaling 仅适用于 Deployment 和 ReplicaSet,在V1版本中仅支持根据Pod的CPU利用率扩容,在vlalpha版本中,支持根据内存和用户自定义的metric扩缩容
HPA 自动更新 (k8s会根据CPU利用率来进行扩缩容),如果cpu利用率超过80%,此时就会对pod进行扩容,如果cpu利用率低于50%,对pod进行缩容
StatefullSet
StatefullSet 是为了解决有状态服务的问题(对应Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:
(1) 稳定的持久化存储,即Pod重新调度后还是能访问的相同持久化数据,基于PVC来实现
(2)稳定的网络标志,及Pod重新调度后其 PodName 和 HostName 不变,基于Headlesss Service(即没有 Cluster IP 的 Service)来实现。
(3)有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从 0 到 N-1,在下一个Pod运行之前所有之前的Pod必须都是Running 和 Ready 状态),基于 init containers 来实现。
(4)有序收缩,有序删除(即从N-1 到 0)
解析:
有状态:需要实时的进行数据更新及存储,把某个服务抽离出去,再加入回来就没有办法正常工作,这样的服务就是有>状态服务。 例如: mysql,Redis....
无状态:docker主要面对的是无状态服务,所谓的无状态服务就是没有对应的存储数据需要实时的保留,或者是把服务摘除后经过一段时间运行后再把服务放回去依然能够正常运行,就是无状态服务。 例如: Apache、lvs
DaemonSet
DaemonSet确保全部(或者一些 [ node打上污点(可以想象成一个标签),pod如果不定义容忍这个污点,那么pod就不会被调度器分配到这个node ])Node上运行一个Pod的副本。当有Node加入集群时,也会为他们新增一个Pod。当有Node从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除他创建的所有Pod,使用DaemonSet 的一些典型用法:
(1) 运行集群存储daemon,例如在每个Node上运行glustered,ceph
(2)在每个Node上运行日志收集Daemon,例如:fluentd、logstash.
(3)在每个Node上运行监控Daemon,例如:Prometheus Node Exporter
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束
Cron Job管理基于时间Job,即:
- 在给定时间点只运行一次
- 周期性地在给定时间点运行
Volume
数据卷,共享Pod中容器使用的数据。
Label
标签用于区分对象(比如Pod、Service),键/值对存在;每个对象可以有多个标签,通过标签关联对象。
Kubernetes中任意API对象都是通过Label进行标识,Label的实质是一系列的Key/Value键值对,其中key于value由用户自己指定。
Label可以附加在各种资源对象上,如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。
Label是Replication Controller和Service运行的基础,二者通过Label来进行关联Node上运行的Pod。
我们可以通过给指定的资源对象捆绑一个或者多个不同的Label来实现多维度的资源分组管理功能,以便于灵活、方便的进行资源分配、调度、配置等管理工作。 一些常用的Label如下:
版本标签:"release":"stable","release":"canary"......
环境标签:"environment":"dev","environment":"qa","environment":"production"
架构标签:"tier":"frontend","tier":"backend","tier":"middleware"
分区标签:"partition":"customerA","partition":"customerB"
质量管控标签:"track":"daily","track":"weekly"
Label相当于我们熟悉的标签,给某个资源对象定义一个Label就相当于给它大了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。
Label Selector在Kubernetes中重要使用场景如下: -> kube-Controller进程通过资源对象RC上定义Label Selector来筛选要监控的Pod副本的数量,从而实现副本数量始终符合预期设定的全自动控制流程;
-> kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立起每个Service岛对应Pod的请求转发路由表,从而实现Service的智能负载均衡;
-> 通过对某些Node定义特定的Label,并且在Pod定义文件中使用Nodeselector这种标签调度策略,kuber-scheduler进程可以实现Pod”定向调度“的特性;
转载自:https://juejin.cn/post/7242512226917580855