k8s 集群架构
# 基础架构
集群:cluster = Master+ node
Master 节点主要还是负责管理和控制。
Node节点是工作负载节点,里面是具体的容器。
# Master
Master节点包括API Server、Scheduler、Controller manager、etcd
API server
: 是整个系统的对外接口,供客户端和其它组件调用,相当于“营业厅”Scheduler
: cheduler负责对集群内部的资源进行调度,相当于“调度室”Controller mannger
: 负责管理控制器,相当于“大总管”etcd
: 资料库,用来做服务注册与发现和配置中心
# 1. api server
- Kubernetes API Server: Kubernetes API,集群的统一入口,各组件协调者,以HTTP API提供接口服务,所有对象资源的增删改查和监听操作都 交给APIServer处理后再提交给Etcd存储。
# 2. Contraoller mannger
Replication Controller
: 管理维护Replication Controller,关联Replication Controller和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。副本控制器 — 实现副本数量和预期设定的数量永远保持一致。 例如: 构建集群 : 6台服务器集群 — k8s部署:预期设定数量=6 ,k8s能永远保证副本数据量一致等于6
Node Controller
: 管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点。检查node节点监控状况;由k8s本身内部实现的。
Namespace Controller
: 管理维护Namespace,定期清理无效的Namespace,包括Namesapce下的API对象,比如Pod、Service等。创建pod,会把pod分配在不同命名空间下,定期清理无效的namespace
Service Controller
: 管理维护Service(虚拟IP) ,提供负载以及服务代理。虚拟服务控制器,维护虚拟ip,提供负载均衡。
EndPoints Controller
: 管理维护Endpoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints (即Pod Ip + Container Port)。提供了pod,service关联服务。
Service Account Controller
: 管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret。安全认证
Persistent Volume Controller
: 管理维护Persistent Volume和Persistent Volume Claim,为新的Persistent Volume Claim分配Persistent Volume进行绑定,为释放的Persistent Volume执行清理回收。持久化数据卷控制器,给有状态服务部署控制器用的,数据持久化存储 PVC
DaemonSet Controller
: 管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node上正常的运行Daemon Pod。让每一个node节点都运行相同的服务
Deployment Controller
: 管理维护Deployment,关联Deployment和Replication Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication Controller和 Pod的更新。无状态服务部署的控制器,支持滚动更新
Job Controller
: 管理维护Job,为Jod创建一次性任务Pod,保证完成Job指定完成的任务数目定时任务控制器
Pod Autoscaler Controller
: 实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作自动更新控制器,可以根据指定条件自动扩容。
# 3. scheduler
根据调度算法为新创建的Pod选择一个Node节点。 scheduler在整个系统中承担了承上启下的重要功能,承上是指它负责接收controller manager创建新的Pod,为其安排一个落脚的目标Node,启下是指安置工作完成后,目标Node上的kubelet服务进程接管后继工作。
scheduler的作用是通过调度算法为待调度Pod列表上的每一个Pod从Node列表中选择一个最合适的Node。
- podQueue (即将要创建的pod进行排队)
- nodeList (存储pod的节点的集合)
- scheduler通过调度策略算法把pod 和 某一个node进行配对,存储在etcd,node节点kubelet监控到数据,把pod获取到在本地创建pod.
# 4. etcd
- etcd是一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。
- Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是:
- 网络插件flannel、对于其它网络插件也需要用到etcd存储网络的配置信息
- kubernetes本身,包括各种对象的状态和元信息配置
# Node
Node节点包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可选)、Pod
Pod
: 是k8s管理的最小的基本单元。Pod内部可以运行一个或者多个容器。一般情况下,pod内部只允许一个容器运行,便于管理。pod是一个用来封装容器的容器。Docker
: docker引擎,pod内部运行的都是容器,这个容器是由docker引擎创建的,docker引擎是node节点基础服务。Kubelet
: node节点代理,kubelet代理master节点请求,在本地node节点执行;监听etcd,获取指令管理pod,kubelet是真正管理pod的组件。Kube-proxy
: 代理服务 ,主要是用来生成网络规则,创建访问路由,创建service网络访问规则,负载均衡规则,即设置iptables负载规则,更新service虚拟endpointsFluentd
: 日志收集组件
# 1. kubelet
kubelet负责管理pods和它们上面的容器,images镜像、volumes、etc
kubelet 是 k8s 在node节点上的代理服务。pod的CRUD的是由node节点上kubelet来进行操作。kubelet实际上就相当于链式调用,上游服务是master(scheduler,apiserver),由node的kubelet接受请求,执行具体操作。
- kubelet是Master在Node节点上的Agent,每个节点都会启动 kubelet进程,用来处理 Master 节点下发到本节点的任务,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、 下载secret、获取容器和节点状态等工作。
- 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 的信息,接口以只读形式暴露出去,访问该端口不需要认证和鉴权。
# 2. kube-proy
在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作,kube-proxy 本质上,类似一个反向代理. 我们可以把每个节点上运行的 kube-proxy 看作 service 的透明代理兼LB.
- kube-proxy 监听 apiserver 中service 与Endpoint 的信息, 配置iptables 规则,请求通过iptables 直接转发给 pod
- kube-proxy 反向代理,但是kube-proxy不执行具体的代理任务,通过设置iptables/ipvs路由规则,由serviceVIP & iptables来实现的路由规则
# 3. Pod
Pod是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储和网络,在同一台Docker主机上运行
# 3.1 pod 的基本组成
# 3.2 Pause的作用 !!!
- 每个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。
# 3.3 创建pod的流程
- kubeclt 发送创建的pod的指令,此时这个指令被apiserver拦截,把创建的pod存储在etcd
- schduler 发起调用请求,此时这个指令被apiserver拦截,获取etcd中podQueue.NodeList
- 调度算法:
- 预选调度(遍历所有node,选出符合要求的候选节点:判断pod是否存在冲突,pod名称是否重复)
- 优选策略(判断磁盘有没有冲突、节点是否已经存满了,cpu利用率是否最小、节点资源是否够用、是否和Pod匹配…)
- 选择出一个合适的node节点
- 调度算法:
- 把选择合适的node,pod存储在etcd
- node节点上有一个kubelet进程,发送请求获取pod,node对应创建资源
- 此时如果kubelet发现pod是本机节点需要创建的,kubelet就开始创建pod
# 4 控制器pod
# 4.1 ReplicationController
用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代,而如果异常多出的容器也会自动回收。
相当于ReplicaSet的老版本,现在建议使用Deployments加ReplicaSet替代RC
# 4.2 ReplicaSet 控制器
ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector
虽然ReplicaSet可以独立使用,但一般还是建议使用Deployment来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如 ReplicaSet 不支持 rolling-update 但 Deployment支持)
Deployment为Pod和ReplicaSet 提供了一个 声明式定义方法,用来替代以前的 ReplicationController 来方便的管理应用。
典型的应用场景:
- 定义Deployment 来创建 Pod 和 ReplicaSet
- 滚动升级和回滚应用
- 扩容和索容
- 暂停和继续 Deployment
Deployment不仅仅可以滚动更新,而且可以进行回滚,如何发现升级到V2版本后,发现服务不可用,可以回滚到V1版本
# 4.3 StatefullSet 控制器
StatefullSet 是为了解决有状态服务的问题(对应Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:
- 稳定的持久化存储,即Pod重新调度后还是能访问的相同持久化数据,基于PVC来实现
- 稳定的网络标志,及Pod重新调度后其 PodName 和 HostName 不变,基于Headlesss Service(即没有 Cluster IP 的 Service)来实现。
- 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从 0 到 N-1,在下一个Pod运行之前所有之前的Pod必须都是Running 和 Ready 状态),基于 init containers 来实现。
- 有序收缩,有序删除(即从N-1 到 0)
解析:
- 有状态:需要实时的进行数据更新及存储,把某个服务抽离出去,再加入回来就没有办法正常工作,这样的服务就是有状态服务。 例如: mysql,Redis…
无状态:docker主要面对的是无状态服务,所谓的无状态服务就是没有对应的存储数据需要实时的保留,或者是把服务摘除后经过一段时间运行后再把服务放回去依然能够正常运行,就是无状态服务。 例如: Apache、lvs
# 4.4 DaemonSet 控制器
DaemonSet确保全部(或者一些 [ node打上污点(可以想象成一个标签),pod如果不定义容忍这个污点,那么pod就不会被调度器分配到这个node ])Node上运行一个Pod的副本。当有Node加入集群时,也会为他们新增一个Pod。当有Node从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除他创建的所有Pod,使用DaemonSet 的一些典型用法:
- 运行集群存储daemon,例如在每个Node上运行glustered,ceph
- 在每个Node上运行日志收集Daemon,例如:fluentd、logstash.
- 在每个Node上运行监控Daemon,例如:Prometheus Node Exporter
- Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束 Cron Job管理基于时间Job,即:
在给定时间点只运行一次
周期性地在给定时间点运行
# 其他组件
- COREDNS:可以为集群中的SVC创建一个域名IP的对应关系解析
- DASHBOARD:给 K8S 集群提供一个 B/S 结构访问体系
- INGRESS CONTROLLER:官方只能实现四层代理,INGRESS 可以实现七层代理
- FEDERATION:提供一个可以跨集群中心多K8S统一管理功能
- PROMETHEUS:提供K8S集群的监控能力
- ELK:提供 K8S 集群日志统一分析介入平台